Imported Upstream version 2.4 upstream/2.4
authorAnas Nashif <anas.nashif@intel.com>
Wed, 7 Nov 2012 23:31:22 +0000 (15:31 -0800)
committerAnas Nashif <anas.nashif@intel.com>
Wed, 7 Nov 2012 23:31:22 +0000 (15:31 -0800)
338 files changed:
.bootstrap [new file with mode: 0755]
AUTHORS [new file with mode: 0644]
COPYING.LIB [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
INSTALL [new file with mode: 0644]
Makefile.in [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
TODO [new file with mode: 0644]
aclocal.m4 [new file with mode: 0644]
aes-decrypt-internal.c [new file with mode: 0644]
aes-decrypt.c [new file with mode: 0644]
aes-encrypt-internal.c [new file with mode: 0644]
aes-encrypt-table.c [new file with mode: 0644]
aes-encrypt.c [new file with mode: 0644]
aes-internal.h [new file with mode: 0644]
aes-meta.c [new file with mode: 0644]
aes-set-decrypt-key.c [new file with mode: 0644]
aes-set-encrypt-key.c [new file with mode: 0644]
aes.h [new file with mode: 0644]
aesdata.c [new file with mode: 0644]
arcfour-crypt.c [new file with mode: 0644]
arcfour-meta.c [new file with mode: 0644]
arcfour.c [new file with mode: 0644]
arcfour.h [new file with mode: 0644]
arctwo-meta.c [new file with mode: 0644]
arctwo.c [new file with mode: 0644]
arctwo.h [new file with mode: 0644]
asm.m4 [new file with mode: 0644]
asn1.h [new file with mode: 0644]
base16-decode.c [new file with mode: 0644]
base16-encode.c [new file with mode: 0644]
base16-meta.c [new file with mode: 0644]
base16.h [new file with mode: 0644]
base64-decode.c [new file with mode: 0644]
base64-encode.c [new file with mode: 0644]
base64-meta.c [new file with mode: 0644]
base64.h [new file with mode: 0644]
bignum-next-prime.c [new file with mode: 0644]
bignum-random-prime.c [new file with mode: 0644]
bignum-random.c [new file with mode: 0644]
bignum.c [new file with mode: 0644]
bignum.h [new file with mode: 0644]
blowfish.c [new file with mode: 0644]
blowfish.h [new file with mode: 0644]
buffer-init.c [new file with mode: 0644]
buffer.c [new file with mode: 0644]
buffer.h [new file with mode: 0644]
camellia-crypt-internal.c [new file with mode: 0644]
camellia-crypt.c [new file with mode: 0644]
camellia-internal.h [new file with mode: 0644]
camellia-meta.c [new file with mode: 0644]
camellia-set-decrypt-key.c [new file with mode: 0644]
camellia-set-encrypt-key.c [new file with mode: 0644]
camellia-table.c [new file with mode: 0644]
camellia.h [new file with mode: 0644]
cast128-meta.c [new file with mode: 0644]
cast128.c [new file with mode: 0644]
cast128.h [new file with mode: 0644]
cast128_sboxes.h [new file with mode: 0644]
cbc.c [new file with mode: 0644]
cbc.h [new file with mode: 0644]
config.guess [new file with mode: 0755]
config.h.in [new file with mode: 0644]
config.m4.in [new file with mode: 0644]
config.make.in [new file with mode: 0644]
config.sub [new file with mode: 0755]
configure [new file with mode: 0755]
configure.ac [new file with mode: 0644]
ctr.c [new file with mode: 0644]
ctr.h [new file with mode: 0644]
der-iterator.c [new file with mode: 0644]
der2dsa.c [new file with mode: 0644]
der2rsa.c [new file with mode: 0644]
des-compat.c [new file with mode: 0644]
des-compat.h [new file with mode: 0644]
des.c [new file with mode: 0644]
des.h [new file with mode: 0644]
des3.c [new file with mode: 0644]
desCode.h [new file with mode: 0644]
descore.README [new file with mode: 0644]
desdata.c [new file with mode: 0644]
desinfo.h [new file with mode: 0644]
dsa-keygen.c [new file with mode: 0644]
dsa-sha1-sign.c [new file with mode: 0644]
dsa-sha1-verify.c [new file with mode: 0644]
dsa-sha256-sign.c [new file with mode: 0644]
dsa-sha256-verify.c [new file with mode: 0644]
dsa-sign.c [new file with mode: 0644]
dsa-verify.c [new file with mode: 0644]
dsa.c [new file with mode: 0644]
dsa.h [new file with mode: 0644]
dsa2sexp.c [new file with mode: 0644]
examples/Makefile.in [new file with mode: 0644]
examples/eratosthenes.c [new file with mode: 0644]
examples/getopt.c [new file with mode: 0644]
examples/getopt.h [new file with mode: 0644]
examples/getopt1.c [new file with mode: 0644]
examples/io.c [new file with mode: 0644]
examples/io.h [new file with mode: 0644]
examples/nettle-benchmark.c [new file with mode: 0644]
examples/nettle-openssl.c [new file with mode: 0644]
examples/next-prime.c [new file with mode: 0644]
examples/random-prime.c [new file with mode: 0644]
examples/read_rsa_key.c [new file with mode: 0644]
examples/rsa-decrypt.c [new file with mode: 0644]
examples/rsa-encrypt-test [new file with mode: 0755]
examples/rsa-encrypt.c [new file with mode: 0644]
examples/rsa-keygen.c [new file with mode: 0644]
examples/rsa-session.h [new file with mode: 0644]
examples/rsa-sign-test [new file with mode: 0755]
examples/rsa-sign.c [new file with mode: 0644]
examples/rsa-verify-test [new file with mode: 0755]
examples/rsa-verify.c [new file with mode: 0644]
examples/run-tests [new file with mode: 0755]
examples/setup-env [new file with mode: 0755]
examples/teardown-env [new file with mode: 0755]
gcm-aes.c [new file with mode: 0644]
gcm.c [new file with mode: 0644]
gcm.h [new file with mode: 0644]
gcmdata.c [new file with mode: 0644]
hmac-md5.c [new file with mode: 0644]
hmac-ripemd160.c [new file with mode: 0644]
hmac-sha1.c [new file with mode: 0644]
hmac-sha224.c [new file with mode: 0644]
hmac-sha256.c [new file with mode: 0644]
hmac-sha384.c [new file with mode: 0644]
hmac-sha512.c [new file with mode: 0644]
hmac.c [new file with mode: 0644]
hmac.h [new file with mode: 0644]
hogweed.pc.in [new file with mode: 0644]
install-sh [new file with mode: 0755]
keymap.h [new file with mode: 0644]
knuth-lfib.c [new file with mode: 0644]
knuth-lfib.h [new file with mode: 0644]
macros.h [new file with mode: 0644]
md2-meta.c [new file with mode: 0644]
md2.c [new file with mode: 0644]
md2.h [new file with mode: 0644]
md4-meta.c [new file with mode: 0644]
md4.c [new file with mode: 0644]
md4.h [new file with mode: 0644]
md5-compat.c [new file with mode: 0644]
md5-compat.h [new file with mode: 0644]
md5-compress.c [new file with mode: 0644]
md5-meta.c [new file with mode: 0644]
md5.c [new file with mode: 0644]
md5.h [new file with mode: 0644]
memxor.c [new file with mode: 0644]
memxor.h [new file with mode: 0644]
nettle-internal.c [new file with mode: 0644]
nettle-internal.h [new file with mode: 0644]
nettle-meta-armors.c [new file with mode: 0644]
nettle-meta-ciphers.c [new file with mode: 0644]
nettle-meta-hashes.c [new file with mode: 0644]
nettle-meta.h [new file with mode: 0644]
nettle-types.h [new file with mode: 0644]
nettle-write.h [new file with mode: 0644]
nettle.html [new file with mode: 0644]
nettle.info [new file with mode: 0644]
nettle.pc.in [new file with mode: 0644]
nettle.pdf [new file with mode: 0644]
nettle.texinfo [new file with mode: 0644]
pgp-encode.c [new file with mode: 0644]
pgp.h [new file with mode: 0644]
pkcs1-rsa-md5.c [new file with mode: 0644]
pkcs1-rsa-sha1.c [new file with mode: 0644]
pkcs1-rsa-sha256.c [new file with mode: 0644]
pkcs1-rsa-sha512.c [new file with mode: 0644]
pkcs1.c [new file with mode: 0644]
pkcs1.h [new file with mode: 0644]
prime-list.h [new file with mode: 0644]
realloc.c [new file with mode: 0644]
realloc.h [new file with mode: 0644]
ripemd160-compress.c [new file with mode: 0644]
ripemd160-meta.c [new file with mode: 0644]
ripemd160.c [new file with mode: 0644]
ripemd160.h [new file with mode: 0644]
rotors.h [new file with mode: 0644]
rsa-compat.c [new file with mode: 0644]
rsa-compat.h [new file with mode: 0644]
rsa-decrypt.c [new file with mode: 0644]
rsa-encrypt.c [new file with mode: 0644]
rsa-keygen.c [new file with mode: 0644]
rsa-md5-sign.c [new file with mode: 0644]
rsa-md5-verify.c [new file with mode: 0644]
rsa-sha1-sign.c [new file with mode: 0644]
rsa-sha1-verify.c [new file with mode: 0644]
rsa-sha256-sign.c [new file with mode: 0644]
rsa-sha256-verify.c [new file with mode: 0644]
rsa-sha512-sign.c [new file with mode: 0644]
rsa-sha512-verify.c [new file with mode: 0644]
rsa-sign.c [new file with mode: 0644]
rsa-verify.c [new file with mode: 0644]
rsa.c [new file with mode: 0644]
rsa.h [new file with mode: 0644]
rsa2openpgp.c [new file with mode: 0644]
rsa2sexp.c [new file with mode: 0644]
serpent-decrypt.c [new file with mode: 0644]
serpent-encrypt.c [new file with mode: 0644]
serpent-internal.h [new file with mode: 0644]
serpent-meta.c [new file with mode: 0644]
serpent-set-key.c [new file with mode: 0644]
serpent.h [new file with mode: 0644]
sexp-format.c [new file with mode: 0644]
sexp-transport-format.c [new file with mode: 0644]
sexp-transport.c [new file with mode: 0644]
sexp.c [new file with mode: 0644]
sexp.h [new file with mode: 0644]
sexp2bignum.c [new file with mode: 0644]
sexp2dsa.c [new file with mode: 0644]
sexp2rsa.c [new file with mode: 0644]
sha-example.c [new file with mode: 0644]
sha.h [new file with mode: 0644]
sha1-compress.c [new file with mode: 0644]
sha1-meta.c [new file with mode: 0644]
sha1.c [new file with mode: 0644]
sha224-meta.c [new file with mode: 0644]
sha256-compress.c [new file with mode: 0644]
sha256-meta.c [new file with mode: 0644]
sha256.c [new file with mode: 0644]
sha384-meta.c [new file with mode: 0644]
sha512-compress.c [new file with mode: 0644]
sha512-meta.c [new file with mode: 0644]
sha512.c [new file with mode: 0644]
shadata.c [new file with mode: 0644]
sparc32/aes-decrypt-internal.asm [new file with mode: 0644]
sparc32/aes-encrypt-internal.asm [new file with mode: 0644]
sparc32/aes.m4 [new file with mode: 0644]
sparc32/arcfour-crypt.asm [new file with mode: 0644]
sparc32/machine.m4 [new file with mode: 0644]
sparc64/aes-decrypt-internal.asm [new file with mode: 0644]
sparc64/aes-encrypt-internal.asm [new file with mode: 0644]
sparc64/arcfour-crypt.asm [new file with mode: 0644]
sparc64/machine.m4 [new file with mode: 0644]
stamp-h.in [new file with mode: 0644]
testsuite/.test-rules.make [new file with mode: 0644]
testsuite/Makefile.in [new file with mode: 0644]
testsuite/aes-test.c [new file with mode: 0644]
testsuite/arcfour-test.c [new file with mode: 0644]
testsuite/arctwo-test.c [new file with mode: 0644]
testsuite/base16-test.c [new file with mode: 0644]
testsuite/base64-test.c [new file with mode: 0644]
testsuite/bignum-test.c [new file with mode: 0644]
testsuite/blowfish-test.c [new file with mode: 0644]
testsuite/buffer-test.c [new file with mode: 0644]
testsuite/camellia-test.c [new file with mode: 0644]
testsuite/cast128-test.c [new file with mode: 0644]
testsuite/cbc-test.c [new file with mode: 0644]
testsuite/ctr-test.c [new file with mode: 0644]
testsuite/cxx-test.cxx [new file with mode: 0644]
testsuite/des-compat-test.c [new file with mode: 0644]
testsuite/des-test.c [new file with mode: 0644]
testsuite/des3-test.c [new file with mode: 0644]
testsuite/dsa-keygen-test.c [new file with mode: 0644]
testsuite/dsa-test.c [new file with mode: 0644]
testsuite/gcm-test.c [new file with mode: 0644]
testsuite/gold-bug.txt [new file with mode: 0644]
testsuite/hmac-test.c [new file with mode: 0644]
testsuite/knuth-lfib-test.c [new file with mode: 0644]
testsuite/md2-test.c [new file with mode: 0644]
testsuite/md4-test.c [new file with mode: 0644]
testsuite/md5-compat-test.c [new file with mode: 0644]
testsuite/md5-test.c [new file with mode: 0644]
testsuite/memxor-test.c [new file with mode: 0644]
testsuite/meta-armor-test.c [new file with mode: 0644]
testsuite/meta-cipher-test.c [new file with mode: 0644]
testsuite/meta-hash-test.c [new file with mode: 0644]
testsuite/pkcs1-conv-test [new file with mode: 0755]
testsuite/pkcs1-test.c [new file with mode: 0644]
testsuite/random-prime-test.c [new file with mode: 0644]
testsuite/ripemd160-test.c [new file with mode: 0644]
testsuite/rsa-encrypt-test.c [new file with mode: 0644]
testsuite/rsa-keygen-test.c [new file with mode: 0644]
testsuite/rsa-test.c [new file with mode: 0644]
testsuite/rsa2sexp-test.c [new file with mode: 0644]
testsuite/run-tests [new file with mode: 0755]
testsuite/serpent-test.c [new file with mode: 0644]
testsuite/sexp-conv-test [new file with mode: 0755]
testsuite/sexp-format-test.c [new file with mode: 0644]
testsuite/sexp-test.c [new file with mode: 0644]
testsuite/sexp2rsa-test.c [new file with mode: 0644]
testsuite/sha1-huge-test.c [new file with mode: 0644]
testsuite/sha1-test.c [new file with mode: 0644]
testsuite/sha224-test.c [new file with mode: 0644]
testsuite/sha256-test.c [new file with mode: 0644]
testsuite/sha384-test.c [new file with mode: 0644]
testsuite/sha512-test.c [new file with mode: 0644]
testsuite/symbols-test [new file with mode: 0755]
testsuite/teardown-env [new file with mode: 0755]
testsuite/testutils.c [new file with mode: 0644]
testsuite/testutils.h [new file with mode: 0644]
testsuite/twofish-test.c [new file with mode: 0644]
testsuite/yarrow-test.c [new file with mode: 0644]
texinfo.tex [new file with mode: 0644]
tools/Makefile.in [new file with mode: 0644]
tools/getopt.c [new file with mode: 0644]
tools/getopt.h [new file with mode: 0644]
tools/getopt1.c [new file with mode: 0644]
tools/input.c [new file with mode: 0644]
tools/input.h [new file with mode: 0644]
tools/misc.c [new file with mode: 0644]
tools/misc.h [new file with mode: 0644]
tools/nettle-hash.c [new file with mode: 0644]
tools/nettle-lfib-stream.c [new file with mode: 0644]
tools/output.c [new file with mode: 0644]
tools/output.h [new file with mode: 0644]
tools/parse.c [new file with mode: 0644]
tools/parse.h [new file with mode: 0644]
tools/pkcs1-conv.c [new file with mode: 0644]
tools/sexp-conv.c [new file with mode: 0644]
twofish-meta.c [new file with mode: 0644]
twofish.c [new file with mode: 0644]
twofish.h [new file with mode: 0644]
write-be32.c [new file with mode: 0644]
write-le32.c [new file with mode: 0644]
x86/aes-decrypt-internal.asm [new file with mode: 0644]
x86/aes-encrypt-internal.asm [new file with mode: 0644]
x86/aes.m4 [new file with mode: 0644]
x86/arcfour-crypt.asm [new file with mode: 0644]
x86/camellia-crypt-internal.asm [new file with mode: 0644]
x86/machine.m4 [new file with mode: 0644]
x86/md5-compress.asm [new file with mode: 0644]
x86/sha1-compress.asm [new file with mode: 0644]
x86_64/aes-decrypt-internal.asm [new file with mode: 0644]
x86_64/aes-encrypt-internal.asm [new file with mode: 0644]
x86_64/aes.m4 [new file with mode: 0644]
x86_64/arcfour-crypt.asm [new file with mode: 0644]
x86_64/camellia-crypt-internal.asm [new file with mode: 0644]
x86_64/machine.m4 [new file with mode: 0644]
x86_64/memxor.asm [new file with mode: 0644]
x86_64/serpent-decrypt.asm [new file with mode: 0644]
x86_64/serpent-encrypt.asm [new file with mode: 0644]
x86_64/serpent.m4 [new file with mode: 0644]
x86_64/sha1-compress.asm [new file with mode: 0644]
yarrow.h [new file with mode: 0644]
yarrow256.c [new file with mode: 0644]
yarrow_key_event.c [new file with mode: 0644]

diff --git a/.bootstrap b/.bootstrap
new file mode 100755 (executable)
index 0000000..d85e2e2
--- /dev/null
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+autoconf && autoheader
diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..b021b48
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+Please see the Nettle manual.
diff --git a/COPYING.LIB b/COPYING.LIB
new file mode 100644 (file)
index 0000000..2d2d780
--- /dev/null
@@ -0,0 +1,510 @@
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+       51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations
+below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it
+becomes a de-facto standard.  To achieve this, non-free programs must
+be allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control
+compilation and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at least
+    three years, to give the same user the materials specified in
+    Subsection 6a, above, for a charge no more than the cost of
+    performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply, and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License
+may add an explicit geographical distribution limitation excluding those
+countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms
+of the ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.
+It is safest to attach them to the start of each source file to most
+effectively convey the exclusion of warranty; and each file should
+have at least the "copyright" line and a pointer to where the full
+notice is found.
+
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or
+your school, if any, to sign a "copyright disclaimer" for the library,
+if necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James
+  Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..aff034b
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,5885 @@
+2011-09-03  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac (LIBNETTLE_MINOR): Bumped library version, to 4.3.
+
+       * gcm-aes.c: Include config.h.
+       * tools/nettle-lfib-stream.c: Likewise.
+
+       * ripemd160-compress.c: Added missing include of config.h. Needed
+       for correct operation on big-endian systems.
+
+2011-09-02  Niels Möller  <nisse@amfibolit.hack.org>
+
+       * configure.ac: Changed version number to 2.4.
+
+       * Released nettle-2.3.
+
+2011-08-30  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/hmac-test.c: Added tests for hmac-ripemd160.
+
+       * hmac.h: Declare hmac-ripemd160 related functions.
+
+       * Makefile.in (nettle_SOURCES): Added hmac-ripemd160.c.
+
+2011-08-30  Niels Möller  <nisse@amfibolit.hack.org>
+
+       * nettle.texinfo (Hash functions): Document ripemd-160.
+
+       * hmac-ripemd160.c: New file.
+
+       * hmac.h: Declare hmac-ripemd160 functions.
+
+2011-08-29  Niels Möller  <nisse@lysator.liu.se>
+
+       * sha256.c (sha256_update): Updated MD_UPDATE call for new
+       conventions.
+       (sha256_write_digest): Use MD_PAD rather than MD_FINAL, and insert
+       the length manually.
+       * sha512.c: Analogous changes.
+
+       * sha1.c (COMPRESS): New macro.
+       (sha1_update): Updated MD_UPDATE call for new conventions.
+       (sha1_digest): Use MD_PAD rather than MD_FINAL, and insert the
+       length manually.
+
+       * ripemd160.c (ripemd160_init): Use memcpy for initializing the
+       state vector.
+       (COMPRESS): New macro.
+       (ripemd160_update): Use MD_UPDATE.
+       (ripemd160_digest): Inline ripemd160_final processing. Use MD_PAD
+       and _nettle_write_le32.
+       (ripemd160_final): Deleted function.
+
+       * ripemd160.h (struct ripemd160_ctx): Use a 64-bit block count.
+       Renamed digest to state.
+
+       * md5.c (md5_init): Use memcpy for initializing the state vector.
+       (COMPRESS): New macro, wrapping _nettle_md5_compress.
+       (md5_update): Use MD_UPDATE.
+       (md5_digest): Inline md5_final processing. Use MD_PAD and
+       _nettle_write_le32.
+       (md5_final): Deleted.
+
+       * md5.h (struct md5_ctx): Renamed some fields, for consistency.
+
+       * md4.h (struct md4_ctx): Renamed some fields, for consistency.
+
+       * md4.c (md4_init): Use memcpy for initializing the state vector.
+       (md4_update): Use MD_UPDATE.
+       (md4_digest): Inline md4_final processing, using MD_PAD. Use
+       _nettle_write_le32.
+       (md4_block): Renamed, to...
+       (md4_compress): ... new name. Take ctx pinter as argument.
+       (md4_final): Deleted function.
+
+       * md2.c (md2_update): Use MD_UPDATE.
+
+       * macros.h (MD_UPDATE): Added incr argument. Invoke compression
+       function with ctx pointer as argument, rather than ctx->state.
+       (MD_FINAL): Just pad, don't store length field. Renamed to MD_PAD.
+       (MD_PAD): Analogous change of compression invocations.
+
+       * sha512.c: (COMPRESS): New macro wrapping _nettle_sha512_compress.
+       (sha512_update): Use MD_UPDATE.
+       (sha512_final): Deleted function.
+       (sha512_write_digest): Use MD_FINAL.
+
+       * sha256.c (COMPRESS): New macro wrapping _nettle_sha256_compress.
+       (SHA256_INCR): Deleted macro.
+       (sha256_update): Use MD_UPDATE.
+       (sha256_final): Deleted function.
+       (sha256_write_digest): New function, replacing sha256_final, and
+       using MD_FINAL.
+       (sha256_digest): Use sha256_write_digest.
+       (sha224_digest): Likewise.
+
+       * tools/nettle-hash.c (list_algorithms): Fixed typo in header.
+
+       * sha1.c (SHA1_DATA_LENGTH): Deleted unused macro.
+       (sha1_init): Use memcpy to initialize the state vector.
+       (SHA1_INCR): Deleted macro.
+       (sha1_update): Use MD_UPDATE macro, to reduce code duplication.
+       (sha1_digest): Use MD_FINAL macro.
+       (sha1_final): Deleted function.
+
+       * sha.h (struct sha1_ctx): Renamed attribute digest to state.
+
+       * macros.h (MD_UPDATE): New macro.
+       (MD_FINAL): New macro.
+
+2011-08-28  Niels Möller  <nisse@lysator.liu.se>
+
+       * ripemd160.c (ripemd160_final): Use LE_WRITE_UINT32. Deleted byte
+       swapping at the end, leaving it to ripemd160_digest.
+       (ripemd160_digest): Use _nettle_write_le32.
+
+       * Makefile.in (nettle_SOURCES): Added write-le32.c.
+
+       * md5.c (md5_digest): Use _nettle_write_le32.
+
+       * write-le32.c (_nettle_write_le32): New file and function.
+
+       * ripemd160-compress.c (ROL32): Renamed macro (was "rol"). Deleted
+       x86 version using inline assembly; at least gcc-4.4.5 recognizes
+       shift-and-or expressions which are in fact rotations.
+       (_nettle_ripemd160_compress): Use LE_READ_UINT32.
+
+       * configure.ac (LIBNETTLE_MINOR): Bumped library version, to 4.2.
+
+       * testsuite/meta-hash-test.c: Updated for the addition of
+       ripemd-160.
+
+       * testsuite/.test-rules.make: Added rule for ripemd160-test.
+
+       * examples/nettle-benchmark.c (main): Benchmark ripemd-160.
+
+2011-08-28  Niels Möller  <nisse@lysator.liu.se>
+
+       RIPEMD-160 hash function. Ported from libgcrypt by Andres Mejia.
+       * testsuite/ripemd160-test.c: New file.
+       * ripemd160.h: New file.
+       * nettle-meta.h: Declare nettle_ripemd160.
+       * ripemd160.c: New file, ported from libgcrypt.
+       * ripemd160-compress.c: Likewise.
+       * ripemd160-meta.c: New file.
+       * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added
+       ripemd160-test.c.
+       * nettle-meta-hashes.c (nettle_hashes): Added nettle_ripemd160.
+       * Makefile.in (nettle_SOURCES): Added ripemd160.c,
+       ripemd160-compress.c, and ripemd160-meta.c.
+       (HEADERS): Added ripemd160.h.
+
+2011-08-10  Niels Möller  <nisse@amfibolit.hack.org>
+
+       * nettle.texinfo: Fixed mis-placed const in various prototypes.
+       Spotted by Tatsuhiro Tsujikawa.
+
+2011-07-24  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (PKGCONFIG_FILES, pkgconfigdir): New variables.
+       (DISTFILES): Added nettle.pc.in and hogweed.pc.in.
+       (nettle.pc, hogweed.pc): New targets (invoking config.status).
+       (install-pkgconfig, uninstall-pkgconfig): New targets.
+       (install-here): Depend on install-pkgconfig.
+       (uninstall-here): Depend on uninstall-pkgconfig.
+       (distclean-here): Delete nettle.pc and hogweed.pc.
+
+2011-07-20  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Generate nettle.pc and hogweed.pc.
+
+       * nettle.pc.in, hogweed.pc.in: New files.
+
+2011-07-17  Niels Möller  <nisse@lysator.liu.se>
+
+       * nettle-internal.h: Added missing extern declarations.
+
+2011-07-11  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Changed version number to 2.3.
+
+       * Released nettle-2.2.
+
+       * Makefile.in (DISTFILES): Distribute COPYING.LIB, not COPYING,
+
+2011-07-07  Niels Möller  <nisse@lysator.liu.se>
+
+       * tools/misc.h (werror): Removed incorrect noreturn attribute from
+       declaration.
+
+       * examples/io.c (read_file): Bug fix, in dependence of initial
+       size on max_size.
+
+2011-07-01  Niels Möller  <nisse@lysator.liu.se>
+
+       * cbc.c (CBC_BUFFER_LIMIT): Reduced to 512 bytes.
+       (cbc_decrypt): For in-place operation, use overlapping memxor3 and
+       eliminate a memcpy.
+
+       * ctr.c (ctr_crypt): Reorganized to call the encryption function
+       with several blocks at a time. Handle the case of a single block
+       specially.
+
+       * x86_64/memxor.asm: Added ALIGN for shifting loop. Deleted
+       obsolete ifelse.
+
+2011-06-30  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Link in serpent-decrypt.asm, if found.
+
+       * x86_64/serpent-decrypt.asm: Added an SSE2 loop, doing four
+       blocks at a time in parallel.
+
+       * x86_64/serpent-encrypt.asm: Include serpent.m4. Deleted a
+       redundant label.
+
+       * x86_64/serpent.m4: New file, with serpent-related macros.
+
+2011-06-29  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86_64/serpent-decrypt.asm: Wrote main (32-bit) loop.
+       (SBOX0I, SBOX1I, SBOX7I): Fixed bugs.
+
+       * nettle.texinfo (Copyright): Updated for license change to
+       LGPLv2+. Updated copyriight info on serpent.
+
+       * NEWS: Updated information for nettle-2.2.
+
+       * x86_64/serpent-decrypt.asm: New file.
+
+       * x86_64/serpent-encrypt.asm: Fixed .file pseudo op.
+
+       * testsuite/testutils.c (test_cipher_ctr): Display more info on
+       failure.
+
+       * examples/nettle-benchmark.c (bench_ctr): New function.
+       (time_cipher): Also benchmark CTR mode.
+
+       * configure.ac (LIBNETTLE_MINOR): Updated library version number
+       to 4.1.
+       (LIBHOGWEED_MINOR): And to 2.1.
+
+2011-06-22  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Use pwd -P when examining lib directories.
+       Link in serpent-encrypt.asm, if found.
+
+2011-06-21  Niels Möller  <nisse@lysator.liu.se>
+
+       * serpent-decrypt.c (SBOX3_INVERSE): Eliminated temporaries.
+       (SBOX4_INVERSE): Likewise.
+       (SBOX5_INVERSE): Likewise.
+       (SBOX6_INVERSE): Likewise.
+       (SBOX7_INVERSE): Likewise.
+       (All SBOX_INVERSE-macros): Deleted type argument, and updated users.
+
+2011-06-20  Niels Möller  <nisse@lysator.liu.se>
+
+       * serpent-decrypt.c: Renamed arguments in sbox macros.
+       (SBOX0_INVERSE): Eliminated temporaries.
+       (SBOX1_INVERSE): Likewise.
+       (SBOX2_INVERSE): Likewise.
+
+       * x86_64/serpent-encrypt.asm: Added an SSE2 loop, doing four
+       blocks at a time in parallel.
+
+       * testsuite/serpent-test.c (test_main): Added some more multiple
+       block tests.
+
+2011-06-15  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac (libdir): On 64-bit Linux, we used to assume that
+       libraries are installed according to the FHS. Since at least
+       Fedora and Gentoo follow the FHS convention, while at least Debian
+       doesn't, we have to try to figure out which convention is used.
+
+2011-06-14  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86_64/serpent-encrypt.asm: Slight simplification of loop logic.
+
+       * x86_64/serpent-encrypt.asm: New file.
+
+2011-06-12  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/serpent-test.c (test_main): Added tests with multiple
+       blocks at a time.
+
+       * serpent-encrypt.c (SBOX6): Renamed arguments. Eliminated
+       temporaries.
+       (SBOX7): Likewise.
+       (All SBOX-macros): Deleted type argument, and updated users.
+
+       * configure.ac: Display summary at the end of configure..
+       (asm_path): Set only if enable_assember is yes.
+
+2011-06-10  Niels Möller  <nisse@lysator.liu.se>
+
+       * serpent-encrypt.c (SBOX5): Renamed arguments. Eliminated
+       temporaries.
+
+2011-06-09  Niels Möller  <nisse@lysator.liu.se>
+
+       * serpent-encrypt.c (SBOX4): Renamed arguments. Eliminated
+       temporaries.
+
+       * configure.ac (LIBNETTLE_LINK, LIBHOGWEED_LINK): Cygwin fix, from
+       Vincent Torri.
+
+2011-06-08  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/eratosthenes.c (find_first_one): Fixed c99-style
+       declaration. Reported by Sebastian Reitenbach.
+       (find_first_one): Declare the lookup table as static const, and
+       use unsigned char rather than unsigned..
+
+2011-06-07  Niels Möller  <nisse@lysator.liu.se>
+
+       * serpent-encrypt.c (SBOX0): Renamed arguments. Eliminated
+       temporaries.
+       (SBOX1): Likewise.
+       (SBOX2): Likewise.
+       (SBOX3): Likewise.
+
+2011-06-06  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (DISTFILES): Added serpent-internal.h.
+       (nettle_SOURCES): Replaced serpent.c by serpent-set-key.c,
+       serpent-encrypt.c, and serpent-decrypt.c.
+
+       * serpent.c: Replaced by several new files.
+       * serpent-set-key.c: New file.
+       * serpent-encrypt.c: New file.
+       * serpent-decrypt.c: New file.
+       * serpent-internal.h: New file.
+
+       * serpent.c [HAVE_NATIVE_64_BIT]: Process two blocks at a time in
+       parallel. Measured speedup of 10%--25% (higher for encryption) on
+       x86_64.
+
+2011-06-01  Niels Möller  <nisse@lysator.liu.se>
+
+       * serpent.c (ROUNDS): Deleted macro.
+       (serpent_block_t): Deleted array typedef.
+       (KEYXOR): New macro, replacing BLOCK_XOR.
+       (BLOCK_COPY, SBOX, SBOX_INVERSE): Deleted macros.
+       (LINEAR_TRANSFORMATION): Use four separate arguments.
+       (LINEAR_TRANSFORMATION_INVERSE): Likewise.
+       (ROUND): Take separate arguments for all input and output words.
+       (ROUND_INVERSE): Likewise.
+       (ROUND_LAST, ROUND_FIRST_INVERSE): Deleted macros.
+       (serpent_set_key): Moved loop termination test.
+       (serpent_encrypt): Rewrote with unrolling of just eight rounds,
+       and without serpent_block_t.
+       (serpent_decrypt): Likewise.
+
+       * serpent.c: Added do { ... } while (0) around block macros.
+       (serpent_key_t): Deleted array typedef.
+       (ROL32, ROR32): Renamed macros, were rol and ror.
+       (KS_RECURRENCE, KS): New macros.
+       (serpent_key_pad): Renamed, from...
+       (serpent_key_prepare): ...old name.
+       (serpent_subkeys_generate): Deleted function.
+       (serpent_set_key): Rewrote the generation of subkeys. Reduced both
+       temporary storage and code size (less unrolling)
+
+2011-05-31  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/serpent-test.c (test_main): Enabled test with short,
+       40-bit, key.
+
+       * serpent.c (byte_swap_32): Deleted macro.
+       (serpent_key_prepare): Use LE_READ_UINT32. Don't require aligned
+       input, and support arbitrary key sizes.
+
+2011-05-30  Simon Josefsson  <simon@josefsson.org>
+
+       * serpent.c: Rewrite, based on libgcrypt code.  License changed
+       from GPL to LGPL.
+       * serpent_sboxes.h: Removed.
+       * Makefile.in: Drop serpent_sboxes.h.
+
+2011-05-31  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/serpent-test.c (test_main): Added some tests for
+       padding of keys of length which is not a multiple of four bytes.
+
+2011-05-30  Simon Josefsson  <simon@josefsson.org>
+
+       * testsuite/serpent-test.c (test_main): Add test vectors from
+       libgcrypt.
+
+2011-05-21  Niels Möller  <nisse@lysator.liu.se>
+
+       * dsa-keygen.c (dsa_generate_keypair): Avoid double init of mpz
+       variable. Spotted by Nikos Mavrogiannopoulos.
+
+2011-05-06  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Fix link flags for shared libraries on Solaris,
+       which needs -h to set the soname. Patch contributed by Dagobert
+       Michelsen.
+
+2011-05-06  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: New configure option --enable-gcov.
+
+       * arcfour.h (arcfour_stream): Deleted obsolete define.
+
+2011-04-27  Niels Möller  <nisse@lysator.liu.se>
+
+       * tools/nettle-hash.c (find_algorithm): Require exact match.
+
+2011-04-15  Niels Möller  <nisse@lysator.liu.se>
+
+       Reverted broken byte-order change from 2001-06-17:
+       * serpent.c (serpent_set_key): Use correct byteorder.
+       (serpent_encrypt): Likewise.
+       (serpent_decrypt): Likewise.
+
+       * testsuite/serpent-test.c (decode_hex_reverse): New function.
+       (RH, RHL): New macros.
+       (test_main): Byte reverse inputs and outputs for the testvectors
+       taken from the serpent submission package. Enable test vectors
+       from http://www.cs.technion.ac.il/~biham/Reports/Serpent/.
+
+2011-03-23  Niels Möller  <nisse@lysator.liu.se>
+
+       * tools/sexp-conv.c (xalloc): Deleted function, now it's in misc.c
+       instead.
+
+       * configure.ac: Use LSH_FUNC_STRERROR.
+
+       * tools/Makefile.in (TARGETS): Added nettle-hash, and related
+       build rules.
+       (SOURCES): Added nettle-hash.c.
+
+       * tools/misc.c (xalloc): New function.
+
+       * tools/pkcs1-conv.c (main): Made the OPT_* constants local, and
+       fixed numerical values to start with non-ASCII 0x300.
+
+       * tools/nettle-hash.c: New file.
+
+2011-03-23  Niels Möller  <nisse@lysator.liu.se>
+
+       Contributed by Daniel Kahn Gillmor:
+       * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added
+       meta-hash-test.c, meta-cipher-test.c, and meta-armor-test.c.
+
+       * testsuite/meta-hash-test.c: New file.
+       * testsuite/meta-cipher-test.c: New file.
+       * testsuite/meta-armor-test.c: New file.
+
+       * nettle.texinfo: Document nettle_hashes and nettle_ciphers.
+
+       * nettle-meta.h: Declare algorithm lists nettle_ciphers,
+       nettle_hashes, nettle_armors.
+
+       * Makefile.in (nettle_SOURCES): Added nettle-meta-hashes.c,
+       nettle-meta-ciphers.c, and nettle-meta-armors.c.
+
+       * nettle-meta-armors.c: New file.
+       * nettle-meta-ciphers.c: New file.
+       * nettle-meta-hashes.c: New file.
+
+2011-02-18  Niels Möller  <nisse@lysator.liu.se>
+
+       * arcfour.c (arcfour_stream): Deleted function. It's not very
+       useful, and neither documented nor tested.
+
+2011-02-16  Niels Möller  <nisse@lysator.liu.se>
+
+       * cbc.h (CBC_ENCRYPT): Avoid using NULL; we don't ensure that it
+       is defined.
+       (CBC_DECRYPT): Likewise.
+
+       * gcm-aes.c (gcm_aes_set_iv): Use GCM_SET_IV.
+       (gcm_aes_set_key): Deleted cast.
+       (gcm_aes_encrypt): Likewise.
+       (gcm_aes_decrypt): Likewise.
+       (gcm_aes_digest): Likewise.
+       (gcm_aes_update): One less argument to GCM_UPDATE.
+
+       * gcm.h (GCM_SET_KEY): Added cast to nettle_crypt_func *. Help
+       compiler type checking despite this cast.
+       (GCM_ENCRYPT): Likewise.
+       (GCM_DECRYPT): Likewise.
+       (GCM_DIGEST): Likewise.
+       (GCM_SET_IV): New macro, for completeness.
+       (GCM_UPDATE): Deleted unused argument encrypt.
+
+2011-02-14  Niels Möller  <nisse@lysator.liu.se>
+
+       * nettle.texinfo: Split node on cipher modes, and started on
+       the GCM documentation.
+
+       * testsuite/gcm-test.c (test_gcm_aes): Deleted function, replaced
+       by test_aead.
+       (test_main): Use test_aead.
+
+       * testsuite/testutils.c (test_aead): New function, replacing
+       test_gcm_aes and before that test_cipher_gcm.
+
+       * nettle-internal.c (nettle_gcm_aes128): New const struct.
+       (nettle_gcm_aes192): Likewise.
+       (nettle_gcm_aes256): Likewise.
+
+       * nettle-internal.h (struct nettle_aead): Tentative interface for
+       authenticated encryption with associated data.
+
+       * examples/nettle-benchmark.c (time_gcm): Renamed. Updated for
+       gcm_aes_auth to gcm_aes_update renaming. Benchmark both encryption
+       and hashing.
+       (time_gmac): ...old name.
+
+       * nettle-internal.c (des_set_key_hack): Don't touch the bits
+       parity, since thay are now ignored.
+       (des3_set_key_hack): Likewise.
+
+       * cast128-meta.c (nettle_cast128): Don't pass keysize.
+       * nettle-meta.h (_NETTLE_CIPHER_FIX): Deleted keysize parameter
+       derived from the appropriate constant instead.
+
+       * testsuite/gcm-test.c (test_gcm_aes): Updated for gcm_aes_auth to
+       gcm_aes_update renaming.
+
+2011-02-13  Niels Möller  <nisse@lysator.liu.se>
+
+       * gcm.h (GCM_UPDATE): Renamed, from...
+       (GCM_AUTH): ...old name.
+
+       * gcm-aes.c (gcm_aes_update): Renamed, from...
+       (gcm_aes_auth): ...old name.
+
+       * gcm.c (gcm_update): Renamed, and fixed an assert. From...
+       (gcm_auth): ...old name.
+
+       * gcm.h (GCM_TABLE_BITS): Increase table size to 8 bits,
+       corresponding to 4 KByte of key-dependent tables.
+
+2011-02-10  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86_64/memxor.asm: New file. Improves performance by 22% for the
+       unaligned01 case and 35% for the unaligned12 case, benchmarked on
+       Intel SU1400.
+
+       * examples/nettle-benchmark.c (cgt_works_p): New function.
+       (cgt_time_start): Likewise.
+       (cgt_time_end): Likewise.
+       (clock_time_start): Likewise.
+       (clock_time_end): Likewise.
+       (time_function): Read clock via function pointers time_start and
+       time_end, so we can select method at runtime.
+       (xalloc): Use die function.
+       (main): Choose timing function. If available, try clock_gettime,
+       and fall back to clock if it doesn't exist.
+
+       * examples/nettle-benchmark.c (die): New function.
+       (TIME_END, TIME_START): Check return value from clock_gettime.
+
+       * gcm.h (union gcm_block): Use correct length for w array.
+
+       * testsuite/gcm-test.c (test_main): Added the rest of the
+       testcases from the spec.
+
+2011-02-09  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/gcm-test.c (test_main): Enabled testcases 5 and 6,
+       with different IV lengths.
+
+       * gcm-aes.c (gcm_aes_set_iv): Updated for gcm_set_iv change.
+
+       * gcm.c (gcm_hash_sizes): New function.
+       (gcm_set_iv): Added support for IVs of arbitrary size. Needed
+       another argument, for the hash subkey.
+       (gcm_digest): Use gcm_hash_sizes.
+
+       * examples/nettle-benchmark.c (time_gmac): Use gcm_aes interface.
+
+       * testsuite/gcm-test.c (test_gcm_aes): New function, replacing
+       test_cipher_gcm and using the new gcm_aes interface.
+       (test_main): Updated to use test_gcm_aes.
+       * testsuite/testutils.c (test_cipher_gcm): Deleted function.
+
+       * Makefile.in (nettle_SOURCES): Added gcm-aes.c.
+
+       * gcm.c (gcm_set_key): Replaced context argument by a struct
+       gcm_key *.
+       (gcm_hash): Replaced context argument by a struct gcm_key * and a
+       pointer to the hashing state block.
+       (gcm_auth): Added struct gcm_key * argument.
+       (gcm_encrypt): Likewise.
+       (gcm_decrypt): Likewise.
+       (gcm_digest): Likewise.
+
+       * gcm-aes.c: New file.
+       (gcm_aes_set_key): New function.
+       (gcm_aes_set_iv): Likewise.
+       (gcm_aes_auth): Likewise.
+       (gcm_aes_encrypt): Likewise.
+       (gcm_aes_decrypt): Likewise.
+       (gcm_aes_digest): Likewise.
+
+       * gcm.h (struct gcm_key): Moved the key-dependent and
+       message-independent state to its own struct.
+       (struct gcm_ctx): ... and removed it here.
+       (GCM_CTX): New macro.
+       (GCM_SET_KEY): Likewise.
+       (GCM_AUTH): Likewise.
+       (GCM_ENCRYPT): Likewise.
+       (GCM_DECRYPT): Likewise.
+       (GCM_DIGEST): Likewise.
+       (struct gcm_aes_ctx): New struct.
+
+2011-02-08  Niels Möller  <nisse@lysator.liu.se>
+
+       * gcm.h (struct gcm_ctx): The hash key is now always an array,
+       named h, with array size depending on GCM_TABLE_BITS.
+       * gcm.c (gcm_gf_shift): Added a separate result argument.
+       (gcm_gf_mul): Compile bitwise version only when GCM_TABLE_BITS ==
+       0. Simplified interface with just two arguments pointing to
+       complete blocks.
+       (gcm_gf_shift_4, gcm_gf_shift_8): Renamed table-based functions, from...
+       (gcm_gf_shift_chunk): ... old name.
+       (gcm_gf_mul): Renamed both table-based versions and made the
+       argument types compatible with the bitwise gcm_gf_mul.
+       (gcm_gf_mul_chunk): ... the old name.
+       (gcm_set_key): Initialize the table using adds and shifts only.
+       When GCM_TABLE_BITS > 0, this eliminates the only use of the
+       bitwise multiplication.
+       (gcm_hash): Simplified, now that we have the same interface for
+       gcm_gf_mul, regardless of table size.
+
+       * gcm.c (GHASH_POLYNOMIAL): Use unsigned long for this constant.
+       (gcm_gf_shift_chunk): Fixed bugs for the big endian 64-bit case,
+       e.g., sparc64. For both 4-bit and 8-bit tables.
+
+       * gcm.c: Use the new union gcm_block for all gf operations.
+
+       * gcm.h (union gcm_block): New union, used to enforce alignment.
+
+2011-02-07  Niels Möller  <nisse@lysator.liu.se>
+
+       * gcm.c (gcm_gf_shift_chunk) : Bug fix for little-endian 8-bit
+       tables.
+
+       * gcm.c (gcm_gf_mul_chunk): Special case first and last iteration.
+       (gcm_gf_add): New function, a special case of memxor. Use it for
+       all memxor calls with word-aligned 16 byte blocks. Improves
+       performance to 152 cycles/byte with no tables, 28 cycles per byte
+       with 4-bit tables and 10.5 cycles per byte with 8-bit tables.
+
+       Introduced 8-bit tables. If enabled, gives gmac performance of 19
+       cycles per byte (still on intel x86_64).
+       * gcm.c (gcm_gf_shift_chunk): New implementation for 8-bit tables.
+       (gcm_gf_mul_chunk): Likewise.
+       (gcm_set_key): Generate 8-bit tables.
+
+       * Makefile.in (SOURCES): Added gcmdata.c.
+
+       * gcm.h (GCM_TABLE_BITS): Set to 4.
+
+2011-02-06  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (TARGETS): Added gcmdata.
+       (gcmdata): New rule.
+
+       Introduced 4-bit tables. Gives gmac performance of 45 cycles per
+       byte (still on intel x86_64).
+       * gcm.c (gcm_gf_shift): Renamed. Tweaked little-endian masks.
+       (gcm_rightshift): ... old name.
+       (gcm_gf_mul): New argument for the output. Added length argument
+       for one of the inputs (implicitly padding with zeros).
+       (shift_table): New table (in 4-bit and 8-bit versions), generated
+       by gcmdata.
+       (gcm_gf_shift_chunk): New function shifting 4 bits at
+       a time.
+       (gcm_gf_mul_chunk): New function processing 4 bits at a time.
+       (gcm_set_key): Generation of 4-bit key table.
+       (gcm_hash): Use tables, when available.
+
+       * gcmdata.c (main): New file.
+
+       * gcm.c (gcm_rightshift): Moved the reduction of the shifted out
+       bit here.
+       (gcm_gf_mul): Updated for gcm_rightshift change. Improves gmac
+       performance to 181 cycles/byte.
+
+       * gcm.c (gcm_gf_mul): Rewrote. Still uses the bitwise algorithm from the
+       specification, but with separate byte and bit loops. Improves gmac
+       performance a bit further, to 227 cycles/byte.
+
+       * gcm.c (gcm_rightshift): Complete rewrite, to use word rather
+       than byte operations. Improves gmac performance from 830 cycles /
+       byte to (still poor) 268 cycles per byte on intel x86_64.
+
+2011-02-05  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/nettle-benchmark.c (time_gmac): New function.
+       (main): Call time_gmac.
+
+       * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added gcm-test.c.
+
+       * testsuite/testutils.c (test_cipher_gcm): New function,
+       contributed by Nikos Mavrogiannopoulos.
+
+       * testsuite/gcm-test.c: New file, contributed by Nikos
+       Mavrogiannopoulos.
+
+       * Makefile.in (nettle_SOURCES): Added gcm.c.
+       (HEADERS): Added gcm.h.
+
+       * gcm.c: New file, contributed by Nikos Mavrogiannopoulos.
+       * gcm.h: New file, contributed by Nikos Mavrogiannopoulos.
+
+       * macros.h (INCREMENT): New macro, moved from ctr.c. Deleted third
+       argument.
+       * ctr.c: Use INCREMENT macro from macros.h, deleted local version.
+
+2011-01-07  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/Makefile.in (check): Add ../.lib to PATH, since that's
+       where w*ndows looks for dlls.
+
+       * testsuite/testutils.c (test_cipher_stream): More debug output on
+       failure.
+
+2010-12-14  Niels Möller  <nisse@lysator.liu.se>
+
+       * nettle-types.h: Deleted some unnecessary parenthesis from
+       function typedefs.
+       (nettle_realloc_func): Moved typedef here...
+       * realloc.h: ...from here.
+
+       * buffer.c (nettle_buffer_init_realloc): Use an explicit pointer
+       for realloc argument.
+
+2010-12-07  Niels Möller  <nisse@lysator.liu.se>
+
+       * nettle.texinfo (Copyright): Updated info on blowfish.
+
+2010-11-26  Niels Möller  <nisse@lysator.liu.se>
+
+       Reapplied optimizations (150% speedup on x86_32) and other fixes,
+       relicensing them as LGPL.
+       * blowfish.c (do_encrypt): Renamed, to...
+       (encrypt): ...new name.
+       (F): Added context argument. Shift input explicitly, instead of
+       reading individual bytes via memory.
+       (R): Added context argument.
+       (encrypt): Deleted a bunch of local variables. Using the context
+       pointer for everything should consume less registers.
+       (decrypt): Likewise.
+       (initial_ctx): Arrange constants into a struct, to simplify key
+       setup.
+       (blowfish_set_key): Some simplification.
+
+2010-11-26  Simon Josefsson  <simon@josefsson.org>
+
+       * blowfish.c: New version ported from libgcrypt. License changed
+       from GPL to LGPL.
+
+2010-11-25  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (install-shared-nettle): Use INSTALL_DATA, which
+       clears the execute permission bits.
+       (install-shared-hogweed): Likewise.
+
+2010-11-16  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Updated gmp url.
+
+2010-11-01  Niels Möller  <nisse@lysator.liu.se>
+
+       * tools/misc.c (werror): Don't call exit (copy&paste-error).
+
+2010-10-26  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/rsa-encrypt.c (main): No extra message for bad options.
+
+       * examples/rsa-keygen.c (main): Added long options. Deleted -?,
+       and fixed handling of bad options.
+
+       * examples/next-prime.c (main): Deleted -?, and fixed handling of
+       bad options.
+       * examples/random-prime.c (main): Likewise.
+
+2010-10-22  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/nettle-benchmark.c (main): Added long options. Deleted -?,
+       and fixed handling of bad options.
+
+       * examples/eratosthenes.c (main): Added long options. Deleted -?,
+       and fixed handling of bad options. Renamed -s to -q (long option
+       --quiet).
+
+       * tools/pkcs1-conv.c (main): Deleted short alias -? for --help,
+       and fixed handling of bad options.
+       * tools/sexp-conv.c (parse_options): Likewise.
+
+2010-10-06  Niels Möller  <nisse@lysator.liu.se>
+
+       * memxor.c (memxor3): Optimized.
+       (memxor3_common_alignment): New function.
+       (memxor3_different_alignment_b): New function.
+       (memxor3_different_alignment_ab): New function.
+       (memxor3_different_alignment_all): New function.
+
+       * examples/nettle-benchmark.c (time_function): Reorganized, to
+       reduce overhead.
+       (time_memxor): Also benchmark memxor3.
+
+       * x86_64/memxor.asm: New file.
+
+       * examples/nettle-benchmark.c (overhead): New global variable.
+       (time_function): Compensate for call overhead.
+       (bench_nothing, time_overhead): New functions.
+       (time_memxor): Tweaked src size, making it an integral number of
+       words.
+       (main): Call time_overhead.
+
+2010-10-01  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86_64/camellia-crypt-internal.asm (ROUND): Reordered sbox
+       lookups.
+
+       * testsuite/memxor-test.c: Also test memxor3.
+
+2010-09-30  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Link in memxor.asm, if found.
+
+       * testsuite/testutils.c (test_cipher_cbc): Print more info when
+       failing.
+
+       * testsuite/memxor-test.c (test_xor): Added verbose printout.
+
+       * examples/nettle-benchmark.c (time_memxor): Count size of
+       unsigned long as "block size" for memxor.
+
+2010-09-24  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/.test-rules.make: Added rule for memxor-test.
+       * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added memxor-test.c
+       * testsuite/memxor-test.c: New file.
+
+       * memxor.c (memxor_common_alignment): New function.
+       (memxor_different_alignment): New function.
+       (memxor): Optimized to do word-operations rather than byte
+       operations.
+
+       * configure.ac (HAVE_NATIVE_64_BIT): New config.h define.
+
+       Partial revert of 2010-09-20 changes.
+       * camellia-set-encrypt-key.c (camellia_set_encrypt_key):
+       Reintroduce CAMELLIA_F_HALF_INV, for 32-bit machines.
+       * camellia-crypt-internal.c (CAMELLIA_ROUNDSM): Two variants,
+       differing in where addition of the key is done.
+       * x86/camellia-crypt-internal.asm: Moved addition of key.
+
+2010-09-22  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/nettle-benchmark.c (BENCH_INTERVAL): Changed unit to
+       seconds.
+       (time_function): Use clock_gettime with CLOCK_PROCESS_CPUTIME_ID,
+       if available. This gives better accuracy, at least on recent
+       linux.
+       (BENCH_INTERVAL): Reduced to 0.1 s.
+       (struct bench_memxor_info): New struct.
+       (bench_memxor): New function.
+       (time_memxor): New function.
+       (main): Use time_memxor. Added optional argument used to limit the
+       algorithms being benchmarked.
+       (GET_CYCLE_COUNTER): Define also for x86_64.
+       (time_memxor): Improved display.
+
+       * examples/Makefile.in (nettle-benchmark): Link using
+       $(BENCH_LIBS) rather than $(LIBS).
+
+       * configure.ac: Check for clock_gettime, and add -lrt to
+       BENCH_LIBS if needed.
+
+2010-09-20  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Less quoting when invoking $CC, to allow CC="gcc
+       -m32".
+
+       * x86/camellia-crypt-internal.asm (ROUND): Adapted to new key
+       convention, moving key xor to the end.
+
+       * camellia-set-encrypt-key.c (CAMELLIA_F_HALF_INV): Deleted macro.
+       (camellia_set_encrypt_key): Deleted the CAMELLIA_F_HALF_INV
+       operations intended for moving the key xor into the middle of the
+       round.
+
+       * camellia-crypt-internal.c (CAMELLIA_ROUNDSM): Moved addition of
+       key to the end, to use a 64-bit xor operation.
+
+       * x86_64/camellia-crypt-internal.asm: New file.
+
+       * x86_64/machine.m4 (LREG, HREG, XREG): New macros.
+
+2010-09-17  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Support shared libraries (dlls) with mingw32.
+       Contributed by David Hoyt.
+
+2010-07-25  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Changed version number to nettle-2.2.
+
+       * Released nettle-2.1.
+
+       * configure.ac: Use camellia-crypt-internal.asm, if available.
+       Bumped soname to libnettle.so.4, and reset LIBNETTLE_MINOR to
+       zero.
+
+       * x86/machine.m4 (LREG, HREG): Moved macros here, from...
+       * x86/aes.m4: ...here.
+
+       * x86/camellia-crypt-internal.asm: New file.
+
+       * nettle.texinfo: Updated and expanded section on DSA.
+       Document aes_invert_key, and camellia. Added missing functions
+       rsa_sha512_verify and rsa_sha512_verify_digest.
+
+       * camellia.h (struct camellia_ctx): Eliminate the two unused
+       subkeys, and renumber the remaining ones.
+       * camellia-crypt-internal.c (_camellia_crypt): Updated for
+       renumbered subkeys.
+       * camellia-set-encrypt-key.c (camellia_set_encrypt_key): Likewise.
+       * camellia-set-decrypt-key.c (camellia_invert_key): Likewise.
+
+       * camellia-set-encrypt-key.c (camellia_set_encrypt_key): Inline
+       the expansion of camellia_setup128 and camellia_setup256, keeping
+       the unexpanded key in scalar variables.
+       (camellia_setup128): Deleted.
+       (camellia_setup256): Deleted.
+
+2010-07-24  Niels Möller  <nisse@lysator.liu.se>
+
+       * camellia-set-encrypt-key.c (camellia_set_encrypt_key): Reduced
+       code size, no complete loop unroll. Use one loop for each phase of
+       the post-processing.
+
+       * testsuite/camellia-test.c: New tests for camellia_invert_key.
+       * testsuite/aes-test.c: New tests for aes_invert_key.
+
+       * aes.h (aes_invert_key): Declare it.
+
+       * aes-set-decrypt-key.c (aes_invert_key): New function, key
+       inversion code extracted from aes_set_decrypt_key.
+       (aes_set_decrypt_key): Use aes_invert_key.
+
+       * camellia-set-encrypt-key.c (camellia_setup128): Generate
+       unmodified subkeys according to the spec. Moved clever combination
+       of subkeys to camellia_set_encrypt_key.
+       (camellia_setup256): Likewise.
+       (camellia_set_encrypt_key): Moved subkey post-processing code
+       here, and reduce code duplication between 128-bit keys and larger
+       keys.
+
+       * camellia.c: Deleted file, split into several new files...
+       * camellia-table.c (_camellia_table): New file with the constant
+       sbox tables.
+       * camellia-set-encrypt-key.c: New file.
+       (camellia_setup128): Generate unmodified subkeys according to the
+       spec. Moved clever combination of subkeys to camellia_set_encrypt_key.
+       (camellia_setup256): Likewise.
+
+       * camellia-set-decrypt-key.c: New file.
+       (camellia_invert_key): Key inversion function.
+       (camellia_set_decrypt_key): New key setup function.
+       * camellia-internal.h: New file.
+       * camellia-crypt.c (camellia_crypt): New file, new wrapper
+       function passing the sbox table to _camellia_crypt.
+       * camellia-crypt-internal.c (_camellia_crypt): New file, with main
+       encrypt/decrypt function.
+       * Makefile.in (nettle_SOURCES): Updated list of camellia source files.  
+       (DISTFILES): Added camellia-internal.h.
+
+2010-07-20  Niels Möller  <nisse@lysator.liu.se>
+
+       * camellia-meta.c: Use _NETTLE_CIPHER_SEP_SET_KEY.
+
+       * camellia.h (struct camellia_ctx): Replaced flag camellia128 by
+       expanded key length nkeys.
+
+       * camellia.c (camellia_set_encrypt_key): Renamed, from...
+       (camellia_set_key): ... old name.
+       (camellia_invert_key): New function.
+       (camellia_set_decrypt_key): New function, using
+       camellia_invert_key.
+       (camellia_crypt): Renamed, from...
+       (camellia_encrypt): ... old name.
+       (camellia_decrypt): Deleted, no longer needed. camellia_crypt used
+       for both encryption and decryption.
+
+       * nettle-meta.h (_NETTLE_CIPHER_SEP_SET_KEY): New macro.
+
+       * dsa-keygen.c: Removed unnecessary include of memxor.h.
+
+       * camellia.c: Rewrote to use 64-bit type for subkeys and use
+       64-bit operations throughout. Performance on x86_32, when compiled
+       with gcc-4.4.4, is reduced by roughly 15%, this should be fixed
+       later.
+
+       * camellia.h (struct camellia_ctx): Use type uint64_t for subkeys.
+
+2010-07-07  Niels Möller  <nisse@lysator.liu.se>
+
+       * aes.h (aes_encrypt, aes_decrypt): Declare ctx argument as const.
+       Also updated implementation.
+       * blowfish.h (blowfish_encrypt, blowfish_decrypt): Likewise.
+       * cast128.h (cast128_encrypt, cast128_decrypt): Likewise.
+       * serpent.h (serpent_encrypt, serpent_decrypt): Likewise.
+       * twofish.h (twofish_encrypt, twofish_decrypt): Likewise.
+
+       * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added
+       camellia-test.c.
+
+       * examples/nettle-benchmark.c: Added camellia ciphers.
+
+       * Makefile.in (nettle_SOURCES): Added camellia.c and
+       camellia-meta.c.
+       (HEADERS): Added camellia.h.
+
+       * nettle-meta.h (nettle_camellia128): Declare.
+       (nettle_camellia192): Likewise.
+       (nettle_camellia256): Likewise.
+
+       * camellia-meta.c: New file.
+
+       * camellia.h: Rewrote interface to match nettle conventions.
+
+       * camellia.c: Converted to nettle conventions.
+       (camellia_encrypt128, camellia_encrypt256): Unified to new
+       function...
+       (camellia_encrypt): ...New function, with a loop doing 6
+       regular rounds, one FL round and one FLINV round per iteration,
+       with iteration count depending on the key size.
+
+       (camellia_decrypt128, camellia_decrypt256): Similarly unified
+       as...
+       (camellia_decrypt): ...New function, analogous to
+       camellia_encrypt.
+
+2010-07-06  Niels Möller  <nisse@lysator.liu.se>
+
+       * camellia.c, camellia.h: New files, copied from
+       http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/camellia-LGPL-1.2.0.tar.gz.
+
+       * testsuite/camellia-test.c: New file.
+
+2010-07-05  Niels Möller  <nisse@lysator.liu.se>
+
+       * nettle.texinfo: Document new conventions for weak key and des
+       parity checks. Document des_check_parity.
+
+       * testsuite/des-test.c (test_weak): Don't check the deleted status
+       attribute.
+
+       * des-compat.c (des_key_sched): Rewrote error checking logic for
+       the case of non-zero des_check_key.
+
+       * des3.c (des3_set_key): Changed weak key detection logic.
+       Complete key setup also for weak keys, and don't set the status
+       attribute.
+
+       * des.c (des_set_key): New iteration logic, to keep key pointer
+       unchanged. Moved weak key check to the end, and don't set the
+       status attribute.
+       (des_encrypt): Ignore status attribute.
+       (des_decrypt): Likewise.
+
+       * des.h (enum des_error): Deleted.
+       (struct des_ctx): Deleted status attribute.
+       (struct des3_ctx): Likewise.
+
+       * blowfish.c (initial_ctx): Deleted status value.
+       (blowfish_encrypt): Ignore status attribute.
+       (blowfish_decrypt): Likewise.
+       (blowfish_set_key): Return result from weak key check, without
+       setting the status attribute.
+
+       * blowfish.h (enum blowfish_error): Deleted.
+       (struct blowfish_ctx): Deleted status attribute.
+
+       * Makefile.in (des_headers): Deleted parity.h.
+
+2010-06-30  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/des-test.c (test_des): New function.
+       (test_weak): New function.
+       (test_main): Use test_des and test_weak. Added tests for all the
+       weak keys. Added some tests with invalid (to be ignored) parity
+       bits.
+
+       * des.c (parity_16): New smaller parity table.
+       (des_check_parity): New function.
+       (des_fix_parity): Use parity_16.
+       (des_weak_p): New weak-key detection. Ignores parity bits, and
+       uses a hash table.
+       (des_set_key): Deleted parity checking code. Replaced old weak-key
+       detection code by a call to des_weak_p.
+
+2010-06-04  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/testutils.c (test_dsa_key): Updated for new name
+       DSA_SHA1_MIN_P_BITS.
+
+       * dsa-keygen.c (dsa_generate_keypair): Use DSA_SHA1_MIN_P_BITS and
+       DSA_SHA256_MIN_P_BITS.
+
+       * dsa.h (DSA_MIN_P_BITS, DSA_Q_OCTETS, DSA_Q_BITS): Renamed to...
+       (DSA_SHA1_MIN_P_BITS, DSA_SHA1_Q_OCTETS, DSA_SHA1_Q_BITS): New
+       names.
+
+       * sexp2dsa.c (dsa_keypair_from_sexp_alist): New argument q_bits.
+       Renamed parameter limit to p_max_bits.
+       (dsa_sha1_keypair_from_sexp): Renamed, was dsa_keypair_from_sexp.
+       Updated to call dsa_keypair_from_sexp_alist with the new argument.
+       (dsa_sha256_keypair_from_sexp): New function.
+       (dsa_signature_from_sexp): New argument q_bits.
+
+       * der2dsa.c (dsa_params_from_der_iterator): Enforce 160-bit limit
+       on q. Renamed parameter limit to p_max_bits.
+       (dsa_openssl_private_key_from_der_iterator): Enforce 160-bit limit
+       on q and x. Renamed parameter limit to p_max_bits.
+
+2010-06-03  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/dsa-test.c (test_main): Added test for dsa-sha256.
+
+2010-06-02  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/dsa-test.c (test_main): Provide expected value of the
+       signature.
+
+       * testsuite/testutils.c (test_dsa160): Added argument for expected
+       signature.
+       (test_dsa256): Likewise.
+
+2010-06-01  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/rsa-keygen-test.c (test_main): Updated expected
+       signatures.
+
+       * examples/random-prime.c (main): Updated for nettle_random_prime
+       change.
+       * testsuite/random-prime-test.c (test_main): Likewise.
+
+       * rsa-keygen.c (bignum_random_prime): Deleted function.
+       (rsa_generate_keypair): Use new nettle_random_prime. Generate
+       secret factors p and q with the two most significant bits set.
+
+       * dsa-keygen.c (dsa_generate_keypair): Updated for changes in
+       nettle_random_prime and _nettle_generate_pocklington_prime. Invoke
+       progress callback.
+
+       * bignum-random-prime.c (_nettle_generate_pocklington_prime): New
+       argument top_bits_set, to optionally generate primes with the two
+       most significant bits set. Reordered argument list.
+       (nettle_random_prime): Likewise, added top_bits_set argument.
+       Invoke progress callback when a prime is generated.
+
+2010-05-26  Niels Möller  <nisse@lysator.liu.se>
+
+       * dsa-keygen.c (dsa_generate_keypair): Use
+       _nettle_generate_pocklington_prime. Deleted old key generation
+       code.
+
+       * bignum-random-prime.c (_nettle_generate_pocklington_prime): Also
+       return the used r. Updated caller.
+
+       * examples/random-prime.c (main): Allow sizes down to 3 bits.
+
+       * bignum-random-prime.c (_nettle_generate_pocklington_prime): New
+       function. Rely on mpz_probab_prime_p (for lack of a trial division
+       function) for trial division.
+       (nettle_random_prime): Rewritten. Uses the prime table for the
+       smallest sizes, then trial division using a new set of tables, and
+       then Maurer's algorithm, calling the new
+       _nettle_generate_pocklington_prime for the final search.
+
+2010-05-25  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/dsa-test.c (test_main): Updated for dsa testing
+       changes.
+
+       * testsuite/dsa-keygen-test.c (test_main): Test dsa256.
+
+       * testsuite/testutils.h (struct nettle_mac): New struct, currently
+       unused.
+
+       * testsuite/testutils.c (test_mac): New function (currently not
+       used).
+       (test_dsa): Replaced by two new functions...
+       (test_dsa160): New function.
+       (test_dsa256): New function.
+       (test_dsa_key): New argument q_size.
+       (DSA_VERIFY): Generalized.
+
+       * dsa-keygen.c (dsa_generate_keypair): Rewritten, now generating
+       primes using Pocklington's theorem. Takes both p_size and q_size
+       as arguments.
+
+2010-05-20  Niels Möller  <nisse@lysator.liu.se>
+
+       * bignum-random-prime.c (miller_rabin_pocklington): Fixed broken
+       logic when Miller-rabin succeeds early.
+
+2010-04-09  Niels Möller  <nisse@lysator.liu.se>
+
+       * bignum-next-prime.c: Include stdlib.h, needed for alloca on
+       freebsd.
+       * hmac.c: Likewise.
+
+       * examples/Makefile.in (SOURCES): Added random-prime.c.
+
+       * examples/random-prime.c: New program.
+
+       * testsuite/Makefile.in (TS_NETTLE_SOURCES): Moved
+       knuth-lfib-test.c, cbc-test.c, ctr-test.c, hmac-test.c here, from
+       TS_HOGWEED_SOURCES.
+       (TS_HOGWEED_SOURCES): Added random-prime-test.c.
+
+       * testsuite/random-prime-test.c: New test case.
+
+       * examples/next-prime.c (main): With no command line arguments.
+       exit after dislaying usage message.
+
+       * examples/io.c (simple_random): Free buffer when done.
+
+       * configure.ac: Changed message, say CC is the recommended
+       way to configure the ABI.
+
+       * bignum-random.c: Deleted test of HAVE_LIBGMP.
+       * bignum.c: Likewise.
+       * sexp2bignum.c: Likewise.
+
+       * Makefile.in (hogweed_SOURCES): Added bignum-random-prime.c.
+
+       * bignum-random-prime.c (nettle_random_prime): New file, new
+       function.
+
+2010-03-31  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/nettle-benchmark.c (main): Benchmark sha224.
+
+2010-03-30  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/testutils.c (DSA_VERIFY): Updated for dsa_sha1_verify
+       rename.
+       (test_dsa): Check return value from dsa_sha1_sign.
+
+       * Makefile.in (hogweed_SOURCES): Added dsa-sha1-sign.c,
+       dsa-sha1-verify.c, dsa-sha256-sign.c, and dsa-sha256-verify.c.
+
+       * dsa.h: Updated and added dsa declarations.
+
+       * dsa-sha256-verify.c (dsa_sha256_verify_digest): New file, new
+       function.
+       (dsa_sha256_verify): New function.
+       * dsa-sha256-sign.c (dsa_sha256_sign_digest): New file, new
+       function.
+       (dsa_sha256_sign): New function.
+
+       * dsa-sha1-verify.c (dsa_sha1_verify_digest): New file. Moved and
+       renamed function, from dsa_verify_digest, rewrote to use
+       _dsa_verify.
+       (dsa_sha1_verify): Analogous change, renamed from dsa_verify.
+       * dsa-sha1-sign.c (dsa_sha1_sign_digest): New file. Moved and
+       renamed function, from dsa_sign_digest, rewrote to use _dsa_sign,
+       and added return value.
+       (dsa_sha1_sign): Analogous change, renamed from dsa_sign.
+
+       * dsa-verify.c (_dsa_verify): New general verification function,
+       for any hash.
+       * dsa-sign.c (_dsa_sign): New general signing function, for any
+       hash. Returns success code, like the rsa signture functions.
+
+2010-03-29  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac (ABI): Attempt to use a better, ABI-dependant,
+       default value for libdir.
+
+       * x86/md5-compress.asm: Fixed function name in epilogue.
+
+       * asm.m4 (EPILOGUE): Use . to refer to current address.
+
+       * configure.ac (ABI): Detect which ABI the compiler is using.
+       On x86_64, also check for __arch64__.
+
+2010-03-28  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac (asm_path): For x86_64, check if compiler is
+       generating 32-bit code.
+
+2010-03-27  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/hmac-test.c (test_main): Rewrote rest of tests to use
+       HMAC_TEST, and added more tests from Daniel Kahn Gillmor and from
+       RFC 4231.
+
+       * Makefile.in (nettle_SOURCES): Added hmac-sha224.c and
+       hmac-sha384.c.
+
+       * hmac.h: Added declarations of hmac-sha224 and hmac-sha384.
+
+       * hmac-sha224.c: New file.
+
+2010-03-26  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/hmac-test.c (HMAC_TEST): New macro.
+       (test_main): Use HMAC_TEST for the md5 and sha1 tests, and add
+       test vectors from Daniel Kahn Gillmor.
+
+       * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added sha224-test.c.
+
+       * Makefile.in (nettle_SOURCES): Added sha224-meta.c and
+       write-be32.c.
+       (DISTFILES): Added nettle-write.h.
+
+       * sha.h: Added declarations for sha224. Some are aliases for the
+       corresponding sha256 definition.
+
+       * sha256.c (sha256_digest): Use _nettle_write_be32.
+       (sha224_init): New function.
+       (sha224_digest): New function.
+
+       * sha1.c (sha1_digest): Use _nettle_write_be32.
+
+       * nettle-internal.h (NETTLE_MAX_HASH_BLOCK_SIZE)
+       (NETTLE_MAX_HASH_DIGEST_SIZE): Increased, to take sha512 into
+       account.
+
+       * nettle-write.h: New file.
+
+       * write-be32.c (_nettle_write_be32): New file, new function.
+
+       * sha224-meta.c: New file.
+
+2010-03-25  Niels Möller  <nisse@lysator.liu.se>
+
+       * hmac-sha384.c: New file.
+
+       * testsuite/sha224-test.c: New file.
+
+       * testsuite/md4-test.c (test_main): More test vectors, provided by
+       Daniel Kahn Gillmor.
+       * testsuite/md5-test.c (test_main): Likewise.
+       * testsuite/sha1-test.c (test_main): Likewise.
+       * testsuite/sha256-test.c (test_main): Likewise.
+       * testsuite/sha384-test.c (test_main): Likewise.
+       * testsuite/sha512-test.c (test_main): Likewise.
+
+       * configure.ac: Bumped version numbers. Package version
+       nettle-2.1, library versions libnettle.so.3.1, libhogweed.so.2.0.
+
+       * examples/nettle-benchmark.c (main): Benchmark sha384.
+
+       * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added sha384-test.c.
+
+       * testsuite/sha384-test.c: New file.
+
+       * Makefile.in (nettle_SOURCES): Added sha384-meta.c.
+
+       * sha384-meta.c: New file.
+
+       * sha.h: Added declarations for sha384. Some are aliases for the
+       corresponding sha512 definition.
+
+       * sha512.c (sha512_write_digest): New function.
+       (sha512_digest): Use it.
+       (sha384_init): New function.
+       (sha384_digest): New function.
+
+2010-03-24  Niels Möller  <nisse@lysator.liu.se>
+
+       * sha512.c: (sha512_digest): Simplified handling of any final
+       partial word of the digest.
+
+       * sha512.c: Reorganized to use _nettle_sha512_compress.
+
+       * sha512-compress.c (_nettle_sha512_compress): Compression
+       function extracted from sha512.c to a new file.
+
+       * Makefile.in (nettle_SOURCES): Added sha256-compress.c and
+       sha512-compress.c.
+
+       * sha256.c: Reorganized to use _nettle_sha256_compress.
+
+       * sha256-compress.c (_nettle_sha256_compress): Compression
+       function extracted from sha256.c to a new file.
+
+       * examples/nettle-benchmark.c (main): Benchmark sha512.
+
+       * rsa-keygen.c (rsa_generate_keypair): Ensure that bit size of e
+       is less than bit size of n, and check for the unlikely case p = q.
+
+       * rsa.h (RSA_MINIMUM_N_OCTETS, RSA_MINIMUM_N_BITS): Reduced, to
+       correspond to pkcs#1 encryption of single byte messagees.
+
+       * pgp-encode.c (pgp_put_rsa_sha1_signature): Check return value
+       from rsa_sha1_sign.
+       * rsa-compat.c (R_SignFinal): Likewise.
+
+       * rsa-md5-sign.c (rsa_md5_sign): Check and propagate return value
+       from pkcs1_rsa_md5_encode.
+       (rsa_md5_sign_digest): Check and propagate return value from
+       pkcs1_rsa_md5_encode_digest.
+       * rsa-md5-verify.c (rsa_md5_verify): Check return value from
+       pkcs1_rsa_md5_encode.
+       (rsa_md5_verify_digest): Check return value from
+       pkcs1_rsa_md5_encode_digest.
+       * rsa-sha1-sign.c: Analogous changes.
+       * rsa-sha1-verify.c: Analogous changes.
+       * rsa-sha256-sign.c: Analogous changes.
+       * rsa-sha256-verify.c: Analogous changes.
+       * rsa-sha512-sign.c: Analogous changes.
+       * rsa-sha512-verify.c: Analogous changes.
+
+       * pkcs1-rsa-md5.c (pkcs1_rsa_md5_encode)
+       (pkcs1_rsa_md5_encode_digest): Added return value. Check and
+       propagate return value from pkcs1_signature_prefix.
+       * pkcs1-rsa-sha256.c (pkcs1_rsa_sha256_encode)
+       (pkcs1_rsa_sha256_encode_digest): Likewise.
+       * pkcs1-rsa-sha1.c (pkcs1_rsa_sha1_encode)
+       (pkcs1_rsa_sha1_encode_digest): Likewise.
+       * pkcs1-rsa-sha512.c (pkcs1_rsa_sha512_encode)
+       (pkcs1_rsa_sha512_encode_digest): Likewise.
+
+       * pkcs1.c (pkcs1_signature_prefix): Interface change, take both
+       the total size and digest size as arguments, and return a status
+       code to say if the size was large enough.
+
+       * testsuite/Makefile.in: Added hogweed dependency for the test
+       programs.
+
+2010-03-23  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/rsa-test.c (test_main): Test signing with sha512.
+
+       * testsuite/testutils.c (test_rsa_sha512): New function.
+
+       * Makefile.in (hogweed_SOURCES): Added pkcs1-rsa-sha512.c,
+       rsa-sha512-sign.c and rsa-sha512-verify.c.
+
+       * rsa.h: Added prototypes for sha512-related functions.
+       (RSA_MINIMUM_N_OCTETS, RSA_MINIMUM_N_BITS): Increased.
+       * pkcs1.h: Added prototypes for sha512-related functions.
+
+       * rsa-sha512-verify.c: New file.
+       * rsa-sha512-sign.c: New file.
+       * pkcs1-rsa-sha512.c: New file.
+
+2010-03-22  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (nettle_SOURCES): Added hmac-sha512.c.
+
+       * testsuite/hmac-test.c (test_main): Added test cases for
+       hmac-sha512.
+
+       * hmac.h: Declare functions sha512-related functions.
+       * hmac-sha512.c (hmac_sha512_set_key): New file.
+
+       Basic sha512 support.
+       * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added sha512-test.c.
+       * testsuite/sha512-test.c: New file.
+
+       * macros.h (READ_UINT64, WRITE_UINT64): New macros.
+
+       * Makefile.in (nettle_SOURCES): Added sha512.c and sha512-meta.c.
+       * sha.h: Added sha512-related declarations.
+       * nettle-meta.h: Likewise.
+       * sha512-meta.c: New file.
+       * sha512.c: New file.
+
+2010-03-06  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (distdir): Include x86_64 assembler files.
+
+2010-01-20  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Check for mpz_powm_sec.
+
+2010-01-13  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in ($(LIBHOGWEED_FORLINK)): Depend on
+       $(LIBNETTLE_FORLINK).
+
+       * configure.ac (LIBHOGWEED_LIBS): Added -lnettle -lgmp for the
+       default case. Follows debian, and also makes dlopen of
+       libhogweed.so work, without having to use RTLD_GLOBAL.
+       (LIBHOGWEED_LINK): Added -L., to find our libnettle.so.
+
+2009-10-21  Niels Möller  <nisse@lysator.liu.se>
+
+       * tools/Makefile.in (pkcs1-conv$(EXEEXT)): Added dependency on
+       ../libhogweed.a.
+
+2009-10-19  Niels Möller  <nisse@lysator.liu.se>
+
+       * tools/pkcs1-conv.c: Updated for dsa/der interface change.
+
+       * der2dsa.c (dsa_public_key_from_der_iterators): Split into two
+       new functions...
+       (dsa_params_from_der_iterator): New function.
+       (dsa_public_key_from_der_iterator): New function.
+       (dsa_openssl_private_key_from_der_iterator): Renamed, was
+       dsa_private_key_from_der_iterator.
+       (dsa_openssl_private_key_from_der): Likewise.
+       * dsa.h: Corresponding changees to prototypes and #defines.
+
+2009-10-12  Niels Möller  <nisse@lysator.liu.se>
+
+       * sexp-format.c: Removed conditioning on HAVE_LIBGMP.
+
+       * tools/pkcs1-conv.c: Support for DSA keys, contributed by Magnus
+       Holmgren.
+
+       * Makefile.in (hogweed_SOURCES): Added dsa2sexp.c and der2dsa.c.
+
+       * der2dsa.c: New file, contributed by Magnus Holmgren.
+       * dsa2sexp.c: Likewise.
+       * dsa.h: Added prototypes.
+
+       * configure.ac (LIBHOGWEED_MINOR): Bumped libhogweed minor
+       version, now it's 1.1.
+
+       * testsuite/rsa2sexp-test.c (test_main): Updated testcase for
+       "rsa-pkcs1".
+
+2009-10-11  Niels Möller  <nisse@lysator.liu.se>
+
+       * rsa2sexp.c (rsa_keypair_to_sexp): Changed default algorithm name
+       to "rsa-pkcs1".
+
+2009-09-20  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86/sha1-compress.asm: Improved performance by 17% on AMD K7,
+       by letting loopmix scramble the instruction order.
+
+2009-09-15  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86/sha1-compress.asm: Cleanup, removing old cruft. Slight
+       improvement to ROUND_F1_NOEXP. Slight reduction of
+       dependency-chains.
+
+2009-08-25  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86/sha1-compress.asm: Eliminated tmp variable for f3 rounds.
+
+       * examples/nettle-benchmark.c (bench_sha1_compress): New function,
+       for precise benchmarking of the compression function.
+
+2009-06-08  Niels Möller  <nisse@lysator.liu.se>
+
+       * Released nettle-2.0.
+
+2009-06-04  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Set version to 2.0
+
+2009-05-30  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (.texinfo.info): Don't use a temporary output file
+       $@T, trust makeinfo to remove output file on errors.
+
+2009-05-19  Niels Möller  <nisse@lysator.liu.se>
+
+       * nettle.texinfo: Changed license to public domain.
+
+2009-05-11  Niels Möller  <nisse@lysator.liu.se>
+
+       * nettle.texinfo: Fixes from Karl Berry. Added some more index
+       terms.
+
+2009-03-06  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86_64/aes-encrypt-internal.asm: Reduced unrolling. Keep state
+       in %eax--%edx only.
+       * x86_64/aes-decrypt-internal.asm: Likewise.
+
+       * x86_64/aes.m4 (MOVE_HREG): Deleted, no longer needed.
+       (AES_STORE): Reduced offsets.
+       (AES_ROUND): Use HREG directly, not MOVE_HREG.
+
+       * x86_64/aes-decrypt-internal.asm: Rearrange register allocation.
+       Put SA--SD in %eax--%edx, so the second byte can be accessed as
+       %ah-%dh. TD is not needed, SD can be reused. Use the register that
+       is saved for the outer loop counter, getting it off the stack.
+       * x86_64/aes-encrypt-internal.asm: Likewise.
+
+       * x86_64/aes.m4 (HREG, MOVE_HREG): New macros.
+       (XREG): Fixed bug in handling of %r8 and %r9.
+       (AES_ROUND): Use MOVE_HREG.
+
+2009-02-10  Niels Möller  <nisse@lysator.liu.se>
+
+       * base16-meta.c (base16_encode_update_wrapper): Mark ctx argument
+       as UNUSED.
+
+       * testsuite/sexp-conv-test: Updated testcases for improved
+       handling of comments.
+
+       * tools/sexp-conv.c (sexp_convert_item): Use sexp_put_soft_newline
+       to terminate comments, and modify indentation for the case that a
+       list starts with a comment.
+
+       * tools/output.c (sexp_output_init): Initialize soft_newline.
+       (sexp_put_raw_char): Clear soft_newline.
+       (sexp_put_newline): Check and reset soft_newline.
+       (sexp_put_soft_newline): New function.
+
+       * tools/output.h (struct sexp_output): Removed union with single
+       element, and updated all users. New attribute soft_newline.
+
+2008-12-22  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in ($(des_headers)): Create files in $(srcdir).
+
+2008-11-28  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/cxx-test.cxx: Include <cstdio>.
+
+2008-11-22  Niels Möller  <nisse@lysator.liu.se>
+
+       * yarrow256.c (yarrow256_fast_reseed): Set ctx->seeded = 1, so
+       that it is set if and only if the aes context has been initialized
+       with aes_set_encrypt_key.
+       (yarrow256_seed): No need to set ctx->seeded here.
+       (yarrow256_update): Likewise.
+
+2008-11-04  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/next-prime.c (main): Avoid using gmp_fprintf, to stay
+       compatible with gmp-3.1.
+
+2008-11-01  Niels Möller  <nisse@lysator.liu.se>
+
+       * nettle.texinfo: Updated for 2.0. New section on linking.
+
+       * nettle-types.h, nettle-meta.h: Moved all typedefs for function
+       types to nettle-types.h. Use non-pointer types, so that the types
+       can be used to declare functions. Updated all users.
+
+2008-10-31  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/yarrow-test.c (test_main): Updated for seed file
+       changes.
+
+       * sha-example.c (display_hex): Use %02x, not %2x.
+
+2008-10-30  Niels Möller  <nisse@lysator.liu.se>
+
+       * tools/sexp-conv.c (main): Fixed file locking.
+
+2008-10-25  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Set version to 2.0rc1.
+
+       * examples/Makefile.in (next-prime$(EXEEXT)): Added -lnettle to
+       linker.
+
+2008-10-24  Niels Möller  <nisse@lysator.liu.se>
+
+       * sha256.c (ROUND): Simplified macro.
+
+       * yarrow256.c (yarrow256_fast_reseed): Renamed (was
+       yarrow_fast_reseed) and made non-static. Don't generate seed file
+       here, let the application use yarrow256_random instead.
+       (yarrow256_slow_reseed): Renamed (was yarrow_slow_reseed) and made
+       non-static.
+       (yarrow256_force_reseed): Deleted function, use
+       yarrow256_slow_reseed instead. For backwards compatibility,
+       yarrow.h defines yarrow256_force_reseed as an alias for that
+       function.
+
+       * yarrow.h (struct yarrow256_ctx): Deleted seed_file buffer.
+
+2008-09-17  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86/arcfour-crypt.asm: Improved loop logic, and unrolled
+       loop twice. Gave a modest speedup.
+
+2008-09-15  Niels Möller  <nisse@lysator.liu.se>
+
+       * yarrow256.c (yarrow256_seed): Disallow length == 0.
+
+       * base64-decode.c (decode_table): Added vertical tab (VT) and form
+       feed (FF) as white space characters.
+
+       * x86_64/aes-decrypt-internal.asm: New file.
+
+2008-09-13  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86/aes-encrypt-internal.asm: Replaced pushl and popl in the
+       loop with movl. Eliminated redundant movl.
+       * x86/aes-decrypt-internal.asm: Likewise.
+
+       * x86_64/aes.m4: New file.
+
+       * x86/aes-encrypt-internal.asm: Updated for AES_FINAL_ROUND. Only
+       three times through the substitution loop.
+       * x86/aes-decrypt-internal.asm: Likewise.
+       * x86_64/aes-encrypt-internal.asm: Likewise.
+
+       * x86/aes.m4 (AES_FINAL_ROUND): Do the substitution on the least
+       significant byte here.
+
+       * x86/aes-encrypt-internal.asm: Updated use of AES_SUBST_BYTE. USe
+       decl for outer loop.
+       * x86/aes-decrypt-internal.asm: Likewise.
+
+       * x86/aes.m4 (LREG, HREG): New macros.
+       (AES_SUBST_BYTE): Take state registers as argument. Use LREG to
+       get the corresponding byte register.
+       (AES_ROUND): Use movzbl together with LREG and HREG.
+       (AES_SUBST_BYTE): Likewise.
+
+2008-09-10  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86_64/sha1-compress.asm: Avoid using registers %rbx and %rbp,
+       which must be preserved.
+
+2008-09-08  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (stamp-h.in): Use $(AUTOHEADER).
+
+       * x86_64/sha1-compress.asm: New x86_64 assembler, based on the x86
+       version.
+
+       * configure.ac (asm_path): Set up asm_path for x86_64.
+
+       * x86_64/machine.m4: New file, new directory.
+
+2008-08-28  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/eratosthenes.c (main): Rewrote block-wise sieving to
+       use less memory. New options -s and -v.
+
+2008-08-27  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/sexp-conv-test (print_raw, print_nl): Use printf.
+       Updated testcases with comments; comments are now preserved.
+
+       * tools/sexp-conv.c (sexp_convert_item): Keep comments in advanced
+       output.
+       (parse_options): New --lock option.
+       (main): Optionally lock output file.
+
+       * tools/parse.c (sexp_check_token): Removed check for "any" token.
+       All callers specify the token they expect.
+       (sexp_parse): Pass on comment tokens.
+
+       * tools/output.c (sexp_put_data): Made non-static.
+
+       * tools/input.c (sexp_get_comment): New function.
+       (sexp_get_token): Use sexp_get_comment.
+
+       * tools/misc.h (enum sexp_token): Start enumeration with zero, zero
+       is no longer used to mean any type. New type SEXP_COMMENT.
+
+       * configure.ac: Check for fcntl file locking.
+
+2008-08-26  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (tags-here): Put TAGS file in the source directory.
+       * examples/Makefile.in (tags): Likewise.
+       * testsuite/Makefile.in (tags): Likewise.
+       * tools/Makefile.in (tags): Likewise.
+
+2008-02-29  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/Makefile.in (SOURCES): Added next-prime.c.
+
+2008-01-05  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/Makefile.in (TARGETS): Added eratosthenes and next-prime.
+       (next-prime, eratosthenes): New rules.
+       (nettle-benchmark): Don't rely on $@.
+
+       * examples/eratosthenes.c (find_first_one): Optimized, using
+       slightly larger table.
+       (main): Use atol, rather than atoi.
+
+       * testsuite/symbols-test: Check symbols also in libhogweed.
+
+       * examples/next-prime.c: New file.
+       Deleted code for detailed timing.
+
+       * Makefile.in (hogweed_SOURCES): Added bignum-next-prime.c.
+       (DISTFILES): Added prime-list.h.
+       (hogweed_OBJS): Removed $(LIBOBJS).
+
+       * bignum-next-prime.c (nettle_next_prime): Renamed function, for
+       name space reasons. Was bignum_next_prime. Updated call in
+       rsa-keygen.c.
+       (primes): Use prime-list.h.
+       (nettle_next_prime): Skip Fermat test. Use mpz_millerrabin
+       directly, rather than mpz_probab_prime_p, when the former is
+       available.
+
+       * bignum.h (nettle_next_prime): New prototype.
+
+       * rsa-keygen.c (bignum_next_prime): Deleted, moved to
+       bignum-next-prime.c. Call with a larger prime limit, this improves
+       the running time of lsh-keygen by roughly 25%.
+
+       * prime-list.h: List of odd primes < 2^16.
+
+       * configure.ac: Check for sizeof(long).
+
+2008-01-03  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/nettle-benchmark.c (main): Removed incorrect UNUSED
+       from declaration.
+
+       * bignum-next-prime.c: Moved the bignum_next_prime function to a
+       separate file.
+
+2007-09-08  Niels Möller  <nisse@lysator.liu.se>
+
+       * sparc64/aes-encrypt-internal.asm: The directory with the aes.m4
+       include file was renamed from "sparc" to "sparc32". Updated include.
+       * sparc64/aes-decrypt-internal.asm: Likewise.
+       * sparc32/aes-encrypt-internal.asm: Likewise.
+       * sparc32/aes-decrypt-internal.asm: Likewise.
+
+2007-09-07  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/read_rsa_key.c: Include stdlib.h.
+
+2007-06-02  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in: Typo fixes to install targets, spotted by Magnus
+       Holmgren.
+
+2007-05-14  Niels Möller  <niels@s3.kth.se>
+
+       * configure.ac: Fixed copy-and-paste errors in shared library
+       name setup.
+
+       * config.make.in (LIBNETTLE_SONAME, LIBHOGWEED_SONAME): Define.
+
+       * Makefile.in (libnettle.so, libhogweed.so): Fixed rules.
+
+       * Makefile.in: Split nettle library into two files, libnettle.a
+       and libhogweed.a, and similarly for the shared libraries.
+
+       * configure.ac: Bumped nettle so-versions to 3.0. Set hogweed
+       so-versions to 1.0. New makefile conditionals IF_SHARED and
+       IF_HOGWEED. Renamed WITH_PUBLIC_KEY to WITH_HOGWEED. Deleted
+       SHLIBTARGET, SHLIBINSTALL, RSA_EXAMPLES and RSA_TOOLS.
+
+       * config.make.in: Updated for hogweed split.
+
+       * C source files: Don't use WITH_PUBLIC_KEY / WITH_HOGWEED, the
+       Makefile sorts out which files should be compiled.
+
+       * pgp.h: Include bignum.h, don't pretend to work without bignums.
+
+       * pgp-encode.c (pgp_put_mpi, pgp_put_public_rsa_key)
+       (pgp_put_rsa_sha1_signature): Define unconditionally. Removed the
+       checking of HAVE_LIBGMP and WITH_PUBLIC_KEY.
+
+       * examples/io.h: Use WITH_HOGWEED, not WITH_PUBLIC_KEY.
+       * examples/io.c (read_rsa_key): Deleted, moved to...
+       * examples/read_rsa_key.c: New file, extracted from io.c.
+
+       * examples/Makefile.in: Use IF_HOGWEED instead of RSA_EXAMPLES.
+       Link appropriate programs with -lhogweed.
+       (SOURCES): Added read_rsa_key.c.
+
+       * tools/Makefile.in (pkcs1-conv): Use IF_HOGWEED, not @RSA_TOOLS@,
+       for configuration. Link with -lhogweed.
+
+       * testsuite/testutils.h: Use WITH_HOGWEED, not WITH_PUBLIC_KEY.
+       * testsuite/testutils.c: Likewise.
+
+       * testsuite/Makefile.in (TS_NETTLE_SOURCES, TS_HOGWEED_SOURCES):
+       Separate test cases using nettle and those also using hogweed.
+
+2007-04-05  Niels Möller  <nisse@lysator.liu.se>
+
+       * Moved in CVS tree. Also renamed directory sparc to sparc32.
+
+2007-02-24  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (clean-here): Remove .lib directory.
+       (distclean-here): Remove machine.m4.
+
+2006-12-05  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: AC_PREREQ 2.61, for AC_PROG_MKDIR_P.
+
+       * config.make.in (datarootdir): New directory variable (for
+       autoconf-2.61).
+
+2006-11-28  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Bumped version to 1.16.
+
+       * Released nettle-1.15.
+
+2006-11-27  Niels Möller  <nisse@lysator.liu.se>
+
+       * NEWS: New entry for nettle-1.15.
+
+       * configure.ac (SHLIBMINOR): Bumped version. Library name is now
+       libnettle.so.2.6.
+
+       * sha256.c: Changed copyright notice to use the LGPL.
+
+       * Makefile.in (DISTFILES): Added COPYING.LIB.
+
+       * COPYING.LIB: New file (previously only the plain GPL was
+       included in the distribution).
+
+       * nettle.texinfo: Updated vor nettle-1.15.
+
+       * testsuite/rsa-test.c (test_main): Use test_rsa_sha256.
+       * testsuite/testutils.c (test_rsa_sha256): New function.
+
+       * testsuite/Makefile.in (DISTFILES): Replaces rfc1750.txt by
+       gold-bug.txt.
+
+       * rsa.h (rsa_sha256_sign, rsa_sha256_verify)
+       (rsa_sha256_sign_digest, rsa_sha256_verify_digest): New declarations.
+       (RSA_MINIMUM_N_OCTETS, RSA_MINIMUM_N_BITS): Increased to
+       62 octets and  489 bits, respectively, for supporting sha256.
+
+       * pkcs1.h (pkcs1_rsa_sha256_encode)
+       (pkcs1_rsa_sha256_encode_digest): New declarations and name
+       mangling symbols.
+
+       * Makefile.in (nettle_SOURCES): Added pkcs1-rsa-sha256.c,
+       rsa-sha256-sign.c, rsa-sha256-verify.c.
+
+       * pkcs1-rsa-sha256.c, rsa-sha256-sign.c, rsa-sha256-verify.c: New
+       files.
+
+       * COPYING, INSTALL, install-sh, texinfo.tex: Updated files, from
+       automake-1.10.
+
+2006-11-27  Niels Möller  <niels@s3.kth.se>
+
+       * tools/Makefile.in (install): Use MKDIR_P to create installation
+       directory. Install only one file at a time.
+
+       * Makefile.in (MKDIR_P): Use MKDIR_P for creating installation
+       directories.
+
+       * configure.ac: Use AC_PROG_MKDIR_P.
+
+2006-11-24  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/yarrow-test.c (test_main): Use gold-bug.txt as input
+       file, instead of rfc1750.txt.
+
+       * testsuite/gold-bug.txt: New test input file for yarrow-test.
+       The copyright on this short story by Edgar Allan Poe has expired.
+
+       * testsuite/rfc1750.txt: Deleted file. Debian considers RFC:s
+       non-free, and it was expired anyway. Replaced by gold-bug.txt.
+
+2006-11-24  Niels Möller  <niels@s3.kth.se>
+
+       * Almost all header files: Added C++ guards.
+
+       * configure.ac: Test if the system has any C++ compiler.
+
+       * config.make.in (CXX, CXXFLAGS, COMPILE_CXX, LINK_CXX): New variables.
+
+       * testsuite/Makefile.in: New variables TS_C and TS_CXX. Setup for
+       compiling the C++ file cxx-test.cxx.
+
+       * testsuite/cxx-test.cxx: New testcase, trying to use nettle from
+       a C++ program.
+
+2006-08-28  Niels Möller  <niels@s3.kth.se>
+
+       * index.html: Added section on language bindings.
+
+2006-06-10  Niels Möller  <niels@s3.kth.se>
+
+       * configure.ac: Darwin shared library support, from Grant
+       Robinsson.
+
+2006-05-18  Niels Möller  <nisse@lysator.liu.se>
+
+       * src/nettle/x86/aes.asm: Deleted unused file.
+
+       * aes-decrypt.c (_aes_decrypt_table): Deleted the indexing array,
+       previously commented out.
+       * aes-encrypt-table.c (_aes_encrypt_table): Likewise.
+
+       * Makefile.in (.texinfo.info, .dvi.ps): Use more quotes with
+       basename.
+       (install-here, install-shared, install-info, install-headers): Use
+       plain mkdir, not $(INSTALL) -d.
+
+2006-05-16  Niels Möller  <niels@s3.kth.se>
+       Merged from the lsh experimental branch.
+
+2006-04-26  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/rsa-decrypt.c: Don't include "getopt.h", since it's not used.
+       * examples/nettle-benchmark.c: Include "getopt.h".
+
+       * examples/Makefile.in (GETOPT_OBJS): New variable.
+       (rsa-keygen, rsa-encrypt, nettle-benchmark): Depend on and link
+       with $(GETOPT_OBJS).
+
+       * x86/aes-decrypt-internal.asm: Use ALIGN.
+       * x86/aes-encrypt-internal.asm: Likewise.
+       * x86/arcfour-crypt.asm: Likewise.
+       * x86/md5-compress.asm: Likewise.
+       * x86/sha1-compress.asm: Likewise.
+
+       * config.m4.in (ASM_ALIGN_LOG): Substitute.
+       * configure.ac (ASM_ALIGN_LOG): Check if .align directive is
+       logarithmic.
+       * asm.m4 (ALIGN): New macro. Takes a logarithmic argument, and
+       expands to a .align directive.
+
+2006-04-21  Niels Möller  <nisse@lysator.liu.se>
+
+       * nettle.texinfo (Public-key algorithms): Say that the public key
+       operations are undocumented, not unsupported. Reported by Jeronimo
+       Pellegrini.
+
+2006-04-08  Niels Möller  <nisse@lysator.liu.se>
+
+       * tools/pkcs1-conv.c (read_pem): Fixed c99-style declaration.
+       Reported by Henrik Grubbström.
+
+2006-01-31  Niels Möller  <niels@s3.kth.se>
+
+       * examples/rsa-verify.c: Fixed typo in usage message.
+
+2005-12-05  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Bumped version to 1.15,
+
+       * Released nettle-1.14.
+
+       * NEWS: Updated for 1.14.
+
+       * configure.ac (SHLIBMINOR): Increased minor number. Library
+       version is now libnettle.so.2.5, soname still libnettle.so.2.
+
+2005-11-28  Niels Möller  <nisse@lysator.liu.se>
+
+       * config.make.in (INSTALL): Don't substitute INSTALL, INSTALL_DATA
+       and friends here, to get a correct a relative filename for
+       install-sh when used in tools/Makefile.
+
+       * tools/Makefile.in (INSTALL): Substitute INSTALL, INSTALL_DATA
+       and friends here.
+       * Makefile.in (INSTALL): Likewise.
+
+2005-11-27  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (.texinfo.pdf): New rule. Avoid dependency on
+       intermediate .dvi and .ps files.
+
+       * testsuite/Makefile.in (clean): Delete sha1-huge-test.
+
+       * Makefile.in (install-info, install-headers): Don't use $< and
+       $?; Solaris make doesn't support them in explicit rules.
+
+2005-11-26  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/Makefile.in: Include .test-rules.make, which contains
+       the rules for all the test executables.
+       (test-rules): New rule, to update this file.
+       (DISTFILES): Added $(EXTRA_SOURCES).
+
+       * testsuite/.test-rules.make: Automatically generated file for
+       building the test programs.
+
+2005-11-25  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Disable assembler when compiling with rntcl.
+
+       * tools/Makefile.in (pkcs1_conv_SOURCES): New variable.
+       (pkcs1-conv): Link with getopt.o and getopt1.o.
+
+       * Makefile.in (aesdata, desdata, shadata): Use explicit rules for
+       executables.
+
+       * testsuite/Makefile.in: Use %-rules for building the -test
+       executables, in addition to the suffix rules. Hopefully, this
+       should make all of GNU make, BSD make and Solaris make happy.
+       Use $(EXEEXT) and $(OBJEXT) more consistently.
+
+       * examples/Makefile.in: Use explicit rules for all executable
+       targets. Use $(EXEEXT) and $(OBJEXT) more consistently.
+
+2005-11-25  Niels Möller  <niels@s3.kth.se>
+
+       * testsuite/Makefile.in: Avoid using single-suffix rule to build
+       executables.
+
+2005-11-24  Niels Möller  <niels@s3.kth.se>
+
+       * Makefile.in (distdir): Use [ -f, not [ -e, since the latter
+       is less portable, and not supported by Solaris /bin/sh.
+
+2005-11-23  Niels Möller  <niels@s3.kth.se>
+
+       * testsuite/Makefile.in (DISTFILES): Added teardown-env.
+       * testsuite/teardown-env: New file. Delete files created by the
+       testsuite.
+
+2005-11-21  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/testutils.c (main): Fixed check for -v option. Spotted
+       by Goran K.
+
+2005-11-21  Niels Möller  <niels@s3.kth.se>
+
+       * ctr.h (CTR_CTX, CTR_CRYPT): Fixed bugs, spotted by Goran K.
+
+2005-11-20  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (nettle_SOURCES): Added der2rsa.c.
+
+       * testsuite/Makefile.in (TS_SH): Added pkcs1-conv-test.
+
+       * tools/Makefile.in (TARGETS): Added @RSA_TOOLS@.
+       (SOURCES): Added pkcs1-conv.c.
+       (pkcs1-conv): New rule.
+
+       * tools/pkcs1-conv.c: New program.
+
+       * testsuite/pkcs1-conv-test: New file.
+
+       * examples/rsa-verify-test: Use rsa-sign to create signature.
+
+       * examples/io.c (read_file): Fixed spelling in error message.
+
+       * rsa.h (rsa_public_key_from_der_iterator)
+       (rsa_private_key_from_der_iterator, rsa_keypair_from_der): Declare
+       functions.
+
+       * der2rsa.c: New file.
+
+       * der-iterator.c (asn1_der_iterator_init): Initialize length and
+       data.
+       (asn1_der_iterator_next): Support for lengths >= 0x80.
+       (asn1_der_decode_constructed_last, asn1_der_decode_bitstring)
+       (asn1_der_decode_bitstring_last): New functions.
+       (asn1_der_get_bignum): Check for non-mininal encodings.
+
+       * configure.ac (RSA_TOOLS): New substituted variable. Includes
+       pkcs1-conv, when public-key support is enabled.
+
+       * bignum.h (nettle_asn1_der_get_bignum): Include nettle_-prefix in
+       declaration.
+
+       * asn1.h: Added name mangling defines, and a few new declarations.
+
+2005-11-13  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (nettle_SOURCES): Added der-iterator.c.
+       (HEADERS): Added asn1.h.
+
+       * bignum.h (asn1_der_get_bignum): Declare function.
+
+       * der-iterator.c: New file.
+       * asn1.h: New file.
+
+2005-11-07  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/nettle-benchmark.c: Check HAVE_UNISTD_H.
+
+       * examples/Makefile.in (TARGETS): Use $(EXEEXT).
+       * tools/Makefile.in (TARGETS, sexp-conv, nettle-lfib-stream): Likewise.
+
+       * configure.ac: Use $host_cpu, not $host, when setting up the
+       assembler path. Use $host_os, not uname, when setting up shared
+       library flags.
+
+       * Makefile.in (des.$(OBJEXT)): Use OBJEXT.
+
+       * config.guess, config.sub: In the CVS tree, moved files to the
+       lsh top-level directory.
+
+2005-10-23  Niels Möller  <nisse@lysator.liu.se>
+
+       * sparc64/arcfour-crypt.asm: New file, almost the same as
+       sparc/arcfour-crypt.asm.
+
+       * examples/nettle-benchmark.c (display): Use two decimal places.
+
+       * sparc/arcfour-crypt.asm: Reorganized. Main loop unrolled four
+       times. Uses aligned 32-bit write accesses at DST. Still uses 8-bit
+       read accesses at SRC; could be improved int he case that SRC and
+       DST have compatible alignment.
+
+2005-10-19  Niels Möller  <niels@s3.kth.se>
+
+       * testsuite/arcfour-test.c (test_main): New testcase with 512
+       bytes of data.
+
+2005-10-19  Niels Möller  <nisse@lysator.liu.se>
+
+       * sparc/arcfour-crypt.asm: Fixed bug, spotted by Mikael Kalms. We
+       must order the store at [CTX+I] before the load of [CTX+SI+SJ].
+
+2005-10-18  Niels Möller  <nisse@lysator.liu.se>
+
+       * sparc/arcfour-crypt.asm: Special unrolled code if SRC and DST
+       have compatible alignment. Improves performance by 20%, but I'm
+       not sure it's worth the extra complexity.
+
+       * bignum.c (nettle_mpz_from_octets): Removed sign argument. If
+       mpz_import is available, define nettle_mpz_from_octets as a macro
+       calling mpz_import.
+       (nettle_mpz_from_octets): Start by setting x to zero; callers no
+       longer need to do that.
+       (nettle_mpz_set_str_256_s): New logic for the handling of negative
+       numbers. Convert in the same way as for positive numbers, and then
+       subtract the appropriate power of two.
+
+2005-10-17  Niels Möller  <nisse@lysator.liu.se>
+
+       * bignum.c (nettle_mpz_from_octets): Improved loop. Removed the
+       digit temporary (suggested by Torbjörn Granlund).
+
+       * sparc/arcfour-crypt.asm: Improved instruction scheduling.
+
+       * sparc/arcfour-crypt.asm: Bugfix, use lduh and stuh.
+
+       * sparc/arcfour-crypt.asm: New file.
+
+       * sparc64/aes.asm: Deleted unused file.
+
+       * x86/arcfour-crypt.asm: Use ARCFOUR_I and ARCFOUR_J
+       * asm.m4 (ARCFOUR): New struct.
+
+2005-10-17  Niels Möller  <niels@s3.kth.se>
+
+       * aes-internal.h (struct aes_table): Deleted idx and sparc_idx
+       arrays.
+       * aes-encrypt-table.c (_aes_encrypt_table): Likewise.
+       * aes-decrypt.c (_aes_decrypt_table): Likewise.
+       * asm.m4 (AES): Likewise
+
+2005-10-16  Niels Möller  <nisse@lysator.liu.se>
+
+       * tools/input.c (sexp_get_char): Use unsigned for the done flag.
+
+       * sparc64/aes-encrypt-internal.asm: Include sparc/aes.m4.
+       * sparc64/aes-decrypt-internal.asm: Likewise.
+
+       * sparc64/machine.m4: Use .register pseudo op to say that we use
+       %g2 and %g3 as scratch registers.
+
+       * sparc/aes-encrypt-internal.asm: Explicitly include sparc/aes.m4.
+       * sparc/aes-decrypt-internal.asm: Likewise.
+
+       * sparc/aes.m4: New file. Moved aes-related macros here...
+       * sparc/machine.m4: ... removed aes macros.
+
+       * x86/aes-encrypt-internal.asm: Explicitly include x86/aes.m4.
+       * x86/aes-decrypt-internal.asm: Likewise.
+
+       * x86/aes.m4: New file. Moved aes-related macros here, from...
+       * x86/machine.m4: ... removed aes macros.
+
+       * sparc64/aes-encrypt-internal.asm: New file.
+       * sparc64/aes-decrypt-internal.asm: New file.
+
+       * sparc64/machine.m4: Include the same aes macros used for
+       sparc32.
+       (BIAS): Define magic stack bias constant.
+
+       * sparc/aes-encrypt-internal.asm, sparc/aes-decrypt-internal.asm:
+       Reduced frame size to 104 bytes, since we no longer need wtxt and
+       tmp on the stack.
+
+       * sparc/aes.asm: Deleted old aes implementation.
+
+       * sparc/aes-decrypt-internal.asm: New file.
+
+       * sparc/machine.m4: Don't use m4 eval, instead rely on the
+       assembler's arithmetic.
+
+       * sparc/machine.m4 (AES_FINAL_ROUND): Better scheduling, by
+       interleaving independent operations.
+
+       * sparc/machine.m4 (TMP3): A third temporary register.
+       (AES_FINAL_ROUND): Prepared for scheduling.
+
+       * sparc/machine.m4 (AES_ROUND): Deleted unused argument T. Updated
+       all calls in aes-encrypt-internal.asm.
+
+       * sparc/machine.m4 (AES_ROUND): New loop invariants T0-T3, to
+       avoid the additions of the AES_TABLEx constants in the inner loop.
+
+       * sparc/machine.m4 (AES_ROUND): Better scheduling, by
+       interleaving independent operations.
+
+       * sparc/machine.m4 (AES_ROUND): Alternate between using TMP1 and
+       TMP2, to prepare for scheduling.
+
+       * sparc/aes-encrypt-internal.asm: Renamed Ti -> Xi.
+
+       * sparc/aes-encrypt-internal.asm: Fixed bugs. Now passes the
+       testsuite.
+
+       * sparc/machine.m4 (AES_ROUND, AES_FINAL_ROUND): Bugfixes. Put
+       NOPs in the load dely slots.
+
+       * sparc/aes-encrypt-internal.asm: Implemented. Not yet working,
+       and not optimized.
+
+       * sparc/machine.m4: Use TMP1 and TMP2, so we don't need to pass
+       them as arguments.
+       (AES_FINAL_ROUND): New macro.
+
+2005-10-15  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac (OBJDUMP): Substitute the program false if objdump
+       is not found.
+
+       * asm.m4 (PROLOGUE): Use TYPE_FUNCTION.
+
+       * config.m4.in: Substitute ASM_TYPE_FUNCTION as TYPE_FUNCTION.
+
+       * configure.ac (ASM_ELF_STYLE): Check for %function and #function,
+       but not for @function.
+       (ASM_TYPE_FUNCTION): New substituted variable.
+
+       * configure.ac (ASM_ELF_STYLE): Fixed .type foo,@function statement
+       used when checking for pseudo operations.
+
+       * sparc/machine.m4 (AES_LOAD, AES_ROUND): Started writing new AES
+       macros.
+
+       * sparc/aes-encrypt-internal.asm: New file.
+
+2005-10-14  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86/aes-decrypt.asm, x86/aes-encrypt.asm: Deleted files.
+
+       * x86/aes-decrypt-internal.asm: New file.
+
+       * x86/machine.m4: Changed AES macros, to handle a table register.
+       Also take more of the used registers as argument.
+
+       * x86/aes-encrypt-internal.asm: Rewritten to match new interface,
+       with the table pointer as an argument. Unlike the old code, this
+       should really be position independent.
+
+       * configure.ac: When looking for assembler files, link in
+       aes-encrypt-internal.asm and aes-decrypt-internal.asm. Don't look
+       for aes.asm, aes-encrypt.asm and aes-decrypt.asm.
+
+       * configure.ac (OBJDUMP): Use AC_CHECK_TOOL to check for objdump.
+       (ASM_MARK_NOEXEC_STACK): Use $OBJDUMP when examining the object file.
+
+       * Makefile.in (nettle_SOURCES): Removed aes.c,
+       aes-decrypt-table.c. Added aes-decrypt-internal.c and aes-encrypt-internal.c.
+
+       * aes.c, aes-decrypt-table.c: Deleted files.
+
+       * aes-decrypt.c (_aes_decrypt_table): Moved table here, and made
+       static.
+
+       * aes-internal.h (_aes_decrypt_table): Don't declare, it's no
+       longer globally visible.
+
+       * aes-decrypt-internal.c (_nettle_aes_decrypt): New AES decryption
+       function, analogous to _nettle_aes_encrypt.
+
+2005-10-14  Niels Möller  <niels@s3.kth.se>
+
+       * aes-internal.h (AES_ROUND, AES_FINAL_ROUND): New macros.
+
+       * aes-encrypt-internal.c (_nettle_aes_encrypt): New AES encryption
+       function, avoiding the table-based indexing.
+
+       * sha1-compress.c: Added debugging code.
+       * md5-compress.c: Likewise.
+
+2005-10-13  Niels Möller  <niels@s3.kth.se>
+
+       * config.m4.in (ASM_MARK_NOEXEC_STACK): Use a diversion, to
+       substitute the value of ASM_MARK_NOEXEC_STACK at the end of each
+       assembler file.
+
+       * configure.ac (ASM_MARK_NOEXEC_STACK): Check if the C compiler
+       generates a .note.GNU-stack section. If so, we should do the same
+       in our assembler files.
+
+       * sparc64/aes.asm: New file. Copy of sparc/aes.asm, with minor
+       changes to the stack frame layout. Patch contributed by Henrik
+       Grubbström. Not yet tested.
+
+       * x86/md5-compress.asm: Skip copying of input to the stack, and
+       don't allocate space for it.
+       (F1): Fixed bug.
+
+       * testsuite/md5-test.c: Document intermediate values for first
+       test case.
+
+       * configure.ac (asm_path): Check for sparc64, and use sparc64
+       subdirectory. Link in md5-compress.asm, if it exists.
+
+2005-10-13  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86/md5-compress.asm (REF): Fixed calculation of offset.
+
+2005-10-12  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86/machine.m4 (OFFSET): Moved macro, used to be in...
+       * x86/sha1-compress.asm (OFFSET): ... removed macro.
+
+       * x86/md5-compress.asm: New file, with first attempt at md5
+       assembler. Not yet working.
+
+2005-10-11  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (nettle_SOURCES): Added md5-compress.c.
+
+       * md5.c: Reorganized to use _nettle_md5_compress, in analogy with
+       sha1.c.
+
+       * md5-compress.c (_nettle_md5_compress): New file and new function.
+
+2005-10-10  Niels Möller  <niels@s3.kth.se>
+
+       * testsuite/Makefile.in (EXTRA_SOURCES, EXTRA_TARGETS): New
+       variables, for test cases that are not run by default.
+
+       * testsuite/sha1-huge-test.c (test_main): New test case, with a
+       very large sha1 input.
+
+       * testsuite/testutils.c (test_hash_large): New function.
+
+       * sha1.c (sha1_block): Deleted function; inlined where used.
+       (SHA1_INCR): New macro for incrementing the block count.
+
+2005-10-06  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Bumped version to 1.14.
+
+       * Released nettle-1.13.
+
+       * configure.ac: Check for openssl/aes.h.
+
+       * Makefile.in (distdir): Use a loop to pick up the contents of
+       $(DISTFILES) from source and build directories. For some reason,
+       $? failed to find stamp-h.in in the source directory.
+
+2005-10-05  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86/aes-decrypt.asm: Use C_NAME(_nettle_aes_decrypt_table) when
+       using the AES_SUBST_BYTE macro. Use PROLOGUE and EPILOGUE.
+       * x86/sha1-compress.asm: Use PROLOGUE and EPILOGUE.
+       * x86/arcfour-crypt.asm: Likewise.
+       * x86/aes-encrypt.asm: Likewise.
+
+       * config.m4.in (ELF_STYLE): Substitute configure's ASM_ELF_STYLE.
+
+       * asm.m4 (PROLOGUE, EPILOGUE): New macros, checking the value of
+       ELF_STYLE. So far, used and tested only for the x86 assembler
+       files, and needed to make the assembler happy both with ELF
+       (linux, solaris) and COFF (windows).
+
+       * configure.ac (NM): Use AC_CHECK_TOOL to check for nm.
+       (ASM_SYMBOL_PREFIX): Use $NM when examining the object file.
+       (ASM_ELF_STYLE): New variable. Set to 'yes' if assembling a file
+       with ELF-style .type and .size pseudo ops works.
+
+       * Makefile.in (TARGETS, DISTFILES): Added nettle.pdf.
+       (.texinfo.dvi, .dvi.ps, .ps.pdf): New targets, to build nettle.pdf.
+       (DOCTARGETS): New variable with targets that shouldn't be deleted
+       by make clean.
+       (maintainer-clean-here): New target. Deletes generated
+       documentation files.
+
+       * nettle.texinfo: Define AUTHOR with accents, when running in TeX
+       mode, which doesn't handle latin-1 properly. Set UPDATED-FOR to
+       1.13. Updated copyright years, and introduced a COPYRIGHT-YEARS
+       symbol. Updated copyright section, to mention assembler
+       implementations.
+       (Cipher modes): Transformed the Cipher Block Chaining to a section
+       Cipher modes, describing both CBC and the new CTR mode.
+
+       * src/nettle/x86/aes_tables.asm: Deleted unused file.
+
+       * x86/aes.asm: Deleted contents. This file is needed just to
+       override aes.c, which isn't needed for the x86 implementation.
+
+       * configure.ac (SHLIBMINOR): Increased minor number. Library
+       version is now libnettle.so.2.4, soname still libnettle.so.2.
+
+       * examples/nettle-benchmark.c (main): Reordered hash benchmarks.
+
+       * x86/sha1-compress.asm (EXPAND): Use % 16 instead of & 15 to
+       compute offsets mod 16, since m4 on FreeBSD 49.RELEASE and NetBSD
+       doesn't implement & correctly in eval.
+
+2005-10-03  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86/sha1-compress.asm (OFFSET): New macro.
+       (F3): Eliminated a movl.
+       (ROUND): New argument, for k. When using F3, it's TMP3, on the
+       stack, otherwise, it is kept in TMP2, a register.
+
+2005-10-03  Niels Möller  <niels@s3.kth.se>
+
+       * examples/nettle-openssl.c: Use correct block sizes for openssl
+       ciphers.
+
+       * examples/nettle-benchmark.c: Also display cycles per block.
+
+2005-10-02  Niels Möller  <nisse@lysator.liu.se>
+
+       * sha1-compress.c (_nettle_sha1_compress): Updated to new
+       interface. Now responsible for byte conversion.
+
+       * x86/sha1-compress.asm (_nettle_sha1_compress): Do byte order
+       conversion, and store the input data on the stack. This leaves one
+       more register free for other uses.
+
+       * examples/nettle-benchmark.c: Now display cycles/byte, if the -f
+       option is used to say what the clock frequency is.
+
+       * sha1.c (sha1_block): Don't convert data from uint8_t to
+       uint32_t, that's now the responsibility of _nettle_sha1_compress.
+
+       * sha.h (_nettle_sha1_compress): Changed interface. Second
+       argument is now a pointer to the input data in unaligned,
+       big-endian form.
+
+2005-09-28  Niels Möller  <niels@s3.kth.se>
+
+       * sha1.c (sha1_final): Call sha1_block, don't call the compression
+       function _nettle_sha1_compress directly.
+
+       * nettle-internal.h (nettle_openssl_md5)
+       (nettle_openssl_sha1): Declare.
+
+       * examples/nettle-benchmark.c (main): Benchmark openssl md5 and
+       sha1.
+
+       * examples/nettle-openssl.c (nettle_openssl_md5)
+       (nettle_openssl_sha1): Added glue for openssl hash functions.
+
+       * nettle-internal.h (nettle_openssl_aes128, nettle_openssl_aes192)
+       (nettle_openssl_aes256, nettle_openssl_arcfour128): Declare.
+
+       * examples/nettle-benchmark.c: Check WITH_OPENSSL, not
+       HAVE_LIBCRYPTO. Benchmark openssl's aes and arcfour code.
+
+       * examples/nettle-openssl.c: Updated openssl des glue to use the
+       new openssl des interface. Added glue for arcfour and aes.
+
+2005-09-27  Niels Möller  <nisse@lysator.liu.se>
+
+       * nettle.texinfo (RSA): Improved text about the RSA patent.
+       Use @documentencoding ISO-8859-1.
+
+2005-09-07  Niels Möller  <niels@s3.kth.se>
+
+       * tools/sexp-conv.c (parse_options): New option --raw-hash, for
+       compatibility with lsh-1.x. Equivalent to --hash.
+
+2005-09-06  Niels Möller  <niels@s3.kth.se>
+
+       * tools/sexp-conv.c (main): With --hash, output a newline after
+       each hash.
+
+2005-07-02  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/Makefile.in (TS_SOURCES): Added ctr-test.c.
+
+       * testsuite/testutils.c (test_cipher_ctr): New function.
+
+       * testsuite/ctr-test.c: New file.
+
+       * testsuite/cbc-test.c (test_main): Use static const for msg.
+
+       * Makefile.in (nettle_SOURCES): Added ctr.c.
+       (HEADERS): Added ctr.h.
+       (HEADERS): Added nettle-types.h.
+       (INSTALL_HEADERS): Install nettle-stdint.h.
+       (distclean-here): Delete nettle-stdint.h, not nettle-types.h.
+
+       * ctr.c (ctr_crypt): New file, new function.
+
+       * memxor.c (memxor3): New function, suggested by Adam Langley.
+
+       * nettle-internal.h (NETTLE_MAX_CIPHER_BLOCK_SIZE): New constant.
+
+       * nettle.texinfo (Cipher functions): Fixed typo in prototype for
+       arctwo_encrypt (noticed by Adam Langley).
+
+       * nettle-meta.h: No longer needs to include cbc.h.
+
+       * cbc.h (nettle_crypt_func): Moved typedef to nettle-types.h.
+       (CBC_ENCRYPT, CBC_DECRYPT): Deleted older #if:ed out versions.
+
+       * configure.ac (AX_CREATE_STDINT_H): Use the file name
+       nettle-stdint.h, not nettle-types.h.
+
+       * nettle-types.h: New file. Automatically generated declarations
+       are now in nettle-stdint.h.
+
+2005-03-17  Niels Möller  <niels@s3.kth.se>
+
+       * config.guess: Support Solaris on x86_64. Fix by Henrik
+       Grubbström.
+
+2005-01-03  Niels Möller  <niels@s3.kth.se>
+
+       * examples/io.h: Include RSA declarations only when public key
+       algorithms are enabled. Problem reported by Meilof Veeningen
+       <meilof@gmail.com>.
+
+2004-12-07  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in: Install directories, using $(INSTALL) -d, only if
+       they don't exist already.
+
+2004-12-05  Niels Möller  <nisse@lysator.liu.se>
+
+       * config.make.in (.PRECIOUS): Reverted earlier change. We need
+       .PRECIOUS to stop GNU make from deleting object files for the test
+       programs.
+
+2004-12-02  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (.SUFFIXES): Moved from Makefile.in to...
+       * config.make.in (.SUFFIXES): ... here. This helps compilation
+       with BSD make.
+       * testsuite/Makefile.in (.SUFFIXES): Deleted target.
+
+       * config.make.in (.c): Disable default rule for BSD-make.
+
+       * Makefile.in (all check install uninstall)
+       (clean distclean mostlyclean maintainer-clean): Don't use the -C
+       flag when invoking make, for compatibility with Solaris make.
+
+2004-12-02  Niels Möller  <niels@s3.kth.se>
+
+       * Makefile.in (aesdata, desdata): Commented out the explicit
+       targets.
+       (shadata): Avoid using $< in non-pattern rule.
+
+2004-12-01  Niels Möller  <nisse@lysator.liu.se>
+
+       * config.make.in: Added a default target.
+
+2004-11-29  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/Makefile.in: Use .$(OBJEXT). Explicitly set .SUFFIXES.
+
+       * Makefile.in: Use .$(OBJEXT).
+
+2004-11-28  Niels Möller  <nisse@lysator.liu.se>
+
+       * tools/Makefile.in (nettle-lfib-stream): Avoid using $< in
+       non-suffix rule.
+
+       * Makefile.in (distdir): Handle absolute $distdir.
+       Avoid using the GNU extension $^.
+
+       * examples/Makefile.in: Avoid using the GNU extension $^.
+       * tools/Makefile.in: Likewise.
+       * testsuite/Makefile.in: Likewise.
+
+2004-11-24  Niels Möller  <niels@s3.kth.se>
+
+       * configure.ac: Fixed typo, preventing the creation of dependency
+       files.
+
+2004-11-23  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in: Use DEP_INCLUDE.
+       * tools/Makefile.in: Likewise.
+       * testsuite/Makefile.in: Likewise.
+       * examples/Makefile.in: Likewise.
+
+       * configure.ac (dummy-dep-files): Generate only of dependency
+       tracking is enabled.
+
+2004-11-18  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (clean-here): The clean target should not delete the
+       dependency files. Moved to the distclean target.
+       * examples/Makefile.in: Likewise.
+       * testsuite/Makefile.in: Likewise.
+       * tools/Makefile.in: Likewise.
+
+       * configure.ac (ASM_SYMBOL_PREFIX): Fixed test.
+       (dummy-dep-files): Added quotes to sed command.
+
+2004-11-17  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/symbols-test: Try plain nm if nm -g doesn't work.
+
+       * x86/sha1-compress.asm: Use C_NAME for global symbols.
+       * x86/aes-encrypt.asm: Likewise.
+       * x86/aes-decrypt.asm: Likewise.
+       * x86/arcfour-crypt.asm: Likewise.
+
+       * Makefile.in (config.m4): New rule.
+
+       * config.m4.in (C_NAME): New macro.
+
+       * configure.ac (ASM_SYMBOL_PREFIX): Check if global symbols have a
+       leading underscore.
+
+2004-11-16  Niels Möller  <nisse@lysator.liu.se>
+
+       * Deleted getopt.c, getopt.h and getopt1.c from the CVS tree. Link
+       them from shared copies in lsh/misc instead.
+
+2004-11-14  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (DEP_FILES): Try include with only one macro
+       argument to be expanted.
+
+       * configure.ac (dummy-dep-files): Create dummy dependency files,
+       so that they can be included by the makefiles.
+
+2004-11-13  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in: Don't use -include, as it's GNU make specific.
+       * examples/Makefile.in, tools/Makefile.in, testsuite/Makefile.in:
+       Likewise.
+
+       * examples/nettle-openssl.c: Check WITH_OPENSSL, not HAVE_LIBCRYPTO.
+
+       * configure.ac: Check for individual openssl headers blowfish.h,
+       cast.h, des.h. Renamed symbol HAVE_LIBCRYPTO to WITH_OPENSSL. New
+       configure option --disable-openssl.
+
+2004-11-04  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Bumped version to 1.13.
+
+       * Released nettle-1.12.
+
+2004-11-04  Niels Möller  <niels@s3.kth.se>
+
+       * nettle.texinfo (UPDATED-FOR): Bumped to 1.12.
+
+2004-11-02  Niels Möller  <nisse@lysator.liu.se>
+
+       * nettle.texinfo (Cipher functions): Updated AES documentation,
+       for aes_set_encrypt_key and aes_set_decrypt_key.
+       (UPDATED-FOR): Set to 1.11. I think the manual should be updated
+       with all user-visible changes.
+
+       * aclocal.m4 (LSH_DEPENDENCY_TRACKING): Need extra quoting in case
+       pattern. (This file really lives in the lsh tree, as
+       lsh/acinclude.m4. For a complete ChangeLog, see lsh/Changelog).
+
+2004-10-26  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Bumped version to 1.12.
+
+       * Released nettle-1.11.
+
+       * Makefile.in (clean-here): Delete *.s files.
+       (PRE_CPPFLAGS): Use this variable, not INCLUDES. Removed
+       -I$(srcdir).
+
+       * x86/arcfour-crypt.asm: Use movzbl when extending %cl to 32 bits.
+
+2004-10-24  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86/arcfour-crypt.asm: Reverted the latest two changes; update
+       bost src and dst pointers in the loop, and use plain addb when
+       updating j. These two previous changes slowed the code down on AMD
+       Duron.
+
+2004-10-21  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (install-shared): Use $(INSTALL_PROGRAM).
+
+       * configure.ac (SHLIBMINOR): Updated, shared library version is
+       now libnettle.so.2.3, soname still libnettle.so.2.
+
+       * Makefile.in (DISTFILES): Added asm.m4.
+
+2004-10-21  Niels Möller  <niels@s3.kth.se>
+
+       * examples/Makefile.in: Deleted all configure-related rules,
+       except the one rebuilding this Makefile. One should run make at
+       top level if other configure related files change.
+       * tools/Makefile.in: Likewise.
+       * testsuite/Makefile.in: Likewise.
+
+       * configure.ac: Replaced AC_OUTPUT(list...) with an AC_OUTPUT
+       without arguments, and AC_CONFIG_FILES listing the files.
+
+       * Makefile.in: Changed the assembler rules as suffix rules.
+       Rewrote the configure-related rules, mostly based on the example
+       in the autoconf manual.
+
+2004-10-20  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/nettle-openssl.c (NCOMPAT): Disable openssl backwards
+       compatibility.
+
+       * config.make.in: Insert $(PRE_CPPFLAGS) and $(PRE_LDFLAGS) before
+       $(CPPFLAGS) and $(LDFLAGS). This mechanism replaces $(INCLUDES).
+
+       * examples/Makefile.in (PRE_CPPFLAGS, PRE_LDFLAGS): Use these
+       flags to get -I.. and -L.. early on the command line.
+       * testsuite/Makefile.in: Likewise
+       * tools/Makefile.in: Likewise.
+
+2004-10-20  Niels Möller  <niels@s3.kth.se>
+
+       * Makefile.in: In the assembler rules, there's no need to look in
+       $(srcdir) for the input file.
+
+       * x86/arcfour-crypt.asm: Reduced inner loop by one instruction, by
+       precomputing the offset between src and dst.
+
+       * tools/Makefile.in (.c.$(OBJEXT)): Removed redundant -I.. flag.
+
+       * x86/arcfour-crypt.asm (nettle_arcfour_crypt): Replaced addb ->
+       addl + andl $0xff, improving speed on PPro by another 15%.
+
+2004-10-20  Niels Möller  <nisse@lysator.liu.se>
+
+       * tools/Makefile.in (install): Support DESTDIR.
+       (uninstall): New target.
+
+       * testsuite/Makefile.in (uninstall): New dummy target.
+
+       * config.sub: Copied from automake-1.8.5.
+
+       * examples/Makefile.in (SOURCES): Added rsa-sign.c and rsa-verify.c.
+       (DISTFILES): Added getopt.h.
+       (install uninstall): New dummy targets.
+
+       * config.make.in (.PHONY): Added more targets.
+
+       * Makefile.in (.texinfo.info, .texinfo.html): New targets. Added
+       support for uninstall and DESTDIR. Various fixes to install and
+       distcheck.
+
+       * examples/Makefile.in (INCLUDES): Added -I flags.
+       (distdir): Use $^ to refer to the files.
+       (distclean): New target.
+       * testsuite/Makefile.in: Likewise.
+       * tools/Makefile.in: Likewise.
+
+       * Makefile.in (INCLUDES): Need -I flags for VPATH build.
+       (clean distclean mostlyclean maintainer-clean): Clean
+       subdirectories first.
+       (DISTFILES): Added a bunch of files.
+       (des_headers): Added desCore rules.
+       (install-here): Split off target install-headers, which uses $^ to
+       refer to the files.
+       (distdir): Use $^ to refer to the files.
+       distcheck): Fixes.
+
+       * config.make.in (COMPILE): Add $(INCLUDE) to the line.
+
+2004-10-19  Niels Möller  <nisse@lysator.liu.se>
+
+       Stop using automake. Replaced each Makefile.am with a hand-written
+       Makefile.in.
+       * configure.ac: New output variable CCPIC_MAYBE. New output file
+       config.make. Replaced automake constructions.
+       * .bootstrap: Don't run aclocal and automake.
+       * config.make.in: New file, with shared Makefile variables and rules.
+
+2004-10-18  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86/arcfour-crypt.asm (nettle_arcfour_crypt): Replace incb ->
+       incl + andl, to improve speed on PPro and PII. Suggested by
+       Fredrik Olsson.
+
+2004-10-08  Niels Möller  <niels@s3.kth.se>
+
+       * examples/rsa-encrypt-test: Avoid reading and executing a file at
+       the same time.
+       * examples/setup-env: Likewise.
+
+2004-10-06  Niels Möller  <niels@s3.kth.se>
+
+       * testsuite/symbols-test: Ignore __i686.get_pc_thunk.bx and
+       similar symbols.
+
+2004-10-05  Niels Möller  <nisse@lysator.liu.se>
+
+       * twofish.c (q_table): Use a const pointer array.
+
+       * sexp2dsa.c (dsa_keypair_from_sexp_alist): Use a const pointer
+       array for the keywords.
+       (dsa_signature_from_sexp): Likewise.
+       * sexp2rsa.c (rsa_keypair_from_sexp_alist): Likewise.
+       (rsa_keypair_from_sexp): Likewise.
+
+       * sexp.c (sexp_iterator_check_types): Use an argument of type
+       "const uint8_t * const *" for the types list.
+       (sexp_iterator_assoc): Likewise, for the keys list.
+
+       * list-obj-sizes.awk: Fixes to handle multiple .data and .rodata
+       sections. Also fixed to handle the last file correctly.
+
+2004-09-23  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac (SHLIBLINK, SHLIBLIBS): On cygwin, linking needs
+       -Wl,--whole-archive $(OBJECTS) -Wl,--no-whole-archive $(LIBS).
+
+2004-09-22  Niels Möller  <niels@s3.kth.se>
+
+       * configure.ac: Setup SHLIBFORLINK and friends for cygwin.
+
+       * list-obj-sizes.awk: Strip *_a-prefix from all file names.
+
+       * Makefile.am (libnettle_a_SOURCES): List only .c files. Headers
+       moved to noinst_HEADERS.
+       (SHLIBOBJECTS): Substitute from libnettle_a_SOURCES, not
+       am_libnettle_a_OBJECTS, since the latter includes
+       libnettle_a-prefixes with some automake versions.
+       (SHLIBSONAME): Check if this name is empty, which is the case on
+       cygwin, before using it.
+
+2004-08-31  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: New command line option --disable-pic. Use
+       LSH_CCPIC.
+
+       * Makefile.am (libnettle_a_CFLAGS): Added $(CCPIC), to attempt to
+       build also the static library as position independent code.
+
+2004-08-24  Niels Möller  <nisse@lysator.liu.se>
+
+       * des-compat.c (des_cbc_cksum): Pad input with NUL's, if it's not
+       an integral number of blocks.
+
+2004-08-24  Niels Möller  <niels@s3.kth.se>
+
+       * testsuite/arctwo-test.c, arctwo.h, arctwo.c
+       (arctwo_set_key_ekb): Fixed typo; it should be "ekb", not "ebk".
+
+       Integrated arctwo patch from Simon Josefsson.
+       * testsuite/Makefile.am (noinst_PROGRAMS): Added arctwo-test.
+
+       * Makefile.am (libnettleinclude_HEADERS): Added arctwo.h.
+       (libnettle_a_SOURCES): Added arctwo.c, arctwo.h and arctwo-meta.c.
+
+       * nettle-meta.h (nettle_arctwo40, nettle_arctwo64)
+       (nettle_arctwo64, nettle_arctwo_gutmann128): Declare ciphers.
+
+       * arctwo-meta.c, arctwo.c, arctwo.h, testsuite/arctwo-test.c: New
+       files.
+
+       * macros.h (LE_READ_UINT16, LE_WRITE_UINT16): New macros.
+
+2004-08-23  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/md5-test.c (test_main): Added collision, found in 2004.
+       (test_main): Added second collision.
+
+2004-08-23  Niels Möller  <niels@s3.kth.se>
+
+       * testsuite/md5-test.c (test_main): Added first half of a
+       collision test case.
+
+       * des-compat.c (des_cbc_cksum): Changed input argument to be of
+       type const uint8_t * (was const des_cblock *).
+
+       * des-compat.h (const_des_cblock): New bogus type. Disabled use of
+       const, for compatibility with openssl.
+
+2004-06-08  Niels Möller  <niels@s3.kth.se>
+
+       * aesdata.c: Renamed log and ilog to gf2_log and gf2_exp.
+
+2004-04-07  Niels Möller  <nisse@lysator.liu.se>
+
+       * aes-set-encrypt-key.c (log, ilog): Deleted unused tables.
+
+       * aes-set-decrypt-key.c (gf2_log, gf2_exp, mult): Renamed tables,
+       were log and ilog.
+
+2004-03-20  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Use AC_CONFIG_AUX_DIR([.]).
+
+2004-03-18  Niels Möller  <niels@s3.kth.se>
+
+       * examples/io.c (read_file): Display a message if fopen fails.
+
+2004-03-05  Niels Möller  <nisse@lysator.liu.se>
+
+       * Released nettle-1.10.
+
+       * configure.ac (SHLIBMINOR): Shared library version is now 2.2.
+
+2004-03-04  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/symbols-test: Pass -g flag to nm.
+
+2004-03-02  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Fixed EXEEXT workaround.
+
+2004-03-02  Niels Möller  <niels@s3.kth.se>
+
+       * configure.ac: Added workaround to get the correct $(EXEEXT)=''
+       when compiling with rntcl.
+
+2004-03-02  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/Makefile.am (noinst_PROGRAMS): Put test program list
+       here, to let automake add $(EXEEXT).
+
+       * configure.ac (RSA_EXAMPLES): Append $(EXEEXT) to the filenames.
+
+2004-03-01  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/rsa-keygen.c, examples/rsa-encrypt.c,
+       examples/rsa-decrypt.c: Include "getopt.h" instead of <unistd.h>.
+
+       * examples/Makefile.am (rsa_encrypt_SOURCES, rsa_decrypt_SOURCES)
+       (rsa_keygen_SOURCES): Added getopt.h, getopt.c and getopt1.c.
+
+       * examples/getopt.h, examples/getopt.c, examples/getopt1.c: New
+       files.
+
+       * testsuite/des-compat-test.c: Don't include <unistd.h>.
+
+       * testsuite/testutils.c (main): Don't use getopt. Then we don't
+       need to include <unistd.h>.
+
+2004-03-01  Niels Möller  <niels@s3.kth.se>
+
+       * config.guess: Copied from automake-1.8.2. Hacked to recognize
+       Windows_NT (and Windows_95 and Windows_98) running on "x86" and
+       "686".
+
+       * install-sh: Removed from CVS repository. Let automake supply it.
+
+2004-02-26  Niels Möller  <nisse@lysator.liu.se>
+
+       * nettle-meta.h (nettle_crypt_func): Typedef moved to cbc.h.
+       Include cbc.h instead.
+
+       * des-compat.c: Reverted const change, now all the des_key_sched
+       arguments are not const. This is also what openssl's interface
+       looks like.
+       (cbc_crypt_func): Deleted typedef, use nettle_crypt_func instead.
+
+       * cbc.h (nettle_crypt_func): Moved typedef here.
+       * cbc.c (cbc_encrypt, cbc_decrypt_internal, cbc_decrypt): Use it
+       for typing the f argument. Reverted the const change, for
+       compatibility with nettle_crypt_func.
+
+2004-02-25  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/des-compat-test.c: Use des_cblock for typing more of
+       the variables. Use const. Got rid of most of the explicit casts.
+       Disabled the input/output alignment tests.
+
+       * des.c (des_encrypt, des_decrypt): Use a const context pointer.
+       * des3.c (des3_encrypt, des3_decrypt): Likewise.
+
+       * cbc.c (cbc_encrypt, cbc_decrypt): Use a _const_ void *ctx argument.
+
+       * des-compat.c: Use const for all unchanged arguments.
+       (des_key_sched): Use a copy of the key if we need to fix the
+       parity.
+
+       * testsuite/des-compat-test.c (C_Block, Key_schedule): Deleted
+       defines. Deleted some of the explicit casts.
+
+       * des-compat.c (des_cbc_cksum): Dereference DST pointer.
+
+2004-02-25  Niels Möller  <niels@s3.kth.se>
+
+       * pgp.h: Include nettle-types.h.
+
+2004-02-24  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/symbols-test: Allow symbols starting with double
+       underscores, like on darwin.
+
+2004-02-17  Niels Möller  <niels@s3.kth.se>
+
+       * Makefile.am: Protected %-rules used for building pure objects,
+       and for assembler files, by automake conditionals. Needed for
+       makes such as tru64's, which tries to understand %-patterns, but
+       doesn't get it right.
+       (SUFFIXES): Added .html.
+       (.texinfo.html): Rewrote rule to use a traditional suffix target.
+
+       * configure.ac (enable_assembler): Explicitly set
+       enable_assembler=no, on architectures where we have no assembler
+       files.
+       (ENABLE_ASSEMBLER, ENABLE_SHARED): New automake conditionals.
+
+       * testsuite/testutils.c (xalloc): xalloc(0) should work also on
+       systems where malloc(0) returns NULL.
+
+2004-02-16  Niels Möller  <niels@s3.kth.se>
+
+       * Makefile.am (%.o: %.asm): Added comment about OSF1 make problem.
+
+2004-02-15  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/testutils.h: #include nettle-types.h instead of
+       inttypes.h.
+
+2004-02-12  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/rsa-encrypt-test: Use -r option when invoking
+       rsa-encrypt. Needed for the test to work on systems with no
+       /dev/urandom.
+
+2004-02-12  Niels Möller  <niels@s3.kth.se>
+
+       * configure.ac (CPPFLAGS, LDFLAGS): No spaces after -I and -L, as
+       some C compilers, in particular True64 cc, don't like that.
+
+2004-02-08  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Bumped version number to 1.10.
+
+2004-02-07  Niels Möller  <nisse@lysator.liu.se>
+
+       * Released nettle-1.9.
+
+       * configure.ac (SHLIBMINOR): Bumped, library version is now 2.1.
+
+       * testsuite/sexp-format-test.c: Include bignum.h only if HAVE_LIBGMP.
+       * testsuite/rsa-encrypt-test.c: Include rsa.h only if WITH_PUBLIC_KEY.
+       * testsuite/pkcs1-test.c: Include pkcs1.h only if WITH_PUBLIC_KEY.
+
+       * pgp-encode.c [!HAVE_LIBGMP]: Kludge around the pgp.h's
+       dependency on gmp.h.
+       (pgp_put_mpi): Condition on HAVE_LIBGMP.
+
+       * pgp.h: Don't include bignum.h, to make it possible to compile
+       the non-bignum parts of pgp-encode.c without bignum support. Needs
+       to be fixed properly before the pgp interface is advertised.
+
+       * tools/sexp-conv.c (xalloc): New function.
+       (main): Use xalloc.
+
+       * tools/output.c (sexp_put_digest): Use TMP_DECL instead of alloca.
+
+       * testsuite/testutils.c (xalloc): New function. Made all other
+       functions use xalloc instead of alloca.
+
+       * examples/rsa-keygen.c (main): Use xalloc for allocation.
+       * examples/rsa-encrypt.c (write_bignum): Likewise.
+       * examples/rsa-decrypt.c (read_bignum): Likewise.
+       * testsuite/yarrow-test.c (open_file): Likewise.
+       * testsuite/rsa-encrypt-test.c (test_main): Likewise.
+       * testsuite/bignum-test.c (test_bignum): Likewise.
+
+       * examples/nettle-openssl.c: When calling des_key_sched and
+       des_ecb_encrypt, cst arguments to (void *). Openssl's typedefs
+       des_cblock and const_des_cblock are too broken.
+
+       * examples/nettle-benchmark.c (xalloc): New function. Use instead
+       of alloca, for better portability.
+
+       * examples/io.c (xalloc): New function.
+
+       * Makefile.am (nodist_libnettleinclude_HEADERS): nettle-types.h
+       should not be distributed.
+
+2004-02-06  Niels Möller  <niels@s3.kth.se>
+
+       * x86/sha1-compress.asm: Rename round -> ROUND.
+
+       * x86/sha1-compress.asm: Store the magic constants on stack.
+       Accessing them via %esp should be a little faster than using large
+       immediate operands.
+
+       * Makefile.am (EXTRA_DIST, DISTCLEANFILES): Handle
+       sha1-compress.asm.
+
+       * configure.ac: Use assembler file sha1-compress.asm if available.
+
+       * x86/sha1-compress.asm (EXPAND): Fixed the rotation part of the
+       data expansion.
+
+2004-02-06  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86/sha1-compress.asm: Assembler implementation of
+       sha1_compress. (Not yet working).
+
+       * Makefile.am (libnettle_a_SOURCES): Added sha1-compress.c.
+
+       * sha1.c (sha1_transform): Function renamed to sha1_compress, and
+       moved to...
+       * sha1-compress.c: ... New file.
+
+2004-02-05  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/rsa-encrypt.c (process_file): Copy the leftover to the
+       start of the buffer, when preparing for the final processing.
+
+       * examples/nettle-benchmark.c (bench_hash, time_hash): New functions.
+       (main): Benchmark hash functions too.
+       (BENCH_BLOCK): Increased 10K.
+       (BENCH_INTERVAL): Decreased to 0.25s.
+
+       * examples/nettle-benchmark.c (time_function): Loop around calling
+       f, until 1s has elapsed. Returns seconds per call. Updated bench
+       functions to not loop themselves.
+       (display): Updated MB/s calculation.
+
+       * testsuite/arcfour-test.c (test_main): Use test_cipher_stream.
+
+       * testsuite/testutils.c (test_cipher_stream): New function, that
+       tries dividing the input into varying size blocks before
+       processing.
+
+       * x86/arcfour-crypt.asm (nettle_arcfour_crypt): Bug fix, half of
+       the S array swap was forgotten.
+       * arcfour.c (arcfour_stream): Likewise.
+       * arcfour-crypt.c (arcfour_crypt): Likewise.
+
+2004-02-05  Niels Möller  <niels@s3.kth.se>
+
+       * x86/arcfour-crypt.asm (nettle_arcfour_crypt): Must store the new
+       i, j at the end of the loop.
+
+       * Makefile.am (EXTRA_DIST): Make sure x86 assembler files are
+       distributed.
+       (DISTCLEANFILES): And that the symlinks and .s files are deleted.
+
+       * x86/aes-encrypt.asm, x86/aes-decrypt.asm, x86/arcfour-crypt.asm:
+       Fixed debug information.
+
+       * x86/arcfour-crypt.asm: New file. About three times faster than
+       the optimized C code.
+
+       * configure.ac: Use assembler file arcfour-crypt.asm if available.
+
+       * arcfour.c (arcfour_crypt): Moved function too...
+       * arcfour-crypt.c (arcfour_crypt): New file.
+
+       * arcfour.c (arcfour_crypt): Optimization suggested by Jonas
+       Walldén. Makes arcfour up to 50% faster on x86 and ppc, and
+       probably on other architectures as well.
+
+2004-01-31  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac (AX_CREATE_STDINT_H): Also look for uint32_t and
+       friends in sys/types.h.
+
+2004-01-11  Niels Möller  <nisse@harpo.hack.org>
+
+       * Makefile.am (libnettleinclude_HEADERS): Added bignum.h,
+       memxor.h, pkcs1.h and rsa-compat.h.
+
+       * configure.ac: Bumped version to 1.9.
+
+2004-01-10  Niels Möller  <nisse@harpo.hack.org>
+
+       * Released nettle-1.8.
+
+       * examples/teardown-env: Delete more test files.
+
+       * nettle.texinfo (Hash functions): Documented md2 and md4.
+
+       * configure.ac (SHLIBMAJOR): Bumped to 2.
+
+2004-01-09  Niels Möller  <nisse@harpo.hack.org>
+
+       * examples/rsa-encrypt-test: New testcase.
+
+       * examples/rsa-encrypt.c, examples/rsa-session.h: Expanded the
+       comment describing the file format, and moved to rsa-session.h.
+
+       * examples/rsa-decrypt.c (process_file): Finished this function.
+       (main): Initialize x. Check the size of the session key after rsa
+       decryption.
+
+       * examples/io.c (write_string): Treat short item count as an error.
+
+2004-01-08  Niels Möller  <niels@s3.kth.se>
+
+       * index.html: Added instructions for CVS access.
+
+       * dsa-keygen.c (dsa_nist_gen): Fixed declaration/statement order.
+
+       * rsa-keygen.c (bignum_next_prime): Fixed off-by-one error when
+       comparing input to the largest listed prime. General cleanup, as
+       prime_limit > 0 always. Use TMP_DECL and TMP_ALLOC.
+
+       * nettle-internal.h (TMP_DECL, TMP_ALLOC): New macros. When alloca
+       is unavailable, they work by allocating a fix amount of stack and
+       imposing a hard limit on what can be allocated. Updated all users
+       of alloca.
+
+2004-01-07  Niels Möller  <nisse@harpo.hack.org>
+
+       * nettle-types.h: New (generated) file, to be used instead of
+       including <inttypes.h> directly. Updated all users of inttypes.h.
+
+       * Makefile.am (DISTCLEANFILES, libnettleinclude_HEADERS): Added
+       nettle-types.h.
+
+       * configure.ac (AX_CREATE_STDINT_H): Create nettle-types.h.
+
+2003-11-16  Niels Möller  <nisse@harpo.hack.org>
+
+       * yarrow256.c (yarrow256_seed): Use const for the seed_file input.
+
+2003-11-12  Niels Möller  <niels@s3.kth.se>
+
+       * list-obj-sizes.awk: New function for decoding hex values, with a
+       new function hex2int. Also implemented calculation of total
+       storage, removed the dependence on the .comment section, and use
+       the $FILTER environment variable as a regexp for restricting the
+       object files that are considered.
+
+2003-09-21  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/rsa-encrypt-test.c (test_main): Don't use gmp_printf,
+       as it seems it's only available with the newer gmp. Use
+       mpz_out_str instead.
+
+2003-09-19  Niels Möller  <niels@s3.kth.se>
+
+       * examples/Makefile.am (EXTRA_DIST): Added rsa-session.h.
+
+       * tools/nettle-lfib-stream.c: New tool, which outputs a sequence
+       of pseudorandom (non-cryptographic) bytes, using Knuth's lagged
+       fibonacci generator.
+
+       * examples/rsa-decrypt.c: Fixes to get the file to compile. It
+       won't work yet.
+
+       * examples/Makefile.am (EXTRA_PROGRAMS): Added rsa-encrypt and
+       rsa-decrypt.
+
+       * examples/io.c (write_file): New function.
+       (write_string): Simplified error check, it's no real point in
+       calling ferror unless we also call fflush.
+
+       * examples/rsa-keygen.c (main): Check return value from
+       simple_random.
+
+       * examples/rsa-decrypt.c, examples/rsa-encrypt.c,
+       examples/rsa-session.h: New files, demonstrating rsa encryption
+       and decryption.
+
+       * configure.ac (RSA_EXAMPLES): Added rsa-encrypt and rsa-decrypt.
+
+2003-09-01  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/testutils.c (print_hex): Use const.
+
+2003-08-30  Niels Möller  <niels@s3.kth.se>
+
+       * md2.c, md2.h: Added reference to RFC 1319.
+       * md4.c, md4.h: Added reference to RFC 1320
+
+2003-08-26  Niels Möller  <niels@s3.kth.se>
+
+       * Makefile.am: Added md2 and md5 files. Deleted the print-path
+       hack.
+
+       * configure.ac: Bumped version to 1.8.
+
+       * testsuite/testutils.c (test_rsa_set_key_1): New function.
+       * testsuite/rsa-test.c (test_main): Use it.
+
+       * testsuite/dsa-keygen-test.c: Deleted definition of UNUSED, it's
+       now in config.h.
+       * testsuite/rsa-keygen-test.c: Likewise.
+
+       * testsuite/Makefile.am (TS_PROGS): Added rsa-encrypt-test,
+       md4-test, and md2-test.
+
+       * testsuite/rsa-encrypt-test.c, testsuite/md4-test.c,
+       testsuite/md2-test.c: New test cases.
+
+       * nettle-meta.h: Declare nettle_md2 and nettle_md4.
+
+       * md5.c: Reorderd functions, putting md5_final at the end.
+
+       * md2.c, md2.h, md2-meta.c: New files, implemented md2.
+       * md4.c, md4.h, md4-meta.c: New files, implemented md4.
+
+2003-08-17  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * desCode.h (des_keymap, des_bigmap): Deleted extern declarations,
+       they conficted with the static definition in des.c. Reported by
+       Simon Josefsson.
+
+       * des.c (DesSmallFipsEncrypt, DesSmallFipsDecrypt): Moved
+       definitions after the definition of the des_kemap array.
+
+2003-08-11  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * rsa-encrypt.c (rsa_encrypt): Bugfix contributed by
+       leg@terra.com.br.
+
+2003-06-10  Niels Möller  <niels@s3.kth.se>
+
+       * Makefile.am (EXTRA_DIST): Distribute sha-example.c.
+
+2003-06-05  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.am (DISTCLEANFILES): Delete .s files.
+
+2003-05-27  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/symbols-test: And allow symbols that start at the
+       beginning of the line, as output by AIX nm.
+
+2003-05-26  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/symbols-test: Allow symbols to start with a dot.
+
+2003-05-14  Niels Möller  <niels@s3.kth.se>
+
+       * pgp.h (enum pgp_subpacket_tag): Copied values from RFC 2440.
+       Renamed PGP_SUBPACKET_ISSUER to PGP_SUBPACKET_ISSUER_KEY_ID.
+
+2003-05-13  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * pgp.h: Do proper namemangling for pgp_put_public_rsa_key and
+       pgp_put_rsa_sha1_signature.
+
+       * pgp-encode.c (pgp_put_mpi): Fixed nettle_mpz_get_str_256 call.
+
+2003-05-12  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * rsa2openpgp.c (rsa_keypair_to_openpgp): Some bugfixes.
+
+       * pgp.h (enum pgp_subpacket_tag): New enum. Definition is bogus
+       and needs to be fixed.
+       Added forward declarations of structs, and prototypes for
+       pgp_put_public_rsa_key and pgp_put_rsa_sha1_signature.
+
+       * pgp-encode.c (pgp_put_mpi): Take a const mpz_t argument. Gugfix,
+       use nettle_mpz_get_str_256.
+       (pgp_put_public_rsa_key, pgp_put_rsa_sha1_signature):
+       Constification. Some bugfixes.
+
+       * Use "config.h", not <config.h>.
+
+       * Reordered includes in most or all .c-files. All should now
+       include config.h.
+
+2003-05-12  Niels Möller  <niels@s3.kth.se>
+
+       * configure.ac: Use LSH_FUNC_ALLOCA.
+
+2003-04-25  Niels Möller  <niels@s3.kth.se>
+
+       * Makefile.am (libnettle_a_SOURCES): Added hmac-sha256.c.
+
+       * testsuite/hmac-test.c (test_main): Added tests for hmac-sha256,
+       from draft-ietf-ipsec-ciph-sha-256-01.txt.
+
+       * hmac-sha256.c (hmac_sha256_digest): New file.
+
+2003-04-22  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sha-example.c (display_hex): Simplified by using printf better.
+
+       * nettle.texinfo (Example): Use @verbatiminclude to include the
+       example program.
+
+       * sha-example.c: Example program, for inclusion in the manual.
+       Fixed bugs reported by Mark Arking.
+
+2003-04-14  Niels Möller  <niels@s3.kth.se>
+
+       * x86/aes-encrypt.asm (nettle_aes_encrypt): Fixed references to
+       _nettle_aes_encrypt_table.
+       * x86/aes-decrypt.asm (nettle_aes_decrypt): Fixed references to
+       _nettle_aes_decrypt_table.
+
+2003-04-12  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/Makefile.am (TS_SH): New test case symbols-test.
+       (EXTRA_PROGRAMS): Added testutils, as a kludge to
+       get automake to track dependencies for testutils.o.
+
+       * x86/aes-encrypt.asm (nettle_aes_encrypt): Renamed function to
+       use the nettle_ prefix.
+       * x86/aes-decrypt.asm (nettle_aes_decrypt): Likewise.
+       * sparc/aes.asm (_nettle_aes_crypt): Likewise.
+
+       * examples/Makefile.am (EXTRA_PROGRAMS): Add "io", as a kludge to
+       get automake to track dependencies for io.o.
+       (LDADD): Added ../libnettle.a, for the dependency.
+
+       * des-compat.c: Use names with the nettle_ prefix when using
+       Nettle's des functions.
+
+       * base16-meta.c (base16_encode_update): Need to undef before
+       redefining.
+
+       * New name mangling, to reduce the risk of link collisions. All
+       functions (except memxor) now use a nettle_ or _nettle prefix when
+       seen by the linker. For most functions, the header file that
+       declares a function also use #define to provide a shorter more
+       readable name without the prefix.
+
+2003-03-11  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * Released nettle-1.7.
+
+       * configure.ac: Bumped version to 1.7.
+
+       * nettle.texinfo (DSA): New section.
+       (RSA): Updated documentation.
+
+2003-03-02  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * examples/nettle-benchmark.c (time_cipher): Don't use GNU C
+       non-constant initializers.
+
+2003-02-23  Niels Moller  <nisse@carduelis>
+
+       * configure.ac: Use LSH_GCC_ATTRIBUTES.
+
+2003-02-19  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * acinclude.m4: Deleted file from cvs, use a link to lsh's
+       acinclude.m4 instead.
+
+2003-02-16  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * Makefile.am (libnettleinclude_HEADERS): Added macros.h.
+
+       * tools/Makefile.am (EXTRA_DIST): Added getopt.h.
+
+2003-02-14  Niels Möller  <niels@s3.kth.se>
+
+       * Makefile.am (print_path): Added target to print the used PATH,
+       for debugging.
+       (print-path): Moved dependency to all-local.
+
+2003-02-11  Niels Möller  <niels@s3.kth.se>
+
+       * buffer.c (nettle_buffer_copy): Bug fix, it didn't return any
+       value.
+
+2003-02-11  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/sexp-format-test.c (test_main): Added test for %( and
+       %).
+
+       * sexp-format.c (sexp_vformat): Handle %( and %).
+
+       * realloc.c (nettle_xrealloc): Fixed out-of-memory check.
+
+       * configure.ac (SHLIBMAJOR): Bumped version number to 1.
+
+       * buffer.c (nettle_buffer_init_realloc): New function.
+       * buffer-init.c (nettle_buffer_init): Use nettle_buffer_init_realloc.
+
+2003-02-10  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/sexp-format-test.c (test_main): New test with tokens
+       in the format string.
+       (test_main): Test space-searated literals too.
+
+       * rsa2sexp.c (rsa_keypair_to_sexp): New argument ALGORITHM_NAME.
+       * examples/rsa-keygen.c (main): Updated call to rsa_keypair_to_sexp.
+       * testsuite/rsa2sexp-test.c (test_main): Likewise.
+
+       * sexp-format.c (sexp_vformat): Allow whitespace in format string.
+
+       * rsa2sexp.c (rsa_keypair_to_sexp): Use literals with sexp_format.
+
+       * sexp-format.c (format_string): New function.
+       (sexp_vformat): Implemented support for literals in the format
+       string.
+
+2003-02-06  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/sexp-conv-test (print_raw, print_nl): New functions.
+       The testfunctions use these instead of using echo directly.
+       Use the test input '3:"\x' instead of '2:"\', to be friendlier to
+       sysv echo.
+
+2003-02-05  Niels Möller  <nisse@lysator.liu.se>
+
+       * des-compat.h (des_set_key): Different name mangling, if this
+       file is included, des_set_key should refer to a function that
+       behaves like openssl's.
+
+       * des-compat.c (des_key_sched, des_is_weak_key): Use the name
+       nettle_des_set_key for referring to Nettle's function.
+
+       * des.h (des_set_key): Name mangling, linker symbols should use a
+       "nettle_" prefix, and this one collided with openssl. Perhaps all
+       symbols should be mangled in a similar way, but that's for later.
+
+       * configure.ac (LDFLAGS): --with-lib-path should add to LDFLAGS,
+       not replace it.
+
+2003-01-30  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * tools/output.c (sexp_put_string): Fixed handling of escapable
+       characters. The code generated random escape sequences for
+       characters in the 0x10-0x1f range.
+
+       * testsuite/sexp-conv-test: More tests for hex and base64 input
+       and output.
+
+2003-01-30  Niels Möller  <niels@s3.kth.se>
+
+       * sexp2bignum.c (nettle_mpz_set_sexp): Call sexp_iterator_next on
+       success. That means the iterator argument can't be const.
+
+2003-01-29  Niels Möller  <niels@s3.kth.se>
+
+       * tools/Makefile.am (LDADD): Add libnettle.a, for the dependency.
+
+2003-01-27  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sexp2dsa.c (dsa_signature_from_sexp): New function.
+
+       RSA renaming. Updated all callers.
+       * rsa-sign.c (rsa_private_key_init, rsa_private_key_clear)
+       (rsa_private_key_prepare): Renamed functions.
+       * rsa.c (rsa_public_key_init, rsa_public_key_clear)
+       (rsa_public_key_prepare): Renamed functions.
+
+2003-01-23  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * Makefile.am (libnettle_a_SOURCES): Added new rsa and pkcs1
+       files. Removed old rsa_md5.c and rsa_sha1.c.
+
+       * testsuite/Makefile.am (TS_PROGS): Added pkcs1-test.
+
+       * dsa-verify.c (dsa_verify_digest): New function.
+       (dsa_verify): Most of the code moved to dsa_verify_digest, which
+       is used here.
+       * dsa-sign.c (dsa_sign_digest): New function.
+       (dsa_sign): Most of the code moved to dsa_sign_digest, which is
+       used here.
+       * dsa.c (_dsa_hash): Deleted function.
+
+       * rsa_md5.c, rsa_sha1.c: Deleted files, contents spread over
+       several files for signing and verification.
+       * rsa-sign.c, rsa-sha1-verify.c, rsa-sha1-sign.c,
+       rsa-md5-verify.c, rsa-md5-sign.c:  New files.
+
+       * rsa-sha1-verify.c (rsa_sha1_verify_digest): New function.
+       * rsa-sha1-sign.c (rsa_sha1_sign_digest):  New function.
+       * rsa-md5-verify.c (rsa_md5_verify_digest):  New function.
+       * rsa-md5-sign.c (rsa_md5_sign_digest):  New function.
+       * rsa-verify.c (_rsa_verify): New file, new function.
+
+       * rsa.c (_rsa_check_size): Renamed from rsa_check_size, and made
+       non-static. Private key functions moved to rsa-sign.c.
+
+       * pkcs1.c, pkcs1.h, pkcs1-rsa-md5.c, pkcs1-rsa-sha1.c: New files.
+       (pkcs1_signature_prefix): New function.
+
+       * testsuite/pkcs1-test.c: New test.
+
+2003-01-22  Niels Möller  <niels@s3.kth.se>
+
+       * examples/Makefile.am (nettle_benchmark_LDADD): Use
+       OPENSSL_LIBFLAGS.
+
+       * configure.ac (OPENSSL_LIBFLAGS): If libcrypto is found, add
+       -lcrypto to OPENSSL_LIBFLAGS, not the plain LDFLAGS.
+
+2003-01-20  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/Makefile.am (CLEANFILES): Delete test.in, test1.out
+       and test2.out.
+
+2003-01-17  Niels Möller  <niels@s3.kth.se>
+
+       * examples/Makefile.am (AM_CPPFLAGS): Use AM_CPPFLAGS instead of
+       AM_CFLAGS.
+       * testsuite/Makefile.am (AM_CPPFLAGS): Likewise.
+
+2003-01-16  Niels Möller  <niels@s3.kth.se>
+
+       * testsuite/Makefile.am (check): Can't use quotes around
+       $(srcdir).
+
+2003-01-14  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/Makefile.am (check): Don't use "run-tests" as a
+       target, as it's confused with the file with the same name.
+
+       * .bootstrap: Added missing #! /bin/sh.
+
+2003-01-12  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * buffer.c (nettle_buffer_reset): New function.
+       (nettle_buffer_copy): New function.
+
+       * tools/input.c, tools/input.h, tools/output.c, tools/output.h,
+       tools/parse.c, tools/parse.h, tools/misc.c, tools/misc.h: Moved
+       parts ov sexp-conv.c to separate files
+
+       * tools/sexp-conv.c (sexp_convert_list): Inlined into
+       sexp_convert_item.
+
+       * tools/sexp-conv.c (struct sexp_input): Deleted string attribute.
+       Changed all related functions to take a struct nettle_buffer *
+       argument instead.
+       (struct sexp_compound_token): New struct.
+       (sexp_compound_token_init, sexp_compound_token_clear): New
+       functions.
+       (struct sexp_parser): Added a struct sexp_compound_token
+       attribute, as a temporary measure.
+       (sexp_parse): Take a struct sexp_compound_token * as argument.
+       Updated all callers. Simplified handling of display types and
+       transport encoding.
+
+       * tools/sexp-conv.c (struct sexp_parser): Renamed struct (was
+       struct sexp_parse_state). Added input pointer. Updated users to
+       not pass around both parser and input.
+       (sexp_check_token): handle token == 0.
+       (sexp_parse): Simplified a little by calling sexp_check_token
+       unconditionally.
+
+       * tools/sexp-conv.c (sexp_convert_string): Deleted function.
+       (sexp_skip_token): Likewise.
+
+       * tools/sexp-conv.c (enum sexp_token): New constant SEXP_DISPLAY.
+       Start constants from 1, to keep 0 free for special uses.
+       (struct sexp_parse_state): New struct for keeping track of parser
+       state.
+       (sexp_parse_init): New function.
+       (sexp_check_token): New function, replacing sexp_skip_token.
+       (sexp_parse): New function.
+       (sexp_convert_item): Simplified by using sexp_parse.
+       (sexp_convert_list): Use sexp_parse.
+       (main): Likewise.
+
+2003-01-08  Niels Möller  <niels@s3.kth.se>
+
+       * tools/sexp-conv.c (parse_options): Initialize prefer_hex.
+
+2003-01-07  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * Makefile.am (des_headers): Refer to the desdata binary using
+       $(EXEEXT).
+
+2003-01-01  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/sexp-conv-test: New tests for hex and base64 literal
+       output.
+
+       * tools/sexp-conv.c (sexp_put_string): Print binary strings using
+       either hex or base 64 (in advanced mode).
+       (parse_options): Implemented -s hex, for output using hex rather
+       than base64.
+
+2002-12-30  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/rsa2sexp-test.c: Don't include rsa.h (done by
+       testutils.h, if enabled).
+       * testsuite/sexp2rsa-test.c: Likewise.
+
+       * rsa-decrypt.c: Make compilation conditional on WITH_PUBLIC_KEY.
+       * rsa-encrypt.c: Likewise.
+       * rsa-compat.c: Likewise.
+
+2002-12-04  Niels Möller  <niels@s3.kth.se>
+
+       * testsuite/Makefile.am (LDADD): Added path to ../libnettle.a,
+       which is redundant except for the dependency.
+
+2002-12-04  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/sexp-format-test.c (test_main): Use %0s instead of %z.
+       New test for %t.
+
+       * sexp-format.c (format_length_string): Deleted function.
+       (format_string): Deleted function.
+       (sexp_vformat): New %t specifier, formatting an optional display
+       type. Deleted %z specifier. Instead, introduced a new modifier "0"
+       that can be used with %s, %l and %t, which says that the data is
+       NUL-terminated.
+
+       * rsa2sexp.c (rsa_keypair_to_sexp): Use %0s rather than %z, when
+       formatting s-expressions.
+
+       * buffer.c (nettle_buffer_grow): Fixed assertion.
+
+2002-11-22  Niels Möller  <niels@s3.kth.se>
+
+       * buffer.c: Include assert.h.
+
+2002-11-21  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/testutils.c (print_hex): Add line breaks.
+
+       * Makefile.am (libnettleinclude_HEADERS): Added realloc.h.
+       (libnettle_a_SOURCES): Added buffer-init.c and realloc.c.
+
+       * sexp.c (sexp_iterator_exit_lists): New function, #if:ed out for
+       now.
+
+       * desdata.c: Include config.h, to get definition of UNUSED.
+       * shadata.c: Likewise.
+
+       * buffer.c (nettle_buffer_grow): New function, replacing
+       grow_realloc.
+       (nettle_buffer_clear): Rewritten to use buffer->realloc.
+
+       * buffer.h (struct nettle_buffer): Replaced the GROW function
+       pointer with a nettle_realloc_func pointer and a
+       void *realloc_ctx.
+       (NETTLE_BUFFER_GROW): Deleted macro, use function instead.
+
+       * buffer-init.c (nettle_buffer_init): Moved to a separate file.
+
+       * realloc.c (nettle_realloc): New function.
+       (nettle_xrealloc): New function.
+
+       * realloc.h (nettle_realloc_func): New typedef.
+
+       * configure.ac: Check for gcc:s __attribute__.
+
+2002-11-16  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sexp2dsa.c, sexp2rsa.c: (macro GET): Check sign of parsed
+       numbers.
+
+       * sexp2bignum.c (nettle_mpz_set_sexp): In the first check against
+       limit, added some margin to allow for sign octets.
+
+2002-11-15  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/testutils.h (LDATA): Use sizeof instead of strlen. Now
+       handles strings including NUL-characters. But works only with
+       literals and character arrays, no char pointers.
+       (LLENGTH): New macro, computing length the same way as LDATA.
+
+       * testsuite/sexp-test.c (test_main): Test sexp_iterator_get_uint32.
+
+       * testsuite/sexp-format-test.c (test_main): Check that %i and %b
+       generate leading zeroes when needed. Check that %b handles
+       negative numbers.
+
+       * testsuite/rsa2sexp-test.c (test_main): Updated test, one leading
+       zero is needed in the private key expression. In verbose mode,
+       print the generated keys.
+
+       * testsuite/sexp2rsa-test.c (test_main): Added a leading zero in
+       the private key expression.
+
+       * testsuite/bignum-test.c (test_bignum): Use
+       nettle_mpz_init_set_str_256_s.
+       (test_size): New function.
+       (test_main): Test size computation and formatting of negative
+       numbers.
+
+       * sexp2bignum.c (nettle_mpz_set_sexp): Use
+       nettle_mpz_set_str_256_s, to handle negative numbers correctly.
+
+       * sexp-format.c (sexp_vformat): For %i, output a leading zero when
+       needed to get a correct, positive, sign. For %b, use
+       nettle_mpz_sizeinbase_256_s, to handle negative numbers properly.
+
+       * bignum.c (nettle_mpz_sizeinbase_256_s): New function.
+       (nettle_mpz_sizeinbase_256_u): New name, was
+       nettle_mpz_sizeinbase_256. Updated all callers.
+       (nettle_mpz_to_octets): New function.
+       (nettle_mpz_get_str_256): Handle negative numbers.
+       (nettle_mpz_from_octets): New function.
+       (nettle_mpz_set_str_256_u): New name, was nettle_mpz_set_str_256.
+       (nettle_mpz_init_set_str_256_u): New name, was
+       nettle_mpz_init_set_str_256.
+       (nettle_mpz_set_str_256_s): New function, handling negative two's
+       complement numbers.
+       (nettle_mpz_init_set_str_256_s): And an init variant.
+
+       * sexp.c (sexp_iterator_get_uint32): New function.
+
+2002-11-10  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/sexp-conv-test: Use input files without any trailing
+       newline character, in order to stress the end of file handling.
+
+       * tools/sexp-conv.c (sexp_get_token_string): Fixed end of file
+       handling.
+       (sexp_get_string): Fixed end of encoding/end of file handling.
+       (parse_options): Check for negative width and complain.
+
+       * tools/sexp-conv.c: Use supplied getopt.
+       (werror): New function.
+       (sexp_output_hash_init): New function.
+       (sexp_put_char): Made base64 linebreaking configurable.
+       Implemented hashing.
+       (sexp_put_code_start, sexp_put_code_end): Don't output any
+       delimiters here.
+       (sexp_put_string): Output base64 delimiters.
+       (sexp_put_digest): New function.
+       (sexp_convert_item): Output transport delimiters.
+       (sexp_convert_file): Deleted function, folded with main.
+       (parse_options): New function.
+       (main): Implemented --hash and --once, needed by lsh-authorize.
+
+       * sexp.h (struct sexp_iterator): New field start.
+
+       * sexp.c (sexp_iterator_subexpr): New function.
+       (sexp_iterator_parse): Initialize ITERATOR->start.
+
+       * sexp-format.c (sexp_vformat): Abort if format string contains
+       unhandled characters.
+
+2002-11-08  Niels Möller  <niels@s3.kth.se>
+
+       * des-compat.c (des_ecb3_encrypt): Don't use struct initialization
+       (c89 doesn't allow non-constant initializers). Reported by James
+       Ralston.
+       (des_ede3_cbc_encrypt): Likewise.
+
+       * examples/nettle-openssl.c: Moved from the top-level directory.
+       Should *not* be included in the nettle library.
+
+2002-11-08  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/testutils.c (test_dsa_key): Bugfix for renamed DSA
+       constant (noted by James Ralston).
+
+2002-11-07  Niels Möller  <niels@s3.kth.se>
+
+       * testsuite/run-tests: Copied new version rom lsh/src/testsuite.
+       This version handles test scripts located in $srcdir.
+
+       * examples/Makefile.am (AM_CFLAGS): We need -I$(top_srcdir).
+       * tools/Makefile.am (AM_CFLAGS): Likewise.
+       * testsuite/Makefile.am (AM_CFLAGS): Likewise.
+
+2002-11-07  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * Makefile.am (SUBDIRS): Added tools.
+       (libnettle_a_SOURCES): Added sexp-transport-format.c,
+       sexp2bignum.c, sexp2dsa.c.
+
+       * sexp2dsa.c (dsa_keypair_from_sexp_alist, dsa_keypair_from_sexp):
+       New file, new functions.
+
+       * rsa2sexp.c (rsa_keypair_to_sexp): %s -> %z renaming.
+
+       * sexp-transport.c (sexp_transport_iterator_first): Fixed bug,
+       length was mishandled.
+
+       * sexp-transport-format.c (sexp_transport_format,
+       sexp_transport_vformat): New file, new functions.
+
+       * sexp-format.c (sexp_format): Return length of output. Allow
+       buffer == NULL, and only compute the needed length in this case.
+       Renamed %s to %z. New format specifiers %s, %i, and %l.
+       (sexp_vformat): New function.
+       (format_prefix): Rewrote to not use snprintf.
+
+       * sexp2rsa.c (rsa_keypair_from_sexp): New limit argument. Use
+       nettle_mpz_set_sexp.
+
+       * dsa-keygen.c (dsa_generate_keypair): Added some newlines to
+       progress display. Use DSA_P_MIN_BITS.
+
+       * dsa.h (DSA_MIN_P_BITS): New constant (was DSA_MINIMUM_BITS).
+       (DSA_Q_OCTETS, DSA_Q_BITS): New constants.
+       (dsa_keypair_from_sexp_alist, dsa_keypair_from_sexp): New
+       prototypes.
+
+       * configure.ac: Output tools/Makefile.
+
+       * sexp2bignum.c (nettle_mpz_set_sexp): New file, and new function.
+       Moved from sexp2rsa.c:get_value.
+
+       * examples/io.c (read_rsa_key): New limit argument in
+       call of rsa_keypair_from_sexp_alist.
+
+       * examples/Makefile.am (noinst_PROGRAMS): Removed sexp-conv.
+
+       * tools/sexp-conv.c: Moved file from examples directory.
+
+       * testsuite/Makefile.am (TS_SH): New variable. Added
+       sexp-conv-test.
+
+       * testsuite/testutils.h (LDUP): New macro.
+
+       * testsuite/sexp2rsa-test.c (test_main): New limit argument in
+       call of rsa_keypair_from_sexp_alist.
+
+       * testsuite/sexp-test.c (test_main): Added test for lengths with
+       more than one digit. Added tests for transport mode decoding.
+
+       * testsuite/sexp-format-test.c (test_main): Added tests for %i and
+       %l.
+
+       * testsuite/sexp-conv-test: Moved test from examples directory.
+       Updated path to sexp-conv, now in ../tools/sexp-conv.
+
+2002-11-03  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sexp-format.c, sexp_format.c: Renamed sexp_format.c to
+       sexp-format.c.
+       * Makefile.am (libnettle_a_SOURCES): Renamed sexp_format.c to
+       sexp-format.c.
+
+       * examples/Makefile.am: Don't set CFLAGS or CPPFLAGS explicitly,
+       let automake handle that.
+       * testsuite/Makefile.am: Likewise.
+
+       * sexp2rsa.c (rsa_keypair_from_sexp_alist): New function.
+       (rsa_keypair_from_sexp): Use it.
+
+2002-11-01  Niels Möller  <niels@s3.kth.se>
+
+       * examples/Makefile.am (LDADD): Use -lnettle, instead of an
+       explicit filename libnettle.a, so that we will use the shared
+       library, if it exists.
+       (AM_LDFLAGS): Added -L.., so we can find -lnettle.
+       (run-tests): Set LD_LIBRARY_PATH to ../.lib, when running the
+       testsuite.
+       * testsuite/Makefile.am: Similar changes.
+
+       * Makefile.am (LIBOBJS): Put @LIBOBJS@ into the make variable
+       LIBOBJS.
+       (CLEANFILES): Delete libnettle.so.
+       (clean-local): Delete the .lib linkfarm.
+       ($(SHLIBFORLINK)): When building libnettle.so, create a link from
+       .lib/$SHLIBSONAME. Needed at runtime, for the testsuite.
+
+2002-11-01  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Fixed definitions using SHLIBMAJOR and SHLIBMINOR.
+       Also AC_SUBST SHLIBMAJOR and SHLIBMINOR. Reported by James
+       Ralston.
+
+2002-10-31  Niels Möller  <niels@s3.kth.se>
+
+       * examples/sexp-conv.c(sexp_put_list_start): Deleted function.
+       (sexp_put_list_end): Likewise.
+       (sexp_put_display_start): Likewise.
+       (sexp_put_display_end): Likewise.
+       (sexp_puts): Likewise.
+
+       * examples/sexp-conv.c (sexp_get_quoted_string): Deleted function.
+       Merged with sexp_get_String.
+       (sexp_get_hex_string): Likewise.
+       (sexp_get_base64_string): Likewise.
+       (sexp_get_string): Do hex and base64 decoding.
+
+       * examples/sexp-conv.c (enum sexp_char_type): New enum, for end
+       markers in the input strem.
+       (struct sexp_input): Deleted LEVEL attribute. Deleted all usage of
+       it.
+       (sexp_get_raw_char): Use INPUT->c and INPUT->ctype to store
+       results. Deleted OUT argument.
+       (sexp_get_char): Likewise. Also removed the
+       INPUT->coding->decode_final call, for symmetry.
+       (sexp_input_end_coding): Call INPUT->coding->decode_final.
+       (sexp_next_char): New function.
+       (sexp_push_char): New function.
+       (sexp_get_token_char): Deleted function.
+       (sexp_get_quoted_char): Simplified. Deleted output argument.
+       (sexp_get_quoted_string): Simplified.
+       (sexp_get_base64_string): Likewise.
+       (sexp_get_token_string): Likewise.
+       (sexp_get_string_length): Skip the character that terminates the
+       string.
+       (sexp_get_token): Cleared upp calling conventions. Always consume
+       the final character of the token.
+       (sexp_convert_list): Take responsibility for converting the start
+       and end of the list.
+       (sexp_convert_file): Call sexp_get_char first, to get the token
+       reading started.
+       (sexp_convert_item): Cleared up calling conventions. Should be
+       called with INPUT->token being the first token of the expression,
+       and returns with INPUT->token being the final token of the
+       expression. Return value changed to void..
+
+       * examples/sexp-conv-test: Added test for transport mode input.
+
+       * examples/sexp-conv.c (sexp_get_char): Use the nettle_armor
+       interface for decoding.
+       (sexp_input_start_coding): New function.
+       (sexp_input_end_coding): New function.
+       (sexp_get_base64_string): Rewrote to use sexp_input_start_coding
+       and sexp_input_end_coding.
+       (sexp_get_token): Generate SEXP_TRANSPORT_START tokens.
+       (sexp_convert_list): Lists are ended only by SEXP_LIST_END.
+       (sexp_convert_item): Implemented transport mode, using
+       sexp_input_start_coding and sexp_input_end_coding.
+
+2002-10-30  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * Makefile.am: Added base16 files.
+
+       * examples/sexp-conv-test: New tests for transport output.
+
+       * examples/sexp-conv.c: Deleted hex functions, moved to Nettle's
+       base16 files.
+       (struct sexp_output): Represent the current encoding as a
+       nettle_armor pointer and a state struct.
+       (sexp_output_init): Deleted MODE argument. Now passed to functions
+       that need it.
+       (sexp_get_char): Updated to new base64 conventions.
+       (sexp_get_base64_string): Likewise.
+       (sexp_put_raw_char): New function.
+       (sexp_put_newline): Use sexp_put_raw_char.
+       (sexp_put_char): Use nettle_armor interface for encoding data.
+       Use OUTPUT->coding_indent for line breaking, so the INDENT
+       argument was deleted.
+       (sexp_put_code_start): New function, replacing sexp_put_base64_start.
+       (sexp_put_code_end): New function, replacing sexp_put_base64_end.
+       (sexp_put_data): Deleted argument INDENT.
+       (sexp_puts): Likewise.
+       (sexp_put_length): Likewise.
+       (sexp_put_list_start): Likewise.
+       (sexp_put_list_end): Likewise.
+       (sexp_put_display_start): Likewise.
+       (sexp_put_display_end): Likewise.
+       (sexp_put_string): Likewise. Also changed base64 handling.
+       (sexp_convert_string): Deleted argument INDENT. New argument
+       MODE_OUT.
+       (sexp_convert_list): New argument MODE_OUT.
+       (sexp_convert_file): Likewise.
+       (sexp_convert_item): Likewise. Also handle output in transport
+       mode.
+       (match_argument): Simple string comparison.
+       (main): Adapted to above changes.
+
+       * testsuite/testutils.c (test_armor): Allocate a larger buffer
+       CHECK, to make decode_update happy. Updated to new base64
+       conventions.
+
+       * testsuite/base64-test.c (test_main): Fixed overlap test to not
+       change the base64 before decoding. Updated to new base64
+       conventions.
+
+       * testsuite/Makefile.am (TS_PROGS): Added base16-test.
+
+       * testsuite/base16-test.c: New test.
+
+       * sexp-transport.c (sexp_transport_iterator_first): Updated to new
+       conventions for base64_decode_update and base64_decode_final.
+
+       * nettle-meta.h: Updated ascii armor declarations. New declaration
+       for nettle_base16.
+
+       * base64-decode.c (base64_decode_single): Return -1 on error.
+       Also keep track of the number of padding characters ('=') seen.
+       (base64_decode_update): New argument dst_length. Return -1 on error.
+       (base64_decode_status):  Renamed function...
+       (base64_decode_final): ... to this.
+
+       * base64.h (struct base64_decode_ctx): Deleted STATUS attribute.
+       Added PADDING attribute.
+
+       * base16.h, base16-encode.c, base16-decode.c, base16-meta.c: New
+       files.
+
+2002-10-28  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * examples/sexp-conv.c (struct hex_decode_ctx): New hex decoding
+       functions.
+       (sexp_get_raw_char): New function.
+       (sexp_get_char): Use sexp_get_raw_char.
+
+2002-10-26  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * examples/sexp-conv.c (sexp_put_length): Bugfix, don't output any
+       leading zero.
+       (main): Implemented -s option.
+
+       * examples/sexp-conv-test: Test for echo -n vs echo '\c'. Added a
+       few tests for canonical output.
+
+2002-10-25  Niels Möller  <niels@s3.kth.se>
+
+       * examples/sexp-conv.c (struct sexp_input): Deleted the mode from
+       the state, that should be passed as argument to relevant
+       functions. Instead, introduces enum sexp_coding, to say if base64
+       coding is in effect.
+       (struct sexp_output): Added coding attribute.
+       (sexp_put_char): Use output->coding.
+       (sexp_put_base64_start): Likewise.
+       (sexp_put_base64_end): Likewise.
+
+       * base64-decode.c (base64_decode_single): Simplified, got rid of
+       the done variable.
+
+2002-10-25  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * examples/sexp-conv.c (sexp_put_newline): Return void, die on
+       error.
+       (sexp_put_char, sexp_put_data, sexp_puts, sexp_put_length,
+       sexp_put_base64_start, sexp_put_base64_end, sexp_put_string,
+       sexp_put_list_start, sexp_put_list_end, sexp_put_display_start,
+       sexp_put_display_end, sexp_convert_string, sexp_convert_list,
+       sexp_skip_token): Likewise.
+       (sexp_convert_item): Die on error.
+
+2002-10-24  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * examples/sexp-conv-test: Doesn't need echo -n anymore.
+
+       * examples/sexp-conv.c (die): New function.
+       (struct sexp_input): Deleted field ITEM.
+       (sexp_get_char): Die on failure, never return -1.
+       (sexp_get_quoted_char): Likewise.
+       (sexp_get_quoted_string): Die on failure, no returned value.
+       (sexp_get_base64_string): Likewise.
+       (sexp_get_token_string): Likewise.
+       (sexp_get_string): Likewise.
+       (sexp_get_string_length): Likewise.
+       (sexp_get_token): Likewise.
+       (sexp_convert_string): Adapted to sexp_get_token.
+       (sexp_convert_list): Likewise.
+       (sexp_convert_file): New function.
+       (main): Use sexp_convert_file.
+
+2002-10-23  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * examples/Makefile.am (TS_PROGS): Added sexp-conv-test.
+
+       * examples/sexp-conv.c (sexp_input_init): Initialize input->string
+       properly.
+       (sexp_get_char): Fixed non-transport case.
+       (sexp_get_quoted_char): Fixed default case.
+       (sexp_get_token): Loop over sexp_get_char (needed for handling of
+       white space). Don't modify input->level. Fixed the code that skips
+       comments.
+       (sexp_put_char): Fixed off-by-one bug in assertion.
+       (sexp_put_string): Fixed escape handling for output of quoted
+       strings.
+       (sexp_convert_list): Prettier output, hanging indent after the
+       first list element.
+       (sexp_skip_token): New function.
+       (sexp_convert_item): Use sexp_skip_token to skip the end of a
+       "[display-type]".
+
+2002-10-22  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * examples/sexp-conv-test: New test program.
+
+       * examples/Makefile.am (noinst_PROGRAMS): Added sexp-conv.
+
+       * examples/sexp-conv.c (sexp_convert_list): New function.
+       (sexp_convert_item): New function.
+       (main): New function. Compiles and runs now, but doesn't work.
+
+       * base64-decode.c (base64_decode_single): New function.
+       (base64_decode_update): Use base64_decode_single.
+
+       * examples/sexp-conv.c: Added output functions.
+
+2002-10-21  Pontus Sköld  <pont@soua.net>
+
+       * base64-encode.c (base64_encode_raw): Fixed null statement
+       amongst variable declarations, broke compilation for non C99
+       compilers.
+
+2002-10-21  Niels Möller  <nisse@lysator.liu.se>
+
+       * examples/sexp-conv.c: New sexp conversion program.
+
+2002-10-21  Niels Möller  <niels@s3.kth.se>
+
+       * Makefile.am (libnettle_a_SOURCES): Added
+       sexp-format-transport.c.
+
+       * sexp-transport.c (sexp_transport_iterator_first): New file and
+       function.
+       * sexp.h (sexp_transport_iterator_first): Added protoype.
+
+       * sexp.c (sexp_iterator_next): Abort if iterator type is boogus.
+
+2002-10-19  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/testutils.c (test_armor): Updated to new armor
+       conventions.
+
+       * testsuite/base64-test.c (test_main): Test BASE64_ENCODE_LENGTH
+       and BASE64_DECODE_LENGTH. Updated test of base64_encode_raw (used
+       to be base64_encode).
+
+       * base64.h (BASE64_ENCODE_LENGTH, BASE64_DECODE_LENGTH): Fixed and
+       documented macros.
+
+       * base64-meta.c (base64_encode_length, base64_decode_length): New
+       functions, corresponding to the macros with the same name.
+
+       * Makefile.am (libnettle_a_SOURCES): base64.c replaced by
+       base64-encode.c and base64-decode.c.
+
+       * pgp-encode.c (pgp_armor): Use new base64 conventions.
+
+       * nettle-meta.h: Updated nettle_armor definitions.
+
+       * base64.h: Major reorganization.
+
+       * base64.c: Deleted file, contents moved to base64-encode.c or
+       base64-decode.c.
+
+       * base64-encode.c: New file. New supporting both encode-at-once
+       and streamed operation.
+
+       * base64-decode.c: New file.
+
+2002-10-09  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/Makefile.am (TS_PROGS): Added dsa-keygen-test.
+
+       * dsa-keygen.c: Call the progress callback only if it's non-NULL.
+
+       * Makefile.am (libnettle_a_SOURCES): Added bignum-random.c and
+       dsa-keygen.c.
+
+       * testsuite/testutils.c (test_dsa_key): New function to sanity
+       check a dsa keypair.
+
+       * testsuite/dsa-test.c (test_main): Call dsa_test_key.
+
+       * testsuite/dsa-keygen-test.c: New test case.
+
+       * dsa.h (DSA_MINIMUM_BITS): New constant.
+
+       * bignum.h (nettle_mpz_random, nettle_mpz_random_size): Added
+       prototypes.
+
+       * dsa-keygen.c: New file.
+
+       * bignum-random.c: New file.
+       (nettle_mpz_random): New function, moved from...
+       * dsa-sign.c (nettle_mpz_random): ... here. Also changed argument
+       ordering and updated callers.
+
+       * bignum-random.c: (nettle_mpz_random_size): New function, renamed
+       and moved here from...
+       * rsa-keygen.c (bignum_random_size): ... here. Updated all
+       callers.
+
+       * testsuite/testutils.c (test_dsa): Needs both public and private
+       key as arguments.
+
+       * testsuite/dsa-test.c (test_main): Updated to changes of the
+       private key struct.
+
+       * testsuite/Makefile.am (TS_PROGS): Added dsa-test.
+
+       * rsa-decrypt.c (rsa_decrypt): Constification.
+       * rsa-encrypt.c (rsa_encrypt): Likewise.
+       * rsa.c (rsa_compute_root): Likewise.
+       * rsa_md5.c (rsa_md5_sign): Likewise.
+       (rsa_md5_verify): Likewise.
+       * rsa_sha1.c (rsa_sha1_sign): Likewise.
+       (rsa_sha1_verify): Likewise.
+
+       * dsa-verify.c (dsa_verify): Use const for the public key
+       argument.
+
+       * dsa-sign.c (dsa_sign): Needs the public key as argument, in
+       addition to the private key. Use const.
+
+       * dsa.h (struct dsa_private_key): Don't include the public
+       information here.
+       * dsa.c (dsa_private_key_init, dsa_private_key_clear): Updated to
+       new struct dsa_private_key.
+
+       * dsa-sign.c (dsa_sign): Bugfix, added missing mpz_init call.
+
+       * Makefile.am (libnettle_a_SOURCES): Added dsa files.
+       (libnettleinclude_HEADERS): Added dsa.h.
+
+       * testsuite/testutils.c (test_dsa): New function.
+
+       * testsuite/dsa-test.c: New test.
+
+       * dsa.h, dsa.c, dsa-sign.c, dsa-verify.c: New files.
+
+       * nettle-meta.h: Moved the nettle_random_func and
+       nettle_progress_func typedefs here...
+       * rsa.h: ... from here.
+
+2002-10-07  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sexp.h (enum sexp_type): Deleted SEXP_START.
+
+       * sexp.c (sexp_iterator_parse): New function, similar to the old
+       sexp_iterator_next, but independent of the previous value of the
+       iterator->type.
+       (sexp_iterator_first): Use sexp_iterator_parse.
+       (sexp_iterator_next): Likewise.
+       (sexp_iterator_enter_list): Use sexp_iterator_parse. SEXP_START
+       not needed anymore.
+       (sexp_iterator_exit_list): Likewise.
+
+2002-10-06  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sexp2rsa.c (get_value): No need to call sexp_iterator_next
+       anymore.
+
+       * sexp.c (sexp_iterator_assoc): Advance the iterator to the
+       element after a matching tag, before recording it.
+       * testsuite/sexp-test.c (test_main): Updated test.
+
+       * testsuite/sexp-test.c (test_main): No need to call
+       sexp_iterator_next after sexp_iterator_exit_list.
+
+       * sexp2rsa.c (rsa_keypair_from_sexp): No need to call
+       sexp_iterator_next anymore.
+
+       * sexp.c (sexp_iterator_next): Updated to new sexp_iterator_exit_list.
+       (sexp_iterator_exit_list): Return with iterator pointing to the
+       element after the list.
+       (sexp_iterator_check_type): Call sexp_iterator_next before
+       returning.
+       (sexp_iterator_check_types): Likewise.
+       (sexp_iterator_assoc): Rearranged calls of sexp_iterator_next.
+
+       * sexp.c (sexp_iterator_enter_list): Call sexp_iterator_next to
+       get to the first element of the list. Updated callers.
+
+       * base64.c (base64_encode_group): New function, used by openpgp
+       armoring code.
+
+       * Makefile.am: Added openpgp files.
+
+       * sexp2rsa.c (rsa_keypair_from_sexp): Use sexp_iterator_first.
+       * testsuite/sexp-test.c (test_main): Likewise.
+
+       * sexp.c (sexp_iterator_init): Made this function static.
+       (sexp_iterator_first): New, friendlier, initialization function.
+
+       * pgp-encode.c: New file. Functions for writing openpgp data
+       packets.
+
+       * pgp.h: New file, with pgp related declarations.
+
+       * rsa2openpgp.c (rsa_keypair_to_openpgp): New file, new function.
+
+2002-10-04  Niels Möller  <niels@s3.kth.se>
+
+       * examples/rsa-keygen.c: Use malloc, instead of asprintf.
+
+2002-10-03  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * Released nettle-1.6.
+
+       * NEWS: Note the aes api change.
+
+       * examples/Makefile.am (EXTRA_DIST): Distribute setup-env and
+       teardown-env.
+
+2002-10-02  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * examples/rsa-keygen.c (main): Comment on the lax security of the
+       private key file.
+
+       * index.html: Added link to mailing list.
+
+2002-10-02  Niels Möller  <niels@s3.kth.se>
+
+       * Makefile.am: Fixed assembler rules, and shared libraries.
+
+       * configure.ac: Fixed the enable-shared option.
+
+2002-10-01  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * configure.ac: New option --enable-shared, and a first attempt at
+       building a shared library (*without* using libtool).
+
+       * Makefile.am: A first attempt at rules for building a shared
+       libnettle.so.
+
+2002-10-01  Niels Möller  <niels@s3.kth.se>
+
+       * examples/run-tests (test_program): Use basename.
+
+       * examples/teardown-env: Delete some more files.
+
+       * examples/run-tests (test_program): Strip directory part of
+       displayed name.
+
+       * examples/Makefile.am (TS_PROGS): New variable. Run tests.
+
+       * examples/io.c (read_file): Bug fix, used to overwrite pointer.
+
+       * examples/rsa-keygen.c (main): Bug fix, private key wasn't
+       written properly.
+
+       * testsuite/Makefile.am: Some cleanup of make check.
+
+       * examples/setup-env, examples/teardown-env: Test environment scripts.
+       * examples/rsa-verify-test, examples/rsa-sign-test: New test cases.
+
+       * examples/run-tests: New file (copied from lsh testsuite).
+
+       * examples/Makefile.am: Use EXTRA_PROGRAMS and @RSA_EXAMPLES@.
+
+       * examples/rsa-sign.c: No need to include config.h. Use werror
+       instead of fprintf.
+       * examples/rsa-verify.c: Likewise.
+       * examples/rsa-keygen.c: Likewise.
+
+       * examples/io.h: Forward declare struct rsa_public_key and struct
+       rsa_private_key, to avoid dependences on config.h.
+
+       * configure.ac (RSA_EXAMPLES): New substituted variable,
+       controlling which example programs to build.
+
+       * examples/rsa-verify.c: New example program.
+
+       * examples/rsa-keygen.c: Use functions from io.c.
+       * examples/rsa-sign.c: Likewise.
+
+       * examples/Makefile.am (noinst_PROGRAMS): Added rsa-verify.
+       (LDADD): Added io.o.
+
+       * configure.ac: New define WITH_PUBLIC_KEY, and new configure flag
+       --disable-public-key. Updated rsa-files to check for that, rather
+       than for HAVE_LIBGMP.
+
+       * examples/io.c, examples/io.c: New files. Miscellaneous functions
+       used by the example programs.
+
+       * base64.h (BASE64_DECODE_LENGTH): Comment fix.
+
+2002-09-30  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sexp2rsa.c (rsa_keypair_from_sexp): Bugfix: Call
+       rsa_prepare_public_key and rsa_prepare_private_key.
+
+       * examples/Makefile.am (noinst_PROGRAMS): Added rsa-sign.
+
+       * examples/rsa-sign.c: New example program.
+
+       * testsuite/base64-test.c (test_main): Test encoding and decoding
+       in place.
+
+       * base64.c (base64_encode): Encode from the end of the data
+       towards the start, in order to support overlapping areas.
+       (base64_encode): Broke out some common code from the switch..
+
+2002-09-30  Niels Möller  <niels@s3.kth.se>
+
+       * sexp_format.c (sexp_format): Don't mix code and declarations.
+
+2002-09-29  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/Makefile.am (TS_PROGS): Added buffer-test
+       sexp-format-test rsa2sexp-test sexp2rsa-test.
+
+
+       * testsuite/sexp-test.c (test_main): Updated calls to
+       sexp_iterator_assoc.
+
+       * testsuite/testutils.h (MEMEQH): New macro.
+
+       * testsuite/sexp2rsa-test.c: New test.
+       * testsuite/sexp-format-test.c: New test.
+       * testsuite/rsa2sexp-test.c: New test.
+       * testsuite/buffer-test.c: New test.
+
+       * testsuite/testutils.c (test_rsa_key): Copied this function
+       from...
+       testsuite/rsa-keygen-test.c: ... here.
+
+       * examples/rsa-keygen.c: New file.
+
+       * Makefile.am: Added new source files and headers buffer.h,
+       buffer.c, sexp_format.c, sexp2rsa.c, rsa2sexp.c.
+
+       * rsa.h (rsa_keypair_to_sexp, rsa_keypair_from_sexp): New
+       prototypes.
+
+       * rsa2sexp.c, sexp2rsa.c: New files.
+
+       * sexp.c (sexp_iterator_assoc): Don't enter the list, associate
+       keys within the current list. Still exit the list when done.
+       (sexp_iterator_assoc): Represent keys as plain NUL-terminated
+       strings.
+       (sexp_iterator_check_type, sexp_iterator_check_types): New
+       functions.
+
+       * sexp_format.c: New file, implementing an sexp canonical syntax
+       formatter.
+
+       * buffer.c, buffer.h: New files, implementing a bare-bones string
+       stream.
+
+       * bignum.c (nettle_mpz_sizeinbase_256): New function.
+
+2002-09-28  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sexp.c (sexp_iterator_assoc): Return 0 for missing or duplicate
+       keys. Now passes all the tests.
+
+       * sexp.c (sexp_iterator_simple): Bugfixes. Check earlier that
+       length doesn't grow too large.
+       (sexp_iterator_next): Skip the current list only if type is
+       SEXP_LIST. Handle ')'.
+       (sexp_iterator_enter_list): Set type to SEXP_START.
+       (sexp_iterator_exit_list): Likewise. Don't skip the ')' here.
+       (sexp_iterator_assoc): Bug fix.
+
+       * testsuite/sexp-test.c (test_main): Reordered sexp_iterator_assoc
+       tests.
+
+       * nettle.texinfo (Randomness): Documented that yarrow256_init can
+       be called with a zero number of sources.
+
+       * testsuite/testutils.h (ASSERT): New macro.
+
+       * testsuite/sexp-test.c: Test sexp parser.
+
+       * Makefile.am (SUBDIRS): Added sexp files.
+
+       * sexp.c, sexp.h: New files, implementing an sexp-parser.
+
+2002-08-27  Niels Möller  <niels@s3.kth.se>
+
+       * Makefile.am (DISTCLEANFILES): make distclean should delete the
+       assembler-related symlinks.
+
+2002-08-26  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * Makefile.am (%.o: %.asm): Create an empty (and unused)
+       dependency file, to make the make/automake dependency tracking
+       happier.
+
+2002-07-18  Niels Möller  <niels@s3.kth.se>
+
+       * examples/nettle-benchmark.c (main): Try openssl's ciphers as
+       well, if available.
+
+       * Makefile.am (libnettle_a_SOURCES): Added nettle-openssl.c.
+
+       * nettle-openssl.c: New file.
+
+       * nettle-internal.h: Declare openssl glue ciphers.
+
+       * des-compat.h: Extra name-mangling, to avoid collisions in case a
+       program links with both nettle and libcrypto (the nettle-benchmark
+       program does).
+
+       * configure.ac: Don't use -ggdb3 with gcc-2.96.
+       Check for openssl's libcrypto (for benchmarking).
+
+2002-05-16  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sparc/aes.asm: Deleted registers i and t3.
+       (_aes_crypt): Moved some registers around. We now use input
+       registers only for arguments, local registers for loop invariants,
+       output registers for temporaries and loop variables, and no global
+       registers at all.
+
+       * sparc/aes.asm (AES_FINAL_ROUND): New macro.
+       (_aes_crypt): Use AES_FINAL_ROUND for the first word of the final
+       round.
+       (_aes_crypt): And for the rest of the final round.
+       (AES_FINAL_ROUND): Don't update dst, just access it offseted by i.
+       (_aes_crypt): Add 16 to dst at the end of the final round.
+       (AES_ROUND): Use ldub, not ld + and, to get the third byte
+       of wtxt.
+       (AES_ROUND): Use ldub, not lduh + and, to get the second
+       byte of a word.
+       (AES_ROUND): Reordered instructions, so that we can save one
+       register.
+       (AES_ROUND): Eliminated use of t3.
+       (AES_FINAL_ROUND): Eliminated ands.
+       (AES_FINAL_ROUND): Reordered, so that we can save one register.
+       (AES_FINAL_ROUND): Eliminated t3.
+       (AES_LOAD): New macro.
+       (_aes_crypt): Unrolled source loop.
+       (_aes_crypt): Use AES_LOAD macro.
+       (_aes_crypt): Deleted cruft from the old source loop.
+       (AES_LOAD): Eliminated t3.
+
+2002-05-15  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sparc/aes.asm (AES_ROUND): New macro.
+       (_aes_crypt): Use AES_ROUND for first word of the
+       round function.
+       (_aes_crypt): And for the rest of the round function.
+
+       * sparc/aes.asm (_aes_crypt): Deleted a bunch of additions,
+       after accessing IDX1.
+
+       * aes-internal.h (struct aes_table): sparc_idx[0] should now
+       contain index values shifted by the size of a word, and with 2
+       added. This saves some additions in the sparc assembler code.
+       Updates aes-encrypt-table.c and aes-decrypt-table.c.
+
+       * sparc/aes.asm (_aes_crypt): Unrolled final loop, preparing for
+       optimizations.
+       (_aes_crypt): Eliminated i from forst copy of the loop. Some
+       cleanup.
+       (_aes_crypt): And from second copy.
+       (_aes_crypt): And from third.
+       (_aes_crypt): And fourth.
+       (_aes_crypt): Eliminated updates of i from the loop.
+       (_aes_crypt): Access IDX1 and IDX3 through the T pointer, saving
+       two registers.
+
+       * aes-internal.h (struct aes_table): Renamed the shift_idx field
+       to sparc_idx, as it will be tweaked to improve the sparc code.
+       Also reduced its size to [2][4].
+       (IDX_FACTOR): Deleted constant.
+       * aes-encrypt-table.c (_aes_encrypt_table): Adapted initializer of
+       sparc_idx.
+       * aes-decrypt-table.c (_aes_decrypt_table): Likewise.
+       * asm.m4: Deleted AES_SIDX2, to match struct aes_table.
+
+       * sparc/aes.asm (_aes_crypt): Unrolled the inner loop, preparing
+       for optimizations suggested by Marcus Comstedt.
+       (_aes_crypt): Eliminated i from the first copy of the inner loop.
+       (_aes_crypt): And from the second copy.
+       (_aes_crypt): And from the third copy.
+       (_aes_crypt): And from the fourth copy.
+       (_aes_crypt): Renamed .Linner_loop to .Lround_loop.
+       (_aes_crypt): Eliminated the loop variable i from the unrolled
+       loop.
+       (_aes_crypt): Deleted moves of constants into t2.
+
+2002-05-15  Niels Möller  <niels@s3.kth.se>
+
+       * x86/aes-encrypt.asm (aes_encrypt): Use AES_SUBST_BYTE.
+       * x86/aes-decrypt.asm (aes_decrypt): Likewise.
+       (aes_decrypt): Use AES_STORE.
+       (aes_decrypt): Deleted first xchgl instruction into, permuting the
+       AES_ROUND calls instead.
+       (aes_decrypt): Likewise for the final round.
+       (aes_decrypt): Got rid if the xchgl instruction after the final
+       round, folding it into the final round.
+
+       * x86/machine.m4: Renamed AES_LAST_ROUND to AES_FINAL_ROUND.
+       Updated users.
+
+       * x86/aes-decrypt.asm (aes_decrypt): Use the AES_LOAD macro.
+       (aes_decrypt): Start using AES_ROUND.
+       (aes_decrypt): Use AES_LAST_ROUND.
+
+       * x86/aes-decrypt.asm (aes_decrypt): Moved function to a separate
+       file...
+       * x86/aes.asm: ... from here.
+
+       * x86/aes.asm (aes_decrypt): Use _aes_decrypt_table instead of
+       itbl1-4. Commented out the inclusion of aes_tables.asm.
+       (aes_decrypt): Use _aes_decrypt_table instead of isbox.
+
+
+       * x86/aes-decrypt.asm: New file, empty at the start.
+
+       * Makefile.am (libnettle_a_SOURCES): Added aes-decrypt-table.c.
+
+       * aes-decrypt.c (_aes_decrypt_table): Moved from this file...
+       * aes-decrypt-table.c (_aes_decrypt_table): ... to a new file.
+
+       * testsuite/aes-test.out: New file, with the output of
+       testsuite/aes-test, when aes.c has been compiled with debugging
+       printouts of intermediate state.
+
+2002-05-15  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sparc/aes.asm: (_aes_crypt): Restore %fp at end of function, to
+       make %fp available for other uses.
+
+       * sparc/aes.asm: The frame setup was broken. Tried to fix it.
+       Reverted to revision 1.70 + minor changes from the head revision.
+
+       * x86/aes-encrypt.asm (aes_encrypt): Use test instead of cmpl $0,.
+
+       * x86/machine.m4 (AES_SUBST_BYTE): New macro.
+
+       * sparc/aes.asm: wtxt needs no register of it's own, as its
+       pointed to by %sp. %g5 moved to %l0, the register previously
+       allocated for wtxt, so that we stay clean of the reserved %g
+       registers.
+
+2002-05-14  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sparc/aes.asm: Avoid using %g6 and %g7, as they are reserved for
+       operating sytem use. Use %i5 and %o7 instead. Also moved %g4 to %g1.
+       (_aes_crypt): Allocate only 32 bytes local storage on the stack.
+       Calculate wtxt and tmp using offsets from %sp, not %fp.
+
+2002-05-14  Niels Möller  <niels@s3.kth.se>
+
+       * x86/aes-encrypt.asm (aes_encrypt): Replaced first quarter of the
+       round function with an invocation of AES_ROUND.
+       (aes_encrypt): Similarly for the second column.
+       (aes_encrypt): Similarly for the rest of the round function.
+
+       * x86/machine.m4 (AES_ROUND): New macro.
+
+       * x86/aes-encrypt.asm (aes_encrypt): Use AES_LOAD macro.
+
+       * x86/machine.m4 (AES_LOAD): New macro.
+
+       * x86/aes-encrypt.asm (aes_encrypt): Use AES_STORE.
+
+       * x86/machine.m4 (AES_STORE): New macro.
+
+       * x86/aes-encrypt.asm (aes_encrypt): Use the AES_LAST_ROUND macro
+       for the first column of the final round.
+       (aes_encrypt): Similarly for the second column.
+       (aes_encrypt): Similarly for the third and fourth column.
+
+       (aes_encrypt): Deleted xchgl instruction in final round, by
+       reordering the second and fourth round.
+
+       * x86/machine.m4 (AES_LAST_ROUND): New macro.
+
+       * x86/aes-encrypt.asm (aes_encrypt): Move code here...
+       * x86/aes.asm: ...from here.
+
+       * x86/aes.asm: Use addl and subl, not add and sub. Replaced
+       references to dtbl1-4 with references to _aes_encrypt_table.
+
+       * configure.ac (asm_path): Enable x86 assembler.
+
+       * x86/aes.asm (aes_decrypt): Adapted to the current interface.
+       Notably, the order of the subkeys was reversed. Single block
+       encrypt/decrypt works now.
+       (aes_encrypt, aes_decrypt): Added an outer loop, so that we can
+       encrypt more than one block at a time.
+
+2002-05-07  Niels Möller  <niels@s3.kth.se>
+
+       * configure.ac: Generate config.m4.
+
+       * x86/aes.asm: Use C for comments, include the tables using
+       include_src, and commented out the key setup functions.
+       Fixed the processing of the first handling of the round function.
+       Now, encryption of a single block works! Multiple blocks, and
+       decryption, is still broken.
+
+       * x86/machine.m4: New file (empty).
+
+       * x86/aes-encrypt.asm: New file, empty for now.
+
+       * Makefile.am (%.asm): Added asm.m4, machine.m4 and config.m4 to
+       the m4 command line.
+       (libnettle_a_SOURCES): Added aes-encrypt-table.c.
+
+       * sparc/aes.asm: No need to include asm.m4, that is taken care of
+       by the Makefile.
+
+       * config.m4.in: New file, configuration for asm.m4.
+
+       * asm.m4 (C, include_src): New macros.
+
+       * aes-encrypt-table.c: New file, table moved out from
+       aes-encrypt.c.
+
+2002-05-06  Niels Möller  <niels@s3.kth.se>
+
+       * configure.ac (CFLAGS): Don't enable -Waggregate-return.
+
+2002-05-05  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.ac: Pass no arguments to AM_INIT_AUTOMAKE.
+
+2002-05-05  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * configure.ac: Update for automake-1.6.
+
+       * configure.ac: Renamed file, used to be configure.in.
+
+2002-03-20  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/run-tests (test_program): Added missing single quote.
+
+2002-03-20  Niels Möller  <nisse@lysator.liu.se>
+
+       * testsuite/run-tests (test_program): Test the exit status of the
+       right process.
+
+2002-03-19  Pontus Sköld  <pont@it.uu.se>
+
+       * testsuite/run-tests: Removed /bin/bashisms to use with /bin/sh.
+
+2002-03-18  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * rsa-keygen.c (rsa_generate_keypair): Output a newline after a
+       non-empty line of 'e':s (bad e was chosen, try again).
+
+2002-03-16  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * configure.in (asm_path): AC_CONFIG_LINKS adds $srcdir
+       automatically.
+
+2002-03-14  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sparc/aes.asm, x86/aes.asm: Added copyright notice.
+
+       * Makefile.am (libnettle_a_SOURCES): Added aes-internal.h.
+       (EXTRA_DIST): Added assembler files.
+
+       * configure.in (asm_path): Use $srcdir when looking for the files.
+       * configure.in (asm_path): For now, disable x86 assembler code.
+       Bumped version to 1.6.
+
+2002-02-25  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sparc/aes.asm (_aes_crypt): Moved increment of src into the
+       source_loop. Also fixed stop condition, the loop was run 5 times,
+       not 4, as it should.
+       (_aes_crypt): Use src directly when accessing the source data,
+       don't use %o5.
+       (_aes_crypt): Renamed variables in source_loop.
+       (_aes_crypt): Changed stop condition in source_loop to not depend
+       on i. Finally reduced the source_loop to 16 instructions. Also
+       increased the alignment of the code to 16.
+       (_aes_crypt): In final_loop, use preshifted indices.
+       (_aes_crypt): In final_loop, construct the result in t0. Use t0-t3
+       for intermediate values.
+       (_aes_crypt): In final_loop, use the register idx.
+       (_aes_crypt): In final_loop, keep i multiplied by 4. Use key to
+       get to the current roundkey.
+       (_aes_crypt): In final_loop, use i for indexing.
+       (_aes_crypt): Update dst in the output loop. This yields a delay
+       slot that isn't filled yet.
+       (_aes_crypt): Decrement round when looping, saving yet some
+       instructions.
+       (_aes_crypt): Reformatted code as blocks of four instructions
+       each.
+       (_aes_crypt): Copy the addresses of the indexing tables into
+       registers at the start. No more need for the idx register.
+       (_aes_crypt): Deleted idx register.
+       (_aes_crypt): Some peep hole optimizations, duplicating some
+       instructions to fill nop:s, and put branch instructions on even
+       word addresses.
+
+2002-02-22  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sparc/aes.asm (_aes_crypt): Moved some more additions out of the
+       inner loop, using additional registers.
+       (_aes_crypt): Deleted one more addition from the inner loop, by
+       using the subkey pointer.
+
+2002-02-19  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * configure.in (asm_path): Renamed "path" to "asm_path". Also look
+       for a machine.m4.
+
+2002-02-16  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sparc/aes.asm: Use that IDX2(j) == j ^ 2
+
+       * Makefile.am (libnettle_a_SOURCES): Reordered aes-decrypt.c and
+       aes-encrypt.c. For some strange reason it makes the benchmark go
+       faster...
+
+       * sparc/aes.asm (_aes_crypt): Use double-buffering, and no
+       separate loop for adding the round key.
+       (round): Keep round index muliplied by 16, so it can be used
+       directly for indexing the subkeys.
+       (_aes_crypt): In the final loop, use ctx+round to access the
+       subkeys, no need for an extra register.
+
+2002-02-15  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sparc/aes.asm (_aes_crypt): Renaming variables, allocating
+       locals starting from %l0.
+       (_aes_crypt): Consistently use %l4, aka i, as the variable for the
+       innermost loops.
+       (_aes_crypt): Moved reading of ctx->nrounds out of the loop.
+       (_aes_crypt): In final_loop, deleted a redundant mov, and use i as
+       loop variable.
+       (_aes_crypt): Started renumbering registers in the inner loop. The
+       computation for the table[j] sub-expression should be kept in
+       register %o[j].
+       (_aes_crypt): Renamed more variables in the inner loop. Now the
+       primary variables are t0, t1, t2, t3.
+
+       * sparc/aes.asm (_aes_crypt): Swapped register %i0 and %o5, %i1
+       and %o0, %i2 and %o4, %i3 and %o3, %i4 and %o2.
+       (_aes_crypt): wtxt was stored in both %l1 and %l2 for the entire
+       function. Freed %l2 for other uses.
+       (_aes_crypt): Likewise for tmp, freeing register %o1.
+
+       * sparc/machine.m4: New file, for sparc-specific macros.
+
+       * sparc/aes.asm (_aes_crypt): Hacked the source_loop, to get rid
+       of yet another redundant loop variable, and one instruction.
+       (_aes_crypt): Strength reduce loop variable in the
+       inner loop, getting rid of one register.
+       (_aes_crypt): Use pre-shifted indices (aes_table.idx_shift), to
+       avoid some shifts in the inner loop.
+       (_aes_crypt): Don't check for nrounds==0 at the start of the loop.
+
+       * asm.m4: Define and use structure-defining macros.
+
+       * Makefile.am (%.asm): Use a GNU pattern rule, to make %.o depend
+       on both %.asm and asm.m4.
+
+       * aes-internal.h (struct aes_table): New subtable idx_shift.
+       Updated tables in aes_encrypt.c and aes_decrypt.c.
+
+       * asm.m4: Use eval to compute values.
+
+       * sparc/aes.asm (_aes_crypt): Deleted commented out old version of
+       the code.
+
+       * asm.m4: Added constants for individual rows of the aes table.
+
+       * aes.c (IDX0, IDX1, IDX2, IDX3): New macros, encapsualting the
+       structure of the idx table.
+
+       * asm.m4: Define various aes struct offsets.
+
+       * testsuite/cbc-test.c (test_cbc_bulk): Use aes_set_encrypt_key
+       and aes_set_decrypt_key.
+
+       * sparc/aes.asm (_aes_crypt): Use symbolic names for the fucntion
+       arguments.
+
+2002-02-14  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sparc/aes.asm: Copied gcc assembler code for _aes_crypt.
+
+       * aesdata.c: New program for generating AES-related tables.
+
+       * testsuite/testutils.c (print_hex): New function (moved from
+       yarrow-test.c).
+
+       * testsuite/rsa-keygen-test.c (progress): Declare the ctx argument
+       as UNUSED.
+
+       * testsuite/cbc-test.c (test_cbc_bulk): New function, testing CBC
+       with larger blocks.
+
+       * yarrow256.c: Replaced uses of aes_set_key with
+       aes_set_encrypt_key.
+
+       * nettle-meta.h (_NETTLE_CIPHER_SEP): New macro, useful for
+       algorithms with separate encyption and decryption key setup.
+
+       * aes-internal.h (struct aes_table): New structure, including all
+       constant tables needed by the unified encryption or decryption
+       function _aes_crypt.
+
+       * aes.c (_aes_crypt): New function, which unifies encryption and
+       decryption.
+
+       AES key setup now uses two separate functions for setting
+       encryption and decryption keys. Applications that don't do
+       decryption need no inverted subkeys and no code to generate them.
+       Similarly, the tables (about 4K each for encryption and
+       decryption), are put into separate files.
+
+       * aes.h (struct aes_ctx): Deleted space for inverse subkeys. For
+       decryption, the inverse subkeys replace the normal subkeys, and
+       they are stored _in the order they are used_.
+
+       * aes-set-key.c (aes_set_key): Deleted file, code moved...
+       * aes-set-decrypt-key.c, aes-set-encrypt-key.c: New files,
+       separated normal and inverse key setup.
+
+       * aes-tables.c: Deleted, tables moved elsewhere...
+       * aes-encrypt.c, aes-decrypt.c: New files; moved encryption and
+       decryption funktions, and needed tables, into separate files.
+
+2002-02-13  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * aes.c (aes_encrypt): Don't unroll the innerloop.
+       (aes_encrypt): Don't unroll the loop for the final round.
+       (aes_decrypt): Likewise, no loop unrolling.
+
+       * aes-set-key.c (aes_set_key): Reversed the order of the inverted
+       subkeys. They are now stored in the same order as they are used.
+
+       * aes-tables.c (itable): New bigger table, generated by aesdata.c.
+
+       * aes.c (aes_decrypt): Rewrote to use the bigger tables.
+
+2002-02-12  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * aes.c (aes_encrypt): Interleave computation and output in the
+       final round.
+
+       * aes-internal.h (AES_SMALL): New macro.
+
+       * aes.c (aes_encrypt): Optionally use smaller rotating inner loop.
+
+       * aes-tables.c (dtbl): Replaced with table generated by aesdata.
+
+       * aes.c (aes_encrypt): Rewrite, now uses larger tables in order to
+       avoid rotates.
+
+       * sparc/aes.asm (aes_encrypt): Strength reduced on j, getting rid
+       of one register and one instruction in the inner loop.
+
+       * sparc/aes.asm (idx, aes_encrypt): Multiplied tabled values by 4,
+       making it possible to get rid of some shifts in the inner loop.
+
+       * configure.in: Fixed spelling of --enable-assembler. Commented
+       out debug echo:s.
+
+       * asm.m4: New file. For now, only doing changequote and changecom.
+
+       * sparc/aes.asm (aes_encrypt): Added comments.
+       (aes_encrypt): Cut off redundant instruction per block, also
+       saving one redundant register pointing to idx.
+       (idx_row): New macro. Include asm.m4.
+
+2002-02-11  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * sparc/aes.asm (key_addition_8to32): Cleaned up.
+       Deleted gcc-generated debugging information.
+
+       * sparc/aes.asm (key_addition32): First attempt at optimization.
+       Made it slower ;-)
+
+       * sparc/aes.asm (key_addition32): Unrolled loop, gained 4%
+       speed, payed four instructions compared to gcc
+       generated code.
+
+       * Makefile.am (.asm.o): New rule for assembling via m4.
+       (libnettle_a_SOURCES): Added new rsa and aes files.
+
+       * configure.in: New command line option --enable-assembler.
+       Selects assembler code depending on the host system.
+
+       * rsa-decrypt.c, rsa-encrypt.c: New files for rsa pkcs#1
+       encryption.
+
+       * aes-set-key.c, aes-tables.c: New files, split off from aes.c.
+       Tables are now not static, but use a _aes_ prefix on their names.
+
+       * aes-internal.h: New file.
+
+       * cast128-meta.c (_NETTLE_CIPHER_FIX): Use _NETTLE_CIPHER_FIX.
+
+       * cbc.c (cbc_decrypt_internal): New function, doing the real CBC
+       procesing and requiring that src != dst.
+       (cbc_decrypt): Use cbc_decrypt_internal. If src == dst, use a
+       buffer of limited size to copy the ciphertext.
+
+       * nettle-internal.c (nettle_blowfish128): Fixed definition, with
+       key size in bits.
+
+       * nettle-meta.h (_NETTLE_CIPHER_FIX): New macro, suitable for
+       ciphers with a fixed key size.
+
+       * examples/nettle-benchmark.c (display): New function for
+       displaying the results, including MB/s figures.
+
+       * sparc/aes.asm: New file. Not yet tuned in any way (it's just the
+       code generated by gcc).
+
+2002-02-11  Niels Möller  <nisse@lysator.liu.se>
+
+       * x86/aes.asm, x86/aes_tables.asm: New assembler implementation by
+       Rafael Sevilla.
+
+2002-02-06  Niels Möller  <nisse@cuckoo.hack.org>
+
+       Applied patch from Dan Egnor improving the base64 code.
+       * base64.h (BASE64_ENCODE_LENGTH): New macro.
+       (struct base64_ctx): New context struct, for decoding.
+       (BASE64_DECODE_LENGTH): New macro.
+       * base64.c (base64_decode_init): New function.
+       (base64_decode_update): New function, replacing base64_decode.
+       Takes a struct base64_ctx argument.
+       * nettle-meta.h: Updated nettle_armor, and related typedefs and
+       macros.
+       * testsuite/testutils.c (test_armor): Updated.
+       * configure.in: Use AC_PREREQ(2.50).
+
+2002-02-01  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * Released nettle-1.5.
+
+2002-01-31  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * acinclude.m4: Commented out gmp-related macros, they're probably
+       not needed anymore.
+
+2002-01-31  Niels Möller  <nisse@lysator.liu.se>
+
+       * configure.in: Added command line options --with-lib-path and
+       --with-include-path. Use the RPATH-macros to get correct flags for
+       linking the test programs with gmp.
+
+       * acinclude.m4: New file.
+
+2002-01-31  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * nettle.texinfo (Randomness): New subsection on Yarrow.
+
+2002-01-30  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * nettle.texinfo (Randomness): New chapter.
+       Spell checking and ispell configuration.
+
+       * md5.c: Added reference to RFC 1321.
+
+2002-01-24  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * nettle.texinfo (Public-key algorithms): Minor fixes.
+
+2002-01-22  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * nettle.texinfo (Nettle soup): New chapter.
+       (Hash functions): New subsection on struct nettle_hash.
+       (Hash functions): New subsection on struct nettle_cipher.
+       (Keyed hash functions): New section, describing MAC:s and HMAC.
+       (Public-key algorithms): New chapter.
+
+       * testsuite/testutils.c (test_armor): New function.
+
+       * testsuite/base64-test.c: New testcase.
+
+       * testsuite/Makefile.am (TS_PROGS): Added base64-test.
+
+       * nettle-meta.h (struct nettle_armor): New struct.
+
+       * configure.in: Bumped version to 1.5.
+
+       * Makefile.am (libnettle_a_SOURCES): Added base64 files, and some
+       missing header files.
+
+       * base64.c, base64.h, base64-meta.c: New files, hacked by Dan
+       Egnor.
+
+2002-01-16  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/yarrow-test.c: Deleted ran_array code, use
+       knuth-lfib.h instead.
+
+       * testsuite/testutils.c (test_rsa_md5, test_rsa_sha1): Moved
+       functions here...
+       * testsuite/rsa-test.c: ...from here.
+
+       * testsuite/rsa-keygen-test.c: New file.
+
+       * testsuite/knuth-lfib-test.c: New file.
+
+       * Makefile.am (libnettle_a_SOURCES): Added knuth-lfib.c and
+       rsa-keygen.c.
+
+       * rsa-keygen.c: New file.
+
+       * rsa.h (RSA_MINIMUM_N_OCTETS): New constant.
+       (RSA_MINIMUM_N_BITS): New constant.
+       (nettle_random_func, nettle_progress_func): New typedefs. Perhaps
+       they don't really belong in this file.
+       (rsa_generate_keypair): Added progress-callback argument.
+
+       * macros.h (READ_UINT24, WRITE_UINT24, READ_UINT16, WRITE_UINT16):
+       New macros.
+
+       * knuth-lfib.c, knuth-lfib.h: New files, implementing a
+       non-cryptographic prng.
+
+2002-01-15  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * hmac-sha1.c: New file.
+
+2002-01-14  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * configure.in: Bumped version to 1.1.
+
+       * testsuite/hmac-test.c (test_main): Added hmac-sha1 test cases.
+
+       * rsa.c (rsa_init_private_key, rsa_clear_private_key): Handle d.
+
+       * rsa.h (struct rsa_private_key): Reintroduced d attribute, to be
+       used only for key generation output.
+       (rsa_generate_keypair): Wrote a prototype.
+
+       * Makefile.am (libnettle_a_SOURCES): Added hmac-sha1.c and
+       nettle-internal.h.
+
+       * des.c: Use static const for all tables.
+       (des_set_key): Use a new const * variable for the parity
+       procesing, for constness reasons.
+
+       * list-obj-sizes.awk: New file.
+
+       * nettle-internal.c, nettle-internal.h: New files.
+
+       * testsuite/Makefile.am (TS_PROGS): Added hmac-test. Deleted old
+       m4-stuff.
+
+       * testsuite/testutils.h (LDATA): Moved this macro here,...
+       * testsuite/rsa-test.c: ... from here.
+
+       * testsuite/hmac-test.c: New file.
+
+       * hmac.h: General cleanup. Added declarations of hmac-md5,
+       hmac-sha1 and hmac-sha256.
+
+       * hmac.c: Bug fixes.
+
+       * hmac-md5.c: First working version.
+
+       * Makefile.am (libnettle_a_SOURCES): Added hmac.c and hmac-md5.c.
+       (libnettleinclude_HEADERS): Added hmac.h.
+
+       * testsuite/rsa-test.c: Also test a 777-bit key.
+
+       * rsa.c (rsa_check_size): Changed argument to an mpz_t. Updated
+       callers.
+       (rsa_prepare_private_key): Compute the size of the key by
+       computing n = p * q.
+
+       * rsa-compat.c: Adapted to new private key struct.
+       * rsa_md5.c: Likesize.
+       * rsa_sha1.c: Likesize.
+
+       * rsa.c (rsa_check_size): New function, for computing and checking
+       the size of the modulo in octets.
+       (rsa_prepare_public_key): Usa rsa_check_size.
+       (rsa_init_private_key): Removed code handling n, e and d.
+       (rsa_clear_private_key): Likewise.
+       (rsa_compute_root): Always use CRT.
+
+       * rsa.h (struct rsa_private_key): Deleted public key and d from
+       the struct, as they are not needed. Added size attribute.
+
+2002-01-12  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * Makefile.am: Added *-meta files.
+
+       * rsa.c (rsa_init_public_key): New function.
+       (rsa_clear_public_key): Likewise.
+       (rsa_init_private_key): Likewise.
+       (rsa_clear_private_key): Likewise.
+
+       * aes-meta.c: New file.
+       * arcfour-meta.c: New file.
+       * cast128-meta.c: New file.
+       * serpent-meta.c: New file.
+       * twofish-meta.c: New file.
+
+       * examples/nettle-benchmark.c: Use the interface in nettle-meta.h.
+
+2002-01-11  Niels Möller  <nisse@cuckoo.hack.org>
+
+       Don't use m4 for generating test programs, it's way overkill. Use
+       the C preprocessor instead.
+       * testsuite/*-test.c: New file.
+
+       * hmac.c, hmac.h, hmac-md5.c: New files.
+
+       Defined structures describing the algoriths. Useful for code that
+       wants to treat an algorithm as a black box.
+       * nettle-meta.h, md5-meta.c, sha1-meta.c, sha256-meta.c: New
+       files.
+
+2002-01-09  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * rsa-compat.c: Updated for new md5 and rsa conventions.
+
+       * rsa_md5.c: Represent a signature as an mpz_t, not a string.
+       Updated calls of md5 functions.
+       * rsa_sha1.c: Likewise.
+
+       * rsa.c (rsa_prepare_public_key): Renamed function, was
+       rsa_init_public_key.
+       (rsa_prepare_private_key): Renamed function, was
+       rsa_init_private_key.
+
+       * nettle.texinfo (Hash functions): Update for the changed
+       interface without *_final. Document sha256.
+
+       * testsuite/md5-test.m4, testsuite/sha1-test.m4,
+       testsuite/sha256-test.m4, testsuite/yarrow-test.c: Updated for new
+       hash function interface.
+
+       * yarrow256.c: Removed calls of sha256_final and and some calls of
+       sha256_init.
+
+       * md5-compat.c (MD5Final): Call only md5_digest.
+
+       * md5.c (md5_digest): Call md5_final and md5_init.
+       (md5_final): Declared static.
+       sha1.c, sha256.c: Analogous changes.
+
+       * bignum.c (nettle_mpz_get_str_256): Declare the input argument
+       const.
+
+2001-12-14  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * Makefile.am (EXTRA_DIST): Added $(des_headers). Changed
+       dependencies for $(des_headers) to depend only on the source file
+       desdata.c, not on the executable.
+
+2001-12-12  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/yarrow-test.c (main): Updated testcase to match fixed
+       generator. Send verbose output to stdout, not stderr.
+
+       * yarrow256.c (yarrow_slow_reseed): Bug fix, update the fast pool
+       with the digest of the slow pool.
+       (yarrow256_init): Initialize seed_file and counter to zero, to
+       ease debugging.
+
+2001-12-07  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * bignum.c (nettle_mpz_get_str_256): Fixed handling of leading
+       zeroes.
+
+2001-12-05  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/yarrow-test.c (main): Updated test to match the fixed
+       key event estimator.
+
+       * yarrow_key_event.c (yarrow_key_event_estimate): Fixed handling
+       of timing info.
+
+       * nettle.texinfo (Copyright): Say that under certain
+       circumstances, Nettle can be used as if under the LGPL.
+
+       * README: Added a paragraph on copyright.
+
+2001-11-15  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * yarrow256.c (yarrow256_force_reseed): New function.
+
+2001-11-14  Niels Möller  <nisse@ehand.com>
+
+       * testsuite/yarrow-test.c (main): Use yarrow256_is_seeded.
+
+       * yarrow256.c (yarrow256_needed_sources): New function.
+       (yarrow256_is_seeded): New function.
+       (yarrow256_update): Use yarrow256_needed_sources.
+
+2001-11-14  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/yarrow-test.out: Updated, to match the seed-file aware
+       generator.
+
+       * testsuite/yarrow-test.c: Updated expected_output. Check the seed
+       file contents at the end.
+
+       * yarrow256.c (yarrow256_seed): New function.
+       (yarrow_fast_reseed): Create new seed file contents.
+
+2001-11-13  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * yarrow.h: Deleted yarrow160 declarations.
+
+2001-11-02  Niels Möller  <nisse@ehand.com>
+
+       * yarrow256.c (yarrow256_init): Fixed order of code and
+       declarations.
+
+2001-10-30  Niels Möller  <nisse@ehand.com>
+
+       * rsa-compat.h: Added real prototypes and declarations.
+
+       * Makefile.am (libnettle_a_SOURCES): Added rsa-compat.h and
+       rsa-compat.c.
+
+       * rsa-compat.c: New file, implementing RSA ref signature and
+       verification functions.
+
+       * configure.in: Check for libgmp. Deleted tests for SIZEOF_INT and
+       friends.
+
+       * rsa_sha1.c: New file, PKCS#1 rsa-sha1 signatures.
+       * rsa_md5.c: New file, PKCS#1 rsa-md5 signatures.
+
+       * rsa.c: New file with general rsa functions.
+
+       * Makefile.am (libnettle_a_SOURCES): Added rsa and bignum files.
+
+       * bignum.c, bignum.h: New file, with base256 functions missing in
+       gmp.
+
+       * testsuite/Makefile.am: Added bignum-test.
+
+       * testsuite/run-tests (test_program): Check the xit code more
+       carefully, and treat 77 as skip. This convention was borrowed from
+       autotest.
+
+       * testsuite/macros.m4: New macro SKIP which exits with code 77.
+
+       * testsuite/bignum-test.m4: New file.
+
+2001-10-15  Niels Möller  <nisse@ehand.com>
+
+       * testsuite/Makefile.am (EXTRA_DIST): Include rfc1750.txt in the
+       distribution.
+
+2001-10-14  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/des-test.m4: Added testcase taken from applied
+       cryptography.
+
+       * testsuite/yarrow-test.c: Use sha256 instead of sha1 for checking
+       input and output. Updated the expected values.
+
+       * yarrow256.c (YARROW_RESEED_ITERATIONS): New constant.
+       (yarrow_iterate): New function.
+       (yarrow_fast_reseed): Call yarrow_iterate.
+
+       * testsuite/yarrow-test.c: Added verbose flag, disabled by
+       default.
+
+2001-10-12  Niels Möller  <nisse@ehand.com>
+
+       * examples/nettle-benchmark.c: Added more ciphers.
+
+       * Makefile.am (SUBDIRS): Added the examples subdir.
+
+       * configure.in: Output examples/Makefile.
+
+2001-10-12  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * examples/nettle-benchmark.c: New benchmarking program.
+
+2001-10-10  Niels Möller  <nisse@ehand.com>
+
+       * testsuite/yarrow-test.c: Open rfc1750.txt. Hash input and
+       output, and compare to expected values.
+
+       * testsuite/Makefile.am (CFLAGS): Don't disable optimization.
+       (run-tests): Set srcdir in the environment when running run-tests.
+
+       * testsuite/rfc1750.txt: Added this rfc as test input for yarrow.
+
+       * yarrow_key_event.c (yarrow_key_event_estimate): Check if
+       previous is zero.
+       (yarrow_key_event_init): Initialize previous to zero.
+
+       * yarrow256.c: Added debug some output.
+
+       * testsuite/yarrow-test.c (main): Better output of entropy
+       estimates at the end.
+
+2001-10-09  Niels Möller  <nisse@ehand.com>
+
+       * testsuite/Makefile.am (TS_PROGS): Added yarrow-test.
+
+       * testsuite/yarrow-test.c: New file.
+
+       * yarrow256.c (yarrow256_init): Initialize the sources.
+       (yarrow256_random): Fixed loop condition.
+
+       * yarrow.h (YARROW_KEY_EVENT_BUFFER): New constant.
+
+       * yarrow_key_event.c: New file.
+
+       * Makefile.am (libnettle_a_SOURCES): Added yarrow_key_event.c.
+
+2001-10-08  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * yarrow.h (struct yarrow_key_event_ctx): New struct.
+
+       * yarrow256.c (yarrow_fast_reseed): Generate two block of output
+       using the old key and feed into the pool.
+
+       * yarrow.h (struct yarrow256_ctx): Deleted buffer, index and
+       block_count.
+
+       * yarrow256.c (yarrow_fast_reseed): New function.
+       (yarrow_slow_reseed): New function.
+       (yarrow256_update): Check seed/reseed thresholds.
+       (yarrow_gate): New function, extracted from
+       yarrow_generate_block_with_gate which was deleted.
+       (yarrow_generate_block_with_gate): Deleted function.
+       (yarrow256_random): Don't buffer any output, instead gate after
+       each request.
+       (YARROW_GATE_THRESHOLD): Deleted constant.
+
+2001-10-07  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * Makefile.am: Added yarrow files.
+
+       * yarrow256.c: New file, implementing Yarrow. Work in progress.
+
+       * sha256.c: New file, implementing sha256.
+
+       * testsuite/Makefile.am (CFLAGS): Added sha256-test.
+
+       * testsuite/sha256-test.m4: New testcases for sha256.
+
+       * shadata.c: New file, for generating sha256 constants.
+
+       * sha.h: Renamed sha1.h to sha.h, and added declarations for
+       sha256.
+
+2001-10-05  Niels Möller  <nisse@ehand.com>
+
+       * testsuite/aes-test.m4: Added a comment with NIST test vectors.
+
+2001-10-04  Niels Möller  <nisse@ehand.com>
+
+       * rsa.h, rsa-compat.h, yarrow.h: New files.
+
+2001-09-25  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * Released version 1.0.
+
+2001-09-25  Niels Möller  <nisse@ehand.com>
+
+       * sha1.c: Include stdlib.h, for abort.
+
+       * md5.c: Include string.h, for memcpy.
+
+       * testsuite/Makefile.am (M4_FILES): New variable. Explicitly list
+       those C source files that should be generated by m4.
+
+       * configure.in: Changed package name from "libnettle" to "nettle".
+
+       * Makefile.am (EXTRA_DIST): Added .bootstrap.
+
+       * AUTHORS: Added a reference to the manual.
+
+2001-09-25  Niels Möller  <nisse@lysator.liu.se>
+
+       * des-compat.c (des_cbc_cksum): Bug fix, local variable was
+       declared in the middle of a block.
+
+2001-09-19  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * nettle.texinfo (Compatibility functions): New section,
+       mentioning md5-compat.h and des-compat.h.
+
+2001-09-18  Niels Möller  <nisse@ehand.com>
+
+       * index.html: New file.
+
+2001-09-16  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * nettle.texinfo: Added description of des3. Minor fixes.
+
+       * testsuite/des-compat-test.c (cbc_data): Shorten to 32 bytes (4
+       blocks), the last block of zeroes wasn't used anyway.
+
+       * des-compat.c (des_compat_des3_decrypt): Decrypt in the right
+       order.
+       (des_ncbc_encrypt): Bug fixed.
+       (des_cbc_encrypt): Rewritten as a wrapper around des_ncbc_encrypt.
+
+2001-09-14  Niels Möller  <nisse@ehand.com>
+
+       * testsuite/des-compat-test.c: New file, copied from libdes
+       (freeswan). All implemented functions but des_cbc_cksum seems to
+       work now.
+
+       * testsuite/Makefile.am (TS_PROGS): Added des-compat-test.
+
+       * des-compat.c: Added libdes typedef:s. Had to remove all use of
+       const in the process.
+       (des_check_key): New global variable, checked by des_set_key.
+
+       * des.c (des_set_key): Go on and expand the key even if it is
+       weak.
+
+       * des-compat.c (des_cbc_cksum): Implemented.
+       (des_key_sched): Fixed return values.
+
+2001-09-11  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * Makefile.am: Added des-compat.c and des-compat.h
+
+       * des-compat.c: Bugfixes, more functions implemented.
+
+       * des-compat.h: Define DES_ENCRYPT and DES_DECRYPT. Bugfixes.
+
+2001-09-10  Niels Möller  <nisse@ehand.com>
+
+       * nettle.texinfo (Copyright): Added copyright information for
+       serpent.
+       (Miscellaneous functions): Started writing documentation on the CBC
+       functions.
+       (Cipher Block Chaining): This section more or less complete now.
+
+2001-09-09  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/cbc-test.m4: Record intermediate values in a comment.
+       * testsuite/des3-test.m4: Likewise.
+
+       * testsuite/aes-test.m4: Added test case that appeared broken in
+       the cbc test.
+
+       * cbc.c (cbc_encrypt): Bug fix, encrypt block *after* XOR:ing the
+       iv.
+
+       * Makefile.am (libnettleinclude_HEADERS): Added cbc.h. Deleted
+       des3.h.
+       (libnettle_a_SOURCES): Added des3.c.
+
+       * testsuite/Makefile.am (TS_PROGS): Added des3-test and cbc-test.
+
+       * testsuite/cbc-test.m4: New testcase.
+
+       * testsuite/des3-test.m4: New testcase.
+
+       * cbc.h (CBC_CTX): New macro.
+       (CBC_ENCRYPT): New macro.
+       (CBC_DECRYPT): New macro.
+
+       * des.c (des_fix_parity): New function.
+
+       * des3.c: New file, implementing triple des.
+
+2001-09-06  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * cbc.c, cbc.h: New files, for general CBC encryption.
+
+       * des-compat.h: Added some prototypes.
+
+2001-09-05  Niels Möller  <nisse@ehand.com>
+
+       * testsuite/Makefile.am (TS_PROGS): Added md5-compat-test.
+
+       * README: Copied introduction from the manual.
+
+       * configure.in: Bumped version to 1.0.
+
+       * Makefile.am (libnettleinclude_HEADERS): Added missing includes.
+       (libnettle_a_SOURCES): Added md5-compat.c and md5-compat.h.
+
+       * md5-compat.c, md5-compat.h: New files, implementing an RFC
+       1321-style interface.
+
+2001-09-02  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * twofish.c (twofish_decrypt): Fixed for();-bug in the block-loop.
+       Spotted by Jean-Pierre.
+       (twofish_encrypt): Likewise.
+
+2001-07-03  Niels Möller  <nisse@ehand.com>
+
+       * testsuite/testutils.c: Include string.h.
+
+       * twofish.c: Include string.h.
+
+2001-06-17  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.am (des_headers): Dont use $(srcdir)/-prefixes as that
+       seems to break with GNU make 3.79.1.
+
+       * testsuite/testutils.c, testsuite/testutils.h: Use <inttypes.h>,
+       not <stdint.h>.
+       Include <stdlib.h>.
+
+2001-06-17  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * Use <inttypes.h>, not <stdint.h>.
+
+       * blowfish.h (BLOWFISH_MAX_KEY_SIZE): Fixed, should be 56.
+
+       * Fixed copyright notices.
+
+       * Makefile.am (libnettle_a_SOURCES): Added desinfo.h and
+       desCode.h.
+       (info_TEXINFOS): Added manual.
+       (EXTRA_DIST): Added nettle.html.
+       (%.html): Added rule for building nettle.html.
+
+       * nettle.texinfo: New manual.
+
+       * configure.in: Bumped version to 0.2.
+
+       * testsuite/Makefile.am (TS_PROGS): Added cast128 test.
+
+       * Added CAST128.
+
+       * testsuite/serpent-test.m4: Added a few rudimentary tests
+       extracted from the serpent package.
+
+       * twofish.c: Adapted to nettle. Made constant tables const.
+       Deleted bytes_to_word and word_to_bytes; use LE_READ_UINT32 and
+       LE_WRITE_UINT32 instead.
+       (twofish_selftest): Deleted. Moved the tests to the external
+       testsuite.
+       (twofish_set_key): Don't silently truncate too large keys.
+
+       * sha1.c (sha1_update): Use unsigned for length.
+
+       * serpent.c (serpent_set_key): Read the key backwards. Fixed
+       padding (but there are no test vectors for key_size not a multiple
+       of 4).
+       (serpent_encrypt): Read and write data in the strange order used
+       by the reference implementation.
+       (serpent_decrypt): Likewise.
+
+       * macros.h (FOR_BLOCKS): New macro, taken from lsh.
+
+       * blowfish.h (struct blowfish_ctx): Use a two-dimensional array
+       for s.
+
+       * blowfish.c (initial_ctx): Arrange constants into a struct, to
+       simplify key setup.
+       (F): Deleted all but one definitions of the F function/macro.
+       Added a context argument, and use that to find the subkeys.
+       (R): Added context argument, and use that to find the subkeys.
+       (blowfish_set_key): Some simplification.
+
+       (encrypt): Deleted code for non-standard number of rounds. Deleted
+       a bunch of local variables. Using the context pointer for
+       everything should consume less registers.
+       (decrypt): Likewise.
+
+       * Makefile.am (libnettle_a_SOURCES): Added twofish.
+
+2001-06-16  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * testsuite/blowfish-test.m4: Fixed test.
+
+       * Added twofish implementation.
+
+       * blowfish.h (struct blowfish_ctx): Use the correct size for the p
+       array.
+
+2001-06-15  Niels Möller  <nisse@ehand.com>
+
+       * testsuite/blowfish-test.m4: Fixed testcase, use correct key
+       length.
+
+       * Makefile.am (libnettle_a_SOURCES): Added blowfish files.
+       ($(des_headers)): Strip directory part when passing file name to
+       desdata.
+
+       * testsuite/blowfish-test.m4: Added one test, from GNUPG.
+
+       * Created blowfish.c and blowfish.h (from GNUPG via LSH). Needs
+       more work.
+
+       * aes.h: Fixed copyright notice to not mention GNU MP. XXX: Review
+       all nettle copyrights.
+
+       * testsuite/Makefile.am (TS_PROGS): Added tests for twofish and
+       blowfish.
+
+2001-06-13  Niels Möller  <nisse@ehand.com>
+
+       * Makefile.am (libnettle_a_SOURCES): Added serpent files.
+
+2001-06-12  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * des.c (des_encrypt, des_decrypt): Assert that the key setup was
+       successful.
+
+       * testsuite/Makefile.am (TS_PROGS): Added tests for des and sha1.
+
+       * testsuite/sha1-test.m4: New file.
+
+       * testsuite/des-test.m4: New file.
+
+       * Added sha1 files.
+
+       * Added desCore files.
+
+       * Makefile.am: Added desCore and sha1.
+
+2001-04-17  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * install-sh: Copied the standard install script.
+
+       * testsuite/Makefile.am (CFLAGS): Disable optimization. Add
+       $(top_srcdir) to the include path.
+       (EXTRA_DIST): Added testutils.h, testutils.c and run-tests.
+       (run-tests): Fixed path to run-tests.
+
+       * Makefile.am (EXTRA_DIST): Added memxor.h.
+       (libnettleinclude_HEADERS): Install headers in
+       $(libnettleincludedir).
+
+2001-04-13  Niels Möller  <nisse@cuckoo.hack.org>
+
+       * Initial checkin.
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..5458714
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,234 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006 Free Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package.  The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.
+
+     Running `configure' might take a while.  While running, it prints
+     some messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about.  Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you can use GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory.  After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug.  Until the bug is fixed you can use this workaround:
+
+     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/Makefile.in b/Makefile.in
new file mode 100644 (file)
index 0000000..27f076a
--- /dev/null
@@ -0,0 +1,460 @@
+# Nettle Makefile
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+LIBOBJS = @LIBOBJS@
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = $(INSTALL_PROGRAM) -s
+MKDIR_P = @MKDIR_P@
+
+SUBDIRS = tools testsuite examples
+
+include config.make
+
+PRE_CPPFLAGS = -I.
+# FIXME: Add configuration of LIBEXT?
+LIBTARGETS = libnettle.a @IF_HOGWEED@ libhogweed.a
+SHLIBTARGETS = $(LIBNETTLE_FORLINK) @IF_HOGWEED@ $(LIBHOGWEED_FORLINK)
+
+TARGETS = aesdata$(EXEEXT) desdata$(EXEEXT) shadata$(EXEEXT) gcmdata$(EXEEXT)\
+         $(LIBTARGETS) @IF_SHARED@ $(SHLIBTARGETS)
+
+DOCTARGETS = nettle.info nettle.html nettle.pdf
+
+PKGCONFIG_FILES = nettle.pc @IF_HOGWEED@ hogweed.pc
+pkgconfigdir = $(libdir)/pkgconfig
+
+all check install uninstall:
+       $(MAKE) $@-here
+       set -e; for d in $(SUBDIRS); do \
+         echo "Making $@ in $$d" ; (cd $$d && $(MAKE) $@); done
+
+clean distclean mostlyclean maintainer-clean tags:
+       set -e; for d in $(SUBDIRS); do \
+         echo "Making $@ in $$d" ; (cd $$d && $(MAKE) $@); done
+       $(MAKE) $@-here
+
+check-here:
+       true
+
+# FIXME: Remove. These targets aren't supported, but they are expected by the
+# automake generated Makefiles in the lsh build.
+dvi installcheck uninstallcheck:
+       true
+
+all-here: $(TARGETS) $(DOCTARGETS)
+
+nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \
+                aes-encrypt-internal.c aes-encrypt.c aes-encrypt-table.c \
+                aes-set-encrypt-key.c aes-set-decrypt-key.c aes-meta.c \
+                arcfour.c arcfour-crypt.c arcfour-meta.c \
+                arctwo.c arctwo-meta.c \
+                base16-encode.c base16-decode.c base16-meta.c \
+                 base64-encode.c base64-decode.c base64-meta.c \
+                camellia-crypt.c camellia-crypt-internal.c \
+                camellia-set-encrypt-key.c camellia-set-decrypt-key.c \
+                camellia-table.c camellia-meta.c \
+                cast128.c cast128-meta.c \
+                blowfish.c \
+                cbc.c ctr.c gcm.c gcm-aes.c \
+                des.c \
+                des3.c des-compat.c \
+                hmac.c hmac-md5.c hmac-ripemd160.c hmac-sha1.c \
+                hmac-sha224.c hmac-sha256.c hmac-sha384.c hmac-sha512.c \
+                knuth-lfib.c \
+                md2.c md2-meta.c md4.c md4-meta.c \
+                md5.c md5-compress.c md5-compat.c md5-meta.c \
+                ripemd160.c ripemd160-compress.c ripemd160-meta.c \
+                sha1.c sha1-compress.c sha1-meta.c \
+                sha256.c sha256-compress.c sha224-meta.c sha256-meta.c \
+                sha512.c sha512-compress.c sha384-meta.c sha512-meta.c \
+                serpent-set-key.c serpent-encrypt.c serpent-decrypt.c \
+                serpent-meta.c \
+                twofish.c twofish-meta.c \
+                yarrow256.c yarrow_key_event.c \
+                buffer.c buffer-init.c realloc.c \
+                nettle-meta-hashes.c nettle-meta-ciphers.c \
+                nettle-meta-armors.c \
+                nettle-internal.c write-be32.c write-le32.c
+
+hogweed_SOURCES = sexp.c sexp-format.c \
+                 sexp-transport.c sexp-transport-format.c \
+                 bignum.c bignum-next-prime.c \
+                 bignum-random.c bignum-random-prime.c \
+                 sexp2bignum.c \
+                 pkcs1.c pkcs1-rsa-md5.c pkcs1-rsa-sha1.c \
+                 pkcs1-rsa-sha256.c pkcs1-rsa-sha512.c \
+                 rsa.c rsa-sign.c rsa-verify.c \
+                 rsa-md5-sign.c rsa-md5-verify.c \
+                 rsa-sha1-sign.c rsa-sha1-verify.c \
+                 rsa-sha256-sign.c rsa-sha256-verify.c \
+                 rsa-sha512-sign.c rsa-sha512-verify.c \
+                 rsa-encrypt.c rsa-decrypt.c \
+                 rsa-keygen.c rsa-compat.c \
+                 rsa2sexp.c sexp2rsa.c \
+                 dsa.c dsa-sign.c dsa-verify.c dsa-keygen.c \
+                 dsa-sha1-sign.c dsa-sha1-verify.c \
+                 dsa-sha256-sign.c dsa-sha256-verify.c  \
+                 dsa2sexp.c sexp2dsa.c \
+                 pgp-encode.c rsa2openpgp.c \
+                 der-iterator.c der2rsa.c der2dsa.c
+
+HEADERS = aes.h arcfour.h arctwo.h asn1.h bignum.h blowfish.h \
+         base16.h base64.h buffer.h camellia.h cast128.h \
+         cbc.h ctr.h gcm.h \
+         des.h des-compat.h dsa.h \
+         hmac.h \
+         knuth-lfib.h \
+         macros.h \
+         md2.h md4.h \
+         md5.h md5-compat.h \
+         memxor.h \
+         nettle-meta.h nettle-types.h \
+         pgp.h pkcs1.h realloc.h ripemd160.h rsa.h rsa-compat.h \
+         sexp.h \
+         serpent.h sha.h twofish.h \
+         yarrow.h
+
+INSTALL_HEADERS = $(HEADERS) nettle-stdint.h
+
+SOURCES = $(nettle_SOURCES) $(hogweed_SOURCES) aesdata.c desdata.c shadata.c gcmdata.c
+
+DISTFILES = $(SOURCES) $(HEADERS) .bootstrap aclocal.m4 configure.ac \
+       configure stamp-h.in \
+       config.guess config.sub install-sh texinfo.tex \
+       config.h.in config.m4.in config.make.in Makefile.in \
+       README AUTHORS COPYING.LIB INSTALL NEWS TODO ChangeLog \
+       nettle.pc.in hogweed.pc.in \
+       memxor.c $(des_headers) descore.README \
+       aes-internal.h camellia-internal.h serpent-internal.h \
+       cast128_sboxes.h desinfo.h desCode.h \
+       nettle-internal.h nettle-write.h prime-list.h \
+       asm.m4 \
+       nettle.texinfo nettle.info nettle.html nettle.pdf sha-example.c
+
+# Rules building static libraries
+nettle_OBJS = $(nettle_SOURCES:.c=.$(OBJEXT)) $(LIBOBJS)
+nettle_PURE_OBJS = $(nettle_OBJS:.$(OBJEXT)=.p$(OBJEXT))
+
+hogweed_OBJS = $(hogweed_SOURCES:.c=.$(OBJEXT))
+hogweed_PURE_OBJS = $(hogweed_OBJS:.$(OBJEXT)=.p$(OBJEXT))
+
+libnettle.a: $(nettle_OBJS)
+       -rm -f $@
+       $(AR) $(ARFLAGS) $@ $(nettle_OBJS)
+       $(RANLIB) $@
+
+libhogweed.a: $(hogweed_OBJS)
+       -rm -f $@
+       $(AR) $(ARFLAGS) $@ $(hogweed_OBJS)
+       $(RANLIB) $@
+
+.c.$(OBJEXT):
+       $(COMPILE) $(CCPIC_MAYBE) -c $< \
+       && $(DEP_PROCESS)
+
+# Rules building shared libraries
+$(LIBNETTLE_FORLINK): $(nettle_PURE_OBJS)
+       $(LIBNETTLE_LINK) $(nettle_PURE_OBJS) -o $@ $(LIBNETTLE_LIBS)
+       -mkdir .lib 2>/dev/null
+       [ -z "$(LIBNETTLE_SONAME)" ] || (cd .lib \
+          && ln -sf ../$(LIBNETTLE_FORLINK) $(LIBNETTLE_SONAME))
+
+$(LIBHOGWEED_FORLINK): $(hogweed_PURE_OBJS) $(LIBNETTLE_FORLINK)
+       $(LIBHOGWEED_LINK) $(hogweed_PURE_OBJS) -o $@ $(LIBHOGWEED_LIBS)
+       -mkdir .lib 2>/dev/null
+       [ -z "$(LIBHOGWEED_SONAME)" ] || (cd .lib \
+          && ln -sf ../$(LIBHOGWEED_FORLINK) $(LIBHOGWEED_SONAME))
+
+.c.p$(OBJEXT):
+       $(COMPILE) $(SHLIBCFLAGS) -c $< -o $@ \
+       && $(DEP_PROCESS)
+
+# For Solaris and BSD make, we have to use an explicit rule for each executable
+aesdata$(EXEEXT): aesdata.$(OBJEXT)
+       $(LINK) aesdata.$(OBJEXT) $(LIBS) -o aesdata$(EXEEXT)
+
+desdata$(EXEEXT): desdata.$(OBJEXT)
+       $(LINK) desdata.$(OBJEXT) $(LIBS) -o desdata$(EXEEXT)
+
+shadata$(EXEEXT): shadata.$(OBJEXT)
+       $(LINK) shadata.$(OBJEXT) $(LIBS) -lm -o shadata$(EXEEXT)
+
+gcmdata$(EXEEXT): gcmdata.$(OBJEXT)
+       $(LINK) gcmdata.$(OBJEXT) $(LIBS) -o gcmdata$(EXEEXT)
+
+# .$(OBJEXT)$(EXEEXT):
+#      $(LINK) $< $(LIBS) -o $@
+
+# desCore rules
+# It seems using $(srcdir)/ doesn't work with GNU make 3.79.1
+# des_headers = $(srcdir)/rotors.h $(srcdir)/keymap.h 
+des_headers = rotors.h keymap.h 
+
+# Generate DES headers.
+$(des_headers): desdata.c
+       $(MAKE) desdata$(EXEEXT)
+       f="$(srcdir)/`basename $@`"; \
+         ./desdata$(EXEEXT) $(@F) > $${f}T; \
+         test -s $${f}T && mv -f $${f}T $$f
+
+des.$(OBJEXT): des.c des.h $(des_headers)
+
+.asm.$(OBJEXT):
+       $(M4) $(srcdir)/asm.m4 machine.m4 config.m4 \
+               $< >$*.s
+       $(COMPILE) $(CCPIC_MAYBE) -c $*.s
+       echo "$@ : $< $(srcdir)/asm.m4 machine.m4 config.m4" >$@.d 
+
+.asm.p$(OBJEXT):
+       $(M4) $(srcdir)/asm.m4 machine.m4 config.m4 \
+               $< >$*.s
+       $(COMPILE) $(SHLIBCFLAGS) -c $*.s -o $@
+       echo "$@ : $< $(srcdir)/asm.m4 machine.m4 config.m4" >$@.d 
+
+# Texinfo rules
+.texinfo.info:
+       cd $(srcdir) && $(MAKEINFO) --output $@ `basename "$<"`
+
+.texinfo.html:
+       cd $(srcdir) && $(MAKEINFO) --html --no-split \
+         --output $@T `basename "$<"` \
+         && test -s $@T && mv -f $@T $@
+
+.texinfo.dvi:
+       cd $(srcdir) && texi2dvi `basename "$<"`
+
+.dvi.ps:
+       cd $(srcdir) && dvips -Ppdf -G0 -o `basename "$<" .dvi`.ps `basename "$<"`
+
+# Avoid rebuilding .dvi and .ps files when the .texinfo source is unchanged.
+PS2PDFFLAGS=-dCompatibilityLevel=1.3 -dMAxSubsetPct=100 -dSubsetFonts=true -dEmbedAllFonts=true
+.texinfo.pdf:
+       $(MAKE) `basename "$<" .texinfo`.ps
+       cd $(srcdir) && ps2pdf $(PS2PDFFLAGS) `basename "$<" .texinfo`.ps
+
+# Configure-related rules, mostly copied from the autoconf manual. No
+# $(srcdir) prefixes on the targets, though.
+
+configure: configure.ac aclocal.m4
+       cd $(srcdir) && $(AUTOCONF)
+
+# autoheader might not change config.h.in, so touch a stamp file.
+config.h.in: stamp-h.in
+stamp-h.in: configure.ac aclocal.m4
+       cd $(srcdir) && $(AUTOHEADER)
+       echo timestamp > $(srcdir)/stamp-h.in
+
+config.status: configure
+       ./config.status --recheck
+
+config.h: stamp-h
+stamp-h: config.h.in config.status
+       ./config.status config.h
+       echo timestamp > stamp-h
+
+Makefile: Makefile.in config.status
+       ./config.status $@
+
+config.make: config.make.in config.status
+       ./config.status $@
+
+config.m4: config.m4.in config.status
+       ./config.status $@
+
+nettle.pc: nettle.pc.in config.status
+       ./config.status $@
+
+hogweed.pc: hogweed.pc.in config.status
+       ./config.status $@
+
+# Installation
+install-here: install-info install-headers install-static install-pkgconfig \
+       @IF_SHARED@ install-shared-nettle @IF_HOGWEED@ install-shared-hogweed
+
+install-static: $(LIBTARGETS)
+       $(MKDIR_P) $(DESTDIR)$(libdir)
+       for f in $(LIBTARGETS); do \
+         $(INSTALL_DATA) $$f $(DESTDIR)$(libdir) ; \
+       done
+
+install-shared-nettle: $(LIBNETTLE_FORLINK)
+       $(MKDIR_P) $(DESTDIR)$(libdir)
+       $(INSTALL_DATA) $(LIBNETTLE_FORLINK) $(DESTDIR)$(libdir)/$(LIBNETTLE_FILE)
+       [ -z "$(LIBNETTLE_SONAME)" ] \
+                || (cd $(DESTDIR)$(libdir) \
+               && ln -sf $(LIBNETTLE_FILE) $(LIBNETTLE_SONAME) \
+               && ln -sf $(LIBNETTLE_FILE) $(LIBNETTLE_FORLINK))
+
+install-shared-hogweed: $(LIBHOGWEED_FORLINK)
+       $(MKDIR_P) $(DESTDIR)$(libdir)
+       $(INSTALL_DATA) $(LIBHOGWEED_FORLINK) $(DESTDIR)$(libdir)/$(LIBHOGWEED_FILE)
+       [ -z "$(LIBHOGWEED_SONAME)" ] \
+                || (cd $(DESTDIR)$(libdir) \
+               && ln -sf $(LIBHOGWEED_FILE) $(LIBHOGWEED_SONAME) \
+               && ln -sf $(LIBHOGWEED_FILE) $(LIBHOGWEED_FORLINK))
+
+# I'd like to use makes VPATH search to locate the files to be
+# installed. But it seems most make programs don't set $<, $^, $? and
+# friends for ordinary explicit rules.
+
+install-info: nettle.info
+       $(MKDIR_P) $(DESTDIR)$(infodir)
+       f=nettle.info ; \
+       [ -f $$f ] || f="$(srcdir)/$$f" ; \
+       $(INSTALL_DATA) "$$f" $(DESTDIR)$(infodir) ; \
+       if (install-info --version && \
+           install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+         install-info --info-dir="$(DESTDIR)$(infodir)" "$$f" ; \
+       else : ; fi
+
+# NOTE: I'd like to use $^, but that's a GNU extension. $? should be
+# more portable, and equivalent for phony targets.
+install-headers: $(INSTALL_HEADERS)
+       $(MKDIR_P) $(DESTDIR)$(includedir)/nettle
+       for f in $(INSTALL_HEADERS) ; do \
+         if [ -f "$$f" ] ; then \
+           $(INSTALL_DATA) "$$f" $(DESTDIR)$(includedir)/nettle ; \
+         else \
+           $(INSTALL_DATA) "$(srcdir)/$$f" $(DESTDIR)$(includedir)/nettle ; \
+         fi ; done
+
+install-pkgconfig: $(PKGCONFIG_FILES)
+       $(MKDIR_P) $(DESTDIR)$(pkgconfigdir)
+       for f in $(PKGCONFIG_FILES) ; do \
+         $(INSTALL_DATA) "$$f" $(DESTDIR)$(pkgconfigdir) ; \
+       done
+
+# Uninstall
+uninstall-here: uninstall-info uninstall-headers uninstall-static \
+               uninstall-pkgconfig @IF_SHARED@ uninstall-shared
+
+uninstall-static:
+       for f in $(LIBTARGETS) ; do \
+         rm -f $(DESTDIR)$(libdir)/$$f ; \
+       done
+
+uninstall-headers:
+       for f in $(INSTALL_HEADERS) ; do \
+         rm -f $(DESTDIR)$(includedir)/nettle/$$f ; \
+       done
+
+uninstall-info:
+       if (install-info --version && \
+           install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+         install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)"/nettle.info ; \
+       else : ; fi
+       -rm -f $(DESTDIR)$(infodir)/nettle.info
+
+# FIXME: Leaves the links around
+uninstall-shared: uninstall-shared-nettle @IF_HOGWEED@ uninstall-shared-hogweed
+
+uninstall-shared-nettle:
+       rm -f $(DESTDIR)$(libdir)/$(LIBNETTLE_FILE)
+       [ -z "$(LIBNETTLE_SONAME)" ] \
+               || rm -f $(LIBNETTLE_SONAME) $(LIBNETTLE_FORLINK)
+
+uninstall-shared-hogweed:
+       rm -f $(DESTDIR)$(libdir)/$(LIBHOGWEED_FILE)
+       [ -z "$(LIBHOGWEED_SONAME)" ] \
+               || rm -f $(LIBHOGWEED_SONAME) $(LIBHOGWEED_FORLINK)
+
+uninstall-pkgconfig:
+       for f in $(PKGCONFIG_FILES) ; do \
+         rm -f $(DESTDIR)$(pkgconfigdir)/$$f ; \
+       done
+
+# Distribution
+distdir = $(PACKAGE_NAME)-$(PACKAGE_VERSION)
+top_distdir = $(distdir)
+
+# NOTE: We should handle both absolute and relative $destdir.
+
+distdir: $(DISTFILES)
+       rm -rf "$(distdir)"
+       mkdir "$(distdir)"
+       set -e; for f in $(DISTFILES) ; do \
+         if [ -f "$$f" ] ; then cp "$$f" "$(distdir)" ; \
+         else cp "$(srcdir)/$$f" "$(distdir)" ; \
+         fi ; \
+       done
+       set -e; for d in sparc32 sparc64 x86 x86_64; do \
+         mkdir "$(distdir)/$$d" ; \
+         cp $(srcdir)/$$d/*.asm $(srcdir)/$$d/*.m4 "$(distdir)/$$d" ; \
+       done
+       set -e; for d in $(SUBDIRS); do \
+         sd="$(distdir)/$$d" ; \
+         mkdir "$$sd" && $(MAKE) -C $$d distdir="`cd $$sd && pwd`" $@ ; \
+       done
+
+dist: distdir
+       tar cf - $(distdir) | gzip -c >$(distdir).tar.gz        
+       rm -rf $(distdir)
+
+rm_distcheck = test ! -d distcheck-tmp \
+           || { find distcheck-tmp -type d ! -perm -200 -exec chmod u+w {} ';' \
+                 && rm -fr distcheck-tmp; }; 
+
+distcheck: dist
+       $(rm_distcheck)
+       mkdir distcheck-tmp
+       gzip -d < $(distdir).tar.gz \
+         | { cd distcheck-tmp && tar xf - && chmod -R a-w $(distdir) ; }
+       mkdir distcheck-tmp/build
+       mkdir distcheck-tmp/install
+       cd distcheck-tmp/build && ../$(distdir)/configure --prefix="`cd ../install && pwd`"
+       cd distcheck-tmp/build && $(MAKE)
+       cd distcheck-tmp/build && $(MAKE) check
+       cd distcheck-tmp/build && $(MAKE) install
+       cd distcheck-tmp/build && $(MAKE) uninstall
+       cd distcheck-tmp && find install -type f -print > leftover-install-files
+       @test `cat distcheck-tmp/leftover-install-files | wc -l` -le 1  \
+         || { echo "ERROR: files left after uninstall:" ; \
+              cat distcheck-tmp/leftover-install-files ; \
+              exit 1; }
+       chmod -R a-w distcheck-tmp/install
+       mkdir distcheck-tmp/destdir
+       destdir="`cd distcheck-tmp/destdir && pwd`" \
+         && cd distcheck-tmp/build \
+         && $(MAKE) install DESTDIR="$$destdir" \
+         && $(MAKE) uninstall DESTDIR="$$destdir"
+       cd distcheck-tmp && find destdir -type f -print > leftover-destdir-files
+       @test `cat distcheck-tmp/leftover-destdir-files | wc -l` -le 1  \
+         || { echo "ERROR: destdir files left after uninstall:" ; \
+              cat distcheck-tmp/leftover-destdir-files ; \
+              exit 1; }        
+       cd distcheck-tmp/build && $(MAKE) dist
+       cd distcheck-tmp/build && rm *.gz
+       cd distcheck-tmp/build && $(MAKE) distclean
+       cd distcheck-tmp && find build -type f -print > leftover-build-files
+       @test `cat distcheck-tmp/leftover-build-files | wc -l` -eq 0  \
+         || { echo "ERROR: files left in build directory after distclean:" ; \
+              cat distcheck-tmp/leftover-build-files ; \
+              exit 1; }
+       $(rm_distcheck)
+
+clean-here:
+       -rm -f $(TARGETS) *.$(OBJEXT) *.p$(OBJEXT) *.s
+       -rm -rf .lib
+
+distclean-here: clean-here
+       -rm -f config.h stamp-h config.log config.status machine.m4 \
+       config.make config.m4 Makefile nettle-stdint.h \
+       nettle.pc hogweed.pc \
+       *.asm *.d
+
+maintainer-clean-here:
+       -rm -f $(DOCTARGETS) *.dvi *.ps
+
+tags-here:     
+       etags -o $(srcdir)/TAGS $(srcdir)/*.c $(srcdir)/*.h
+
+DEP_FILES = $(SOURCES:.c=.$(OBJEXT).d) $(SOURCES:.c=.p$(OBJEXT).d)
+@DEP_INCLUDE@ $(DEP_FILES)
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..9d3915f
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,501 @@
+NEWS for the 2.4 release
+
+       This is a bugfix release only. It turned out ripemd160 in the
+       2.3 release was broken on all big-endian systems, due to a
+       missing include of config.h. nettle-2.4 fixes this.
+
+       The library is intended to be binary compatible with
+       nettle-2.2 and nettle-2.3. The shared library names are
+       libnettle.so.4.3 and libhogweed.so.2.1, with sonames still
+       libnettle.so.4 and libhogweed.so.2.
+       
+NEWS for the 2.3 release
+
+       * Support for the ripemd-160 hash function.
+
+       * Generates and installs nettle.pc and hogweed.pc files, for
+          use with pkg-config. Feedback appreciated. For projects
+          using autoconf, the traditional non-pkg-config ways of
+          detecting libraries, and setting LIBS and LDFLAGS, is still
+          recommended.
+
+       * Fixed a bug which made the testsuite fail in the GCM test on
+         certain platforms. Should not affect any documented features
+         of the library.
+
+       * Reorganization of the code for the various Merkle-Damgård
+         hash functions. Some fields in the context structs for md4,
+         md5 and sha1 have been renamed, for consistency.
+         Applications should not peek inside these structs, and the
+         ABI is unchanged.
+         
+       * In the manual, fixed mis-placed const in certain function
+          prototypes.
+
+       The library is intended to be binary compatible with
+       nettle-2.2. The shared library names are libnettle.so.4.2 and
+       libhogweed.so.2.1, with sonames still libnettle.so.4 and
+       libhogweed.so.2.
+
+NEWS for the 2.2 release
+
+       Licensing change:
+       
+       * Relicensed as LGPL v2.1 or later (user's option).
+
+       * Replaced blowfish and serpent implementation. New code is
+          based on the LGPLed code in libgcrypt.
+
+       New features:
+
+       * Support for Galois/Counter Mode (GCM).
+
+       * New interface for enumerating (most) available algorithms,
+         contributed by Daniel Kahn Gillmor.
+
+       * New tool nettle-hash. Can generate hash digests using any
+         supported hash function, with output compatible with md5sum
+         and friends from GNU coreutils. Checking (like md5sum -c)
+         not yet implemented.
+
+       Bug fixes:
+
+       * The old serpent code had a byte order bug (introduced by
+         yours truly about ten years ago). New serpent implementation
+         does not interoperate with earlier versions of nettle.
+
+       * Fixed ABI-dependent libdir default for Linux-based systems
+         which do not follow the Linux File Hierarchy Standard, e.g.,
+         Debian GNU/Linux.
+
+       Optimizations:
+       
+       * x86_64 implemention of serpent.
+
+       * x86_64 implemention of camellia.
+
+       * Optimized memxor using word rather than byte operations.
+          Both generic C and x86_64 assembler.
+
+       * Eliminated a memcpy for in-place CBC decrypt.
+       
+       Miscellaneous:
+
+       * In command line tools, no longer support -? for requesting
+          help, since using it without shell quoting is a dangerous
+          habit. Use long option --help instead.
+
+       The shared library names are libnettle.so.4.1 and
+       libhogweed.so.2.1, with sonames libnettle.so.4 and
+       libhogweed.so.2.
+
+NEWS for the 2.1 release
+
+       *Important*: this release breaks source and binary
+       compatibility for the digital signature functions, and for the
+       DES and BLOWFISH ciphers which have weak keys.
+
+       Incompatible changes:
+
+       * The functions rsa_md5_sign, rsa_sha1_sign and
+          rsa_sha256_sign, and the corresponding _digest variants, now
+          have a return value which callers should check. The functions
+          return failure if the key is too small for the type of
+          signature.
+
+       * The functions dsa_sign and dsa_verify are renamed to
+          dsa_sha1_sign and dsa_sha1_verify. The _-digest variants are
+          renamed similarly. These functions now have a return value
+          which callers should check, and they return failure if the
+          number q is not of the appropriate size.
+
+       * The return value from des_set_key, des3_set_key and
+         blowfish_set_key now indicates whether or not the given key
+         is weak. But in either case, the key setup is done, and
+         applications that don't care about weak keys can ignore the
+         return value.
+
+         The incompatible part of this change is that enum des_error
+         and enum blowfish_error has been deleted, and so has the
+         status attribute in struct des_ctx, struct des3_ctx, and
+         struct blowfish_ctx.
+
+       The shared library names are libnettle.so.4.0 and
+       libhogweed.so.2.0, with sonames libnettle.so.4 and
+       libhogweed.so.2.
+
+       Other changes:
+
+       * Support for the Camellia block cipher, including an
+          assembler implementation for x86_32.
+
+       * New function aes_invert_key, useful for applications that
+         need both encryption and decryption using the same AES key.
+         
+       * des_set_key and des3_set_key no longer check the key parity
+         bits. Parity bits are silently ignored. A new function
+         des_check_parity is provided, for applications that care
+         about the DES parity bits.
+
+       * Support for sha224, sha384 and sha512.
+
+       * Support for digital signatures using rsa-sha512 and
+          dsa-sha256. Due to lack of official test vectors and interop
+          testing, this support should be considered somewhat
+          experimental.
+
+       * Key generation for RSA and DSA changed to use Maurer's
+         algorithm to generate provably prime numbers (as usual, the
+         mathematical proof does not guaranteee that the
+         implementation is bug free).
+         
+       * x86_64 assembler implementation actually included in the
+         distribution (was accidentally left out in nettle-2.0).
+
+       * Configure script now detects if the compiler uses a 32-bit
+          or 64-bit ABI on x86_64 (prevously did this for sparc only).
+          Also sets the default location for installing libraries
+          (libdir) depending on system type and the ABI used.
+
+       * Added the nettle and gmp libraries as dependencies when
+          linking shared library libhogweed.so. On systems using
+          shared libraries where such dependencies work (in
+          particular, ELF systems), it is sufficient to link
+          applications with -lhogweed. For static linking -lhogweed
+          -lnettle -lgmp is still required.
+
+       * The program pkcs1-conv is extended to also handle dsa keys.
+          Contributed by Magnus Holmgren.
+
+       * Slightly improved sha1 performance on x86.
+
+NEWS for the 2.0 release
+
+       This release breaks binary compatibility by splitting the
+       library into two. Some other smaller changes that are not
+       backwards compatible are also done at the same time.
+
+       * The nettle library is split into two libraries, libnettle
+         and libhogweed. libnettle contains the symmetric crypto
+         algorithms that don't depend on GMP, while libhogweed
+         contains the public key algorithms that depend on GMP.
+         Using a single library worked fine with static linking, but
+         not with dynamic linking. Consider an application that uses
+         nettle and which doesn't use any public key cryptography. If
+         this application is linked dynamically to nettle, it would
+         have to be linked also with GMP if and only if public key
+         support was enabled when the nettle library was installed.
+
+         The library names are libnettle.so.3.0 and
+         libhogweed.so.1.0, with sonames libnettle.so.3 and
+         libhogweed.so.1.
+
+       * Function typedefs have been changed to non-pointer types.
+         E.g, the
+
+           typedef void (nettle_hash_init_func *)(void *ctx);
+
+         of previous versions is replaced by
+
+           typedef void (nettle_hash_init_func)(void *ctx);
+
+         This makes it possible to use the type when declaring
+         functions, like
+
+           nettle_hash_init_func foo_hash_init;
+
+           void foo_hash_init(void *ctx) { ... }
+
+       * Changes to the yarrow256 interface. The automatic seed file
+         generation, and the seed_file member in struct
+         yarrow256_ctx, has been removed. To generate a new seed
+         file, use yarrow256_random. The function
+         yarrow256_force_reseed has been replaced by the two
+         functions yarrow256_fast_reseed and yarrow256_slow_reseed,
+         which were previously static. This interface change makes it
+         easier to mix in the current content of the seed file before
+         overwriting it with newly generated data.
+
+       Other changes:
+
+       * Nettle manual now contributed to the public domain, to
+          enable remixing into documentation of programs that use
+          Nettle.        
+
+       * The sexp-conv program preserves comments when using the
+         advanced syntax for output. Optionally locks the output
+         file.
+
+       * The base64 decoder recognizes ASCII FF (form feed) and VT
+          (vertical tab) as white space.
+
+       * New x86_64 implementations of AES and SHA1. On a 2.2 GHz
+          opteron, SHA1 was benchmarked at 250 MByte/s, and AES-128 at
+          110 MByte/s.
+
+       * Performance of AES increased by 20-30% on x86.
+
+       * New programs in the examples directory: erathostenes and
+          next-prime.
+       
+NEWS for the 1.15 release
+
+       Added support for PKCS#1 style RSA signatures using SHA256,
+       according to RFC 3447. Currently lacks interoperability
+       testing.
+       
+       Header files are now C++ aware, so C++ programs using Nettle
+       should now use plain
+
+         #include <nettle/foo.h>
+
+       rather than
+
+         #extern "C" {
+         #include <nettle/foo.h>
+         }
+
+       as was the recommendation for the previous version. This
+       breaks source-level compatibility with C++, even though
+       there's full binary compatibility.
+
+       The file rfc1750.txt (which is considered non-free by debian)
+       has been removed from the distribution. The file was used as input
+       for the Yarrow testcase, and has been replaced by the short
+       story "The Gold-bug" by Edgar Allan Poe. Anyway, RFC 1750 is
+       obsoleted by RFC 4086.
+
+       Fixes for Darwin shared library support, contributed by Grant
+       Robinsson.
+
+       Example programs now use a supplied getopt.c.
+
+       Configure tests for assemblers with a logarithmic .align
+       directive.
+
+       The library is intended to be upwards binary compatible with
+       earlier versions. The library name is libnettle.so.2.6, soname
+       is still libnettle.so.2.
+               
+NEWS for the 1.14 release
+
+       Experimental support for reading keys in PKCS#1 ASN1/DER
+       format, and a new command line tool pkcs1-conv.
+       
+       Improved MD5 performance on x86.
+
+       Fixed support for sparc64.
+
+       Reorganized AES code. Better performance for all three
+       implementations (C, x86 assembler, sparc assembler).
+
+       New sparc assembler for arcfour. Compared to the code
+       generated by gcc, the new code is about 25% faster on old
+       sparcs, and 6 times faster on ultrasparc.
+
+       Replaced the internal function nettle_mpz_from_octets with a
+       call to mpz_import, if available in the installed GMP library.
+
+       More Makefile fixes; it now seems to work to build with
+       the the make programs on Solaris and FreeBSD (although
+       --disable-dependency-tracking is required for the latter).
+
+       The library is intended to be binary compatible with earlier
+       versions. The library name is libnettle.so.2.5, soname is
+       still libnettle.so.2.
+
+NEWS for the 1.13 release
+
+       Fixed problem with broken m4 on bsd, which resulted in
+       corrupted x86 assembler for sha1.
+
+       Nettle probably works on windows: I've been able to cross
+       compile it with ./configure --host=i586-mingw32msvc (without
+       public-key support), and the testsuite binaries seem to run
+       fine in Wine.
+
+       Implemented CTR mode.
+
+       Improved sha1 performance on x86.
+
+       Configure check to figure out if symbols in assembler files
+       need a leading underscore.
+
+       Improved benchmark program. Displays cycles per byte and block,
+       and compares with openssl (if openssl is installed).
+       
+       Terminating newline in output from sexp-conv --hash.
+
+       The library is intended to be binary compatible with earlier
+       versions. The library name is libnettle.so.2.4. However, the
+       interface for the internal function _nettle_sha1_compress has
+       changed; any program that calls this function directly will
+       break.
+
+NEWS for the 1.12 release
+       
+       Fixed a bug in the configure script.
+
+       Updated the description of aes_set_encrypt_key and
+       aes_set_decrypt_key in the manual.
+
+NEWS for the 1.11 release
+
+       Nettle no longer uses automake. Side effects:
+
+         * Dependency tracking is enabled only for gcc-3 (help with
+           supporting dependency tracking with other compilers is
+           appreciated).
+         
+         * Makefile compatibility with make programs other than GNU
+           make is mostly unknown, please report any problems.
+
+       Support for arctwo.
+
+       Fixes to the libdes compatibility code. Declarations should
+       now match openssl/libdes better. des_cbc_cksum pads
+       input with NUL's, if it's not an integral number of blocks (in
+       general, such unreversible padding is a bad idea).
+
+       By default, also the static library is compiled as position
+       independent code. This is needed on some systems to make it
+       possible to link nettle into a dynamically loaded module. Use
+       the configure flag --disable-pic if this is not desired.
+
+       Stricter constness typing for the sexp_iterator_assoc and
+       sexp_iterator_check_types arguments.
+
+       Minor tweaks of arcfour on x86 cpu:s, to speed it up on older
+       x86 variants such as PII and PPro.
+
+       The shared library is intended to be binary compatible with
+       nettle-1.8 - nettle-1.10. Only the minor version number of the
+       shared library is increased. The soname is still
+       libnettle.so.2.
+
+NEWS for the 1.10 release
+
+       Nettle should now compile also on Tru64, Darwin, FreeBSD and
+       Windows. (The only tested windows build uses the rntcl rsh
+       wrapper to run the command line M$ C compiler "cl". See
+       http://pike.ida.liu.se for those tools, I don't know all
+       details about the Pike team's windows setup).
+
+       There are some known testsuite failures, on Windows and on one
+       of the xenofarm HPUX machines, see
+       http://www.lysator.liu.se/~nisse/xeno-lsh/latest.html. Help
+       tracking these down is appreciated.
+
+       There are no new features.
+       
+       This release is intended to be binary compatible with
+       nettle-1.8 and nettle-1.9.
+       
+NEWS for the 1.9 release
+
+       Optimized C implementation of arcfour. Optimized x86
+       implementations of arcfour and sha1.
+
+       Improved benchmark program.
+       
+       Fixed bug in the rsa-encrypt example program.
+
+       Fixed bug in make install, some of the header files were
+       forgotten.
+       
+       Portability fixes. Fixes to make Nettle compile on systems
+       without gmp. This version has been tested on GNU/Linux,
+       Solaris, HPUX and AIX.
+
+       The shared library is intended to be binary compatible with
+       nettle-1.8. Only the minor version number of the shared
+       library is increased.
+
+NEWS for the 1.8 release
+
+       New example programs, demonstrating encrypting and decrypting
+       files using RSA, and random sessions keys for bulk encryption
+       and message authentication.
+
+       Support for systems that don't have alloca. On such systems,
+       some of Nettle's functions have arbitrary limits applied to
+       their input.
+
+       Uses AX_CREATE_STDINT_H, to support systems without
+       inttypes.h.
+
+       Support for the md2 and md4 hash functions.
+        
+       New name mangling, to reduce the risk of link collisions. All
+       functions (except memxor) now use a nettle_ or _nettle_ prefix
+       when seen by the linker. For most functions, the header file
+       that declares a function also uses #define to provide a
+       shorter more readable name without the prefix.
+
+       The shared library soname for this version is libnettle.so.2.
+       
+NEWS for the 1.7 release
+
+       Implemented DSA.
+
+       Renamed RSA functions for consistency. Now it's
+       rsa_public_key_init, not rsa_init_public_key, etc.
+
+       Both RSA and DSA now have sign/verify functions that take the
+       hash digest as argument.
+
+       A rewritten and much more powerful sexp-conv program.
+
+       Other changes to the sexp code, in particular updating it to
+       the latest SPKI draft.
+
+       Building nettle as a shared library (ELF only) seems to work.
+       The version number is increased, so the library "soname" for
+       this release is "libnettle.so.1".
+
+       Bugfixes. Fixes for build and portability problems.
+
+NEWS for the 1.6 release
+
+       Optimized assembler implementations of aes, for sparc and x86.
+
+       The aes interface has changed slightly. The function
+       aes_set_key is no more. Instead one has to use
+       aes_set_encrypt_key or aes_set_decrypt_key. Sorry about that. 
+
+       New example programs, rsa-keygen, rsa-sign and rsa-verify,
+       located in the examples directory.
+
+       New configure option --enable-shared, which builds a shared
+       library. Not tested.
+
+       New experimental features, including sexp parsing and
+       formatting, and changes to base64 encoding and decoding. The
+       interfaces to these functions are subject to change, and are
+       documented only in the source code.
+       
+NEWS for the 1.5 release
+
+       RSA support. Key generation and signatures.
+       
+       Support for HMAC (RFC-2104).
+
+       An implementation of the Yarrow-256 PRNG.
+
+       New sections in the manual.
+       
+       Changed the interface for hash functions. The md5_digest
+       function is now equivalent to the old sequence of md5_final,
+       md5_digest, md5_init, and similarly for the other hashing
+       algorithms. This makes the interface simpler.
+
+NEWS for the 1.0 release
+
+       Fixed twofish bug spotted by Jean-Pierre Stierlin.
+
+       Added des3 and cbc.
+       
+       New RFC-1321-like interface in nettle/md5-compat.h, suggested
+       by Assar Westerlund.
+
+       New libdes-style compatibility interface in nettle/des-compat.h.
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..635794f
--- /dev/null
+++ b/README
@@ -0,0 +1,43 @@
+What is Nettle? A quote from the introduction in the Nettle Manual:
+
+  Nettle is a cryptographic library that is designed to fit easily in more
+  or less any context: In crypto toolkits for object-oriented languages
+  (C++, Python, Pike, ...), in applications like LSH or GNUPG, or even in
+  kernel space. In most contexts, you need more than the basic
+  cryptographic algorithms, you also need some way to keep track of available
+  algorithms, their properties and variants. You often have some algorithm
+  selection process, often dictated by a protocol you want to implement.
+  
+  And as the requirements of applications differ in subtle and not so
+  subtle ways, an API that fits one application well can be a pain to use
+  in a different context. And that is why there are so many different
+  cryptographic libraries around.
+  
+  Nettle tries to avoid this problem by doing one thing, the low-level
+  crypto stuff, and providing a simple but general interface to it.
+  In particular, Nettle doesn't do algorithm selection. It doesn't do
+  memory allocation. It doesn't do any I/O.
+  
+  The idea is that one can build several application and context specific
+  interfaces on top of Nettle, and share the code, test cases, benchmarks,
+  documentation, etc. Examples are the Nettle module for the Pike
+  language, and LSH, which both use an object-oriented abstraction on top
+  of the library.
+
+Nettle 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. See the file COPYING.LIB for details.
+
+Build nettle with the usual ./configure && make && make check && make
+install. Read the manual. Mail me if you have any questions or
+suggestions.
+
+You can also build Nettle from cvs, see
+http://www.lysator.liu.se/~nisse/nettle/ for current instructions.
+
+You may want to subscribe to the nettle-bugs mailing list. See
+<URL: http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs>.
+
+
+Happy hacking,
+/Niels Möller <nisse@lysator.liu.se>
diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..20b05a5
--- /dev/null
+++ b/TODO
@@ -0,0 +1,17 @@
+Public key support, analogous to that provided by RSAREF. Suggested by
+Dan Egnor. Signatures are done now, but RSA encryption is still
+missing. References:
+
+  http://download.gale.org/rsaref20.tar.Z
+  http://www.openssl.org/docs/crypto/evp.html
+  http://www.openssl.org/docs/crypto/rsa.html
+
+More feedback modes, in order of decreasing priority:  CBC-MAC, OFB,
+and CFB. Suggested by Rafael 'Dido' Sevilla. References:
+
+  http://csrc.nist.gov/encryption/modes/Recommendation/Modes01.pdf
+
+Valgrind reports errors on the des-compat test program. Investigate.
+
+The make rules for building position independent *_p.o files doesn't
+get dependencies right.
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644 (file)
index 0000000..3cf958b
--- /dev/null
@@ -0,0 +1,1062 @@
+dnl Try to detect the type of the third arg to getsockname() et al
+AC_DEFUN([LSH_TYPE_SOCKLEN_T],
+[AH_TEMPLATE([socklen_t], [Length type used by getsockopt])
+AC_CACHE_CHECK([for socklen_t in sys/socket.h], ac_cv_type_socklen_t,
+[AC_EGREP_HEADER(socklen_t, sys/socket.h,
+  [ac_cv_type_socklen_t=yes], [ac_cv_type_socklen_t=no])])
+if test $ac_cv_type_socklen_t = no; then
+        AC_MSG_CHECKING(for AIX)
+        AC_EGREP_CPP(yes, [
+#ifdef _AIX
+ yes
+#endif
+],[
+AC_MSG_RESULT(yes)
+AC_DEFINE(socklen_t, size_t)
+],[
+AC_MSG_RESULT(no)
+AC_DEFINE(socklen_t, int)
+])
+fi
+])
+
+dnl Choose cc flags for compiling position independent code
+dnl FIXME: Doesn't do the right thing when crosscompiling.
+AC_DEFUN([LSH_CCPIC],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_MSG_CHECKING(CCPIC)
+AC_CACHE_VAL(lsh_cv_sys_ccpic,[
+  if test -z "$CCPIC" ; then
+    if test "$GCC" = yes ; then
+      case "$host_os" in
+       bsdi4.*)        CCPIC="-fPIC" ;;
+       bsdi*)          CCPIC="" ;;
+       darwin*)        CCPIC="-fPIC" ;;
+       # Could also use -fpic, depending on the number of symbol references
+       solaris*)       CCPIC="-fPIC" ;;
+       cygwin*)        CCPIC="" ;;
+       mingw32*)       CCPIC="" ;;
+       *)              CCPIC="-fpic" ;;
+      esac
+    else
+      case "$host_os" in
+       darwin*)        CCPIC="-fPIC" ;;
+        irix*)         CCPIC="-share" ;;
+       hpux*)          CCPIC="+z"; ;;
+       *freebsd*)      CCPIC="-fpic" ;;
+       sco*|sysv4.*)   CCPIC="-KPIC -dy -Bdynamic" ;;
+       solaris*)       CCPIC="-KPIC -Bdynamic" ;;
+       winnt*)         CCPIC="-shared" ;;
+       *)              CCPIC="" ;;
+      esac
+    fi
+  fi
+  OLD_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $CCPIC"
+  AC_TRY_COMPILE([], [exit(0);],
+    lsh_cv_sys_ccpic="$CCPIC", lsh_cv_sys_ccpic='')
+  CFLAGS="$OLD_CFLAGS"
+])
+CCPIC="$lsh_cv_sys_ccpic"
+AC_MSG_RESULT($CCPIC)
+AC_SUBST([CCPIC])])
+
+dnl LSH_PATH_ADD(path-id, directory)
+AC_DEFUN([LSH_PATH_ADD],
+[AC_MSG_CHECKING($2)
+ac_exists=no
+if test -d "$2/." ; then
+  ac_real_dir=`cd $2 && pwd`
+  if test -n "$ac_real_dir" ; then
+    ac_exists=yes
+    for old in $1_REAL_DIRS ; do
+      ac_found=no
+      if test x$ac_real_dir = x$old ; then
+        ac_found=yes;
+       break;
+      fi
+    done
+    if test $ac_found = yes ; then
+      AC_MSG_RESULT(already added)
+    else
+      AC_MSG_RESULT(added)
+      # LDFLAGS="$LDFLAGS -L $2"
+      $1_REAL_DIRS="$ac_real_dir [$]$1_REAL_DIRS"
+      $1_DIRS="$2 [$]$1_DIRS"
+    fi
+  fi
+fi
+if test $ac_exists = no ; then
+  AC_MSG_RESULT(not found)
+fi
+])
+
+dnl LSH_RPATH_ADD(dir)
+AC_DEFUN([LSH_RPATH_ADD], [LSH_PATH_ADD(RPATH_CANDIDATE, $1)])
+
+dnl LSH_RPATH_INIT(candidates)
+AC_DEFUN([LSH_RPATH_INIT],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_MSG_CHECKING([for -R flag])
+RPATHFLAG=''
+case "$host_os" in
+  osf1*)               RPATHFLAG="-rpath " ;;
+  irix6.*|irix5.*)     RPATHFLAG="-rpath " ;;
+  solaris*)
+    if test "$TCC" = "yes"; then
+      # tcc doesn't know about -R
+      RPATHFLAG="-Wl,-R,"
+    else
+      RPATHFLAG=-R
+    fi
+    ;;
+  linux*)              RPATHFLAG="-Wl,-rpath," ;;
+  *)                   RPATHFLAG="" ;;
+esac
+
+if test x$RPATHFLAG = x ; then
+  AC_MSG_RESULT(none)
+else
+  AC_MSG_RESULT([using $RPATHFLAG])
+fi
+
+RPATH_CANDIDATE_REAL_DIRS=''
+RPATH_CANDIDATE_DIRS=''
+
+AC_MSG_RESULT([Searching for libraries])
+
+for d in $1 ; do
+  LSH_RPATH_ADD($d)
+done
+])    
+
+dnl Try to execute a main program, and if it fails, try adding some
+dnl -R flag.
+dnl LSH_RPATH_FIX
+AC_DEFUN([LSH_RPATH_FIX],
+[if test $cross_compiling = no -a "x$RPATHFLAG" != x ; then
+  ac_success=no
+  AC_TRY_RUN([int main(int argc, char **argv) { return 0; }],
+    ac_success=yes, ac_success=no, :)
+  
+  if test $ac_success = no ; then
+    AC_MSG_CHECKING([Running simple test program failed. Trying -R flags])
+dnl echo RPATH_CANDIDATE_DIRS = $RPATH_CANDIDATE_DIRS
+    ac_remaining_dirs=''
+    ac_rpath_save_LDFLAGS="$LDFLAGS"
+    for d in $RPATH_CANDIDATE_DIRS ; do
+      if test $ac_success = yes ; then
+       ac_remaining_dirs="$ac_remaining_dirs $d"
+      else
+       LDFLAGS="$RPATHFLAG$d $LDFLAGS"
+dnl echo LDFLAGS = $LDFLAGS
+       AC_TRY_RUN([int main(int argc, char **argv) { return 0; }],
+         [ac_success=yes
+         ac_rpath_save_LDFLAGS="$LDFLAGS"
+         AC_MSG_RESULT([adding $RPATHFLAG$d])
+         ],
+         [ac_remaining_dirs="$ac_remaining_dirs $d"], :)
+       LDFLAGS="$ac_rpath_save_LDFLAGS"
+      fi
+    done
+    RPATH_CANDIDATE_DIRS=$ac_remaining_dirs
+  fi
+  if test $ac_success = no ; then
+    AC_MSG_RESULT(failed)
+  fi
+fi
+])
+
+dnl Like AC_CHECK_LIB, but uses $KRB_LIBS rather than $LIBS.
+dnl LSH_CHECK_KRB_LIB(LIBRARY, FUNCTION, [, ACTION-IF-FOUND [,
+dnl                  ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]])
+
+AC_DEFUN([LSH_CHECK_KRB_LIB],
+[AC_CHECK_LIB([$1], [$2],
+  ifelse([$3], ,
+      [[ac_tr_lib=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+           -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+        AC_DEFINE_UNQUOTED($ac_tr_lib)
+        KRB_LIBS="-l$1 $KRB_LIBS"
+      ]], [$3]),
+  ifelse([$4], , , [$4
+])dnl
+, [$5 $KRB_LIBS])
+])
+
+dnl LSH_LIB_ARGP(ACTION-IF-OK, ACTION-IF-BAD)
+AC_DEFUN([LSH_LIB_ARGP],
+[ ac_argp_save_LIBS="$LIBS"
+  ac_argp_save_LDFLAGS="$LDFLAGS"
+  ac_argp_ok=no
+  # First check if we can link with argp.
+  AC_SEARCH_LIBS(argp_parse, argp,
+  [ LSH_RPATH_FIX
+    AC_CACHE_CHECK([for working argp],
+      lsh_cv_lib_argp_works,
+      [ AC_TRY_RUN(
+[#include <argp.h>
+#include <stdlib.h>
+
+static const struct argp_option
+options[] =
+{
+  { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+struct child_state
+{
+  int n;
+};
+
+static error_t
+child_parser(int key, char *arg, struct argp_state *state)
+{
+  struct child_state *input = (struct child_state *) state->input;
+  
+  switch(key)
+    {
+    default:
+      return ARGP_ERR_UNKNOWN;
+    case ARGP_KEY_END:
+      if (!input->n)
+       input->n = 1;
+      break;
+    }
+  return 0;
+}
+
+const struct argp child_argp =
+{
+  options,
+  child_parser,
+  NULL, NULL, NULL, NULL, NULL
+};
+
+struct main_state
+{
+  struct child_state child;
+  int m;
+};
+
+static error_t
+main_parser(int key, char *arg, struct argp_state *state)
+{
+  struct main_state *input = (struct main_state *) state->input;
+
+  switch(key)
+    {
+    default:
+      return ARGP_ERR_UNKNOWN;
+    case ARGP_KEY_INIT:
+      state->child_inputs[0] = &input->child;
+      break;
+    case ARGP_KEY_END:
+      if (!input->m)
+       input->m = input->child.n;
+      
+      break;
+    }
+  return 0;
+}
+
+static const struct argp_child
+main_children[] =
+{
+  { &child_argp, 0, "", 0 },
+  { NULL, 0, NULL, 0}
+};
+
+static const struct argp
+main_argp =
+{ options, main_parser, 
+  NULL,
+  NULL,
+  main_children,
+  NULL, NULL
+};
+
+int main(int argc, char **argv)
+{
+  struct main_state input = { { 0 }, 0 };
+  char *v[2] = { "foo", NULL };
+
+  argp_parse(&main_argp, 1, v, 0, NULL, &input);
+
+  if ( (input.m == 1) && (input.child.n == 1) )
+    return 0;
+  else
+    return 1;
+}
+], lsh_cv_lib_argp_works=yes,
+   lsh_cv_lib_argp_works=no,
+   lsh_cv_lib_argp_works=no)])
+
+  if test x$lsh_cv_lib_argp_works = xyes ; then
+    ac_argp_ok=yes
+  else
+    # Reset link flags
+    LIBS="$ac_argp_save_LIBS"
+    LDFLAGS="$ac_argp_save_LDFLAGS"
+  fi])
+
+  if test x$ac_argp_ok = xyes ; then
+    ifelse([$1],, true, [$1])
+  else
+    ifelse([$2],, true, [$2])
+  fi   
+])
+
+dnl LSH_GCC_ATTRIBUTES
+dnl Check for gcc's __attribute__ construction
+
+AC_DEFUN([LSH_GCC_ATTRIBUTES],
+[AC_CACHE_CHECK(for __attribute__,
+              lsh_cv_c_attribute,
+[ AC_TRY_COMPILE([
+#include <stdlib.h>
+
+static void foo(void) __attribute__ ((noreturn));
+
+static void __attribute__ ((noreturn))
+foo(void)
+{
+  exit(1);
+}
+],[],
+lsh_cv_c_attribute=yes,
+lsh_cv_c_attribute=no)])
+
+AH_TEMPLATE([HAVE_GCC_ATTRIBUTE], [Define if the compiler understands __attribute__])
+if test "x$lsh_cv_c_attribute" = "xyes"; then
+  AC_DEFINE(HAVE_GCC_ATTRIBUTE)
+fi
+
+AH_BOTTOM(
+[#if __GNUC__ && HAVE_GCC_ATTRIBUTE
+# define NORETURN __attribute__ ((__noreturn__))
+# define PRINTF_STYLE(f, a) __attribute__ ((__format__ (__printf__, f, a)))
+# define UNUSED __attribute__ ((__unused__))
+#else
+# define NORETURN
+# define PRINTF_STYLE(f, a)
+# define UNUSED
+#endif
+])])
+
+# Check for alloca, and include the standard blurb in config.h
+AC_DEFUN([LSH_FUNC_ALLOCA],
+[AC_FUNC_ALLOCA
+AC_CHECK_HEADERS([malloc.h])
+AH_BOTTOM(
+[/* AIX requires this to be the first thing in the file.  */
+#ifndef __GNUC__
+# if HAVE_ALLOCA_H
+#  include <alloca.h>
+# else
+#  ifdef _AIX
+ #pragma alloca
+#  else
+#   ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+#   endif
+#  endif
+/* Needed for alloca on windows */
+#  if HAVE_MALLOC_H
+#   include <malloc.h>
+#  endif
+# endif
+#else /* defined __GNUC__ */
+# if HAVE_ALLOCA_H
+#  include <alloca.h>
+# endif
+#endif
+])])
+
+AC_DEFUN([LSH_FUNC_STRERROR],
+[AC_CHECK_FUNCS(strerror)
+AH_BOTTOM(
+[#if HAVE_STRERROR
+#define STRERROR strerror
+#else
+#define STRERROR(x) (sys_errlist[x])
+#endif
+])])
+
+AC_DEFUN([LSH_FUNC_STRSIGNAL],
+[AC_CHECK_FUNCS(strsignal)
+AC_CHECK_DECLS([sys_siglist, _sys_siglist])
+AH_BOTTOM(
+[#if HAVE_STRSIGNAL
+# define STRSIGNAL strsignal
+#else /* !HAVE_STRSIGNAL */
+# if HAVE_DECL_SYS_SIGLIST
+#  define STRSIGNAL(x) (sys_siglist[x])
+# else
+#  if HAVE_DECL__SYS_SIGLIST
+#   define STRSIGNAL(x) (_sys_siglist[x])
+#  else
+#   define STRSIGNAL(x) "Unknown signal"
+#   if __GNUC__
+#    warning Using dummy STRSIGNAL
+#   endif
+#  endif
+# endif
+#endif /* !HAVE_STRSIGNAL */
+])])
+
+dnl LSH_MAKE_CONDITIONAL(symbol, test)
+AC_DEFUN([LSH_MAKE_CONDITIONAL],
+[if $2 ; then
+  IF_$1=''
+  UNLESS_$1='# '
+else
+  IF_$1='# '
+  UNLESS_$1=''
+fi 
+AC_SUBST(IF_$1)
+AC_SUBST(UNLESS_$1)])
+
+dnl LSH_DEPENDENCY_TRACKING
+
+dnl Defines compiler flags DEP_FLAGS to generate dependency
+dnl information, and DEP_PROCESS that is any shell commands needed for
+dnl massaging the dependency information further. Dependencies are
+dnl generated as a side effect of compilation. Dependency files
+dnl themselves are not treated as targets.
+
+AC_DEFUN([LSH_DEPENDENCY_TRACKING],
+[AC_ARG_ENABLE(dependency_tracking,
+  AC_HELP_STRING([--disable-dependency-tracking],
+    [Disable dependency tracking. Dependency tracking doesn't work with BSD make]),,
+  [enable_dependency_tracking=yes])
+
+DEP_FLAGS=''
+DEP_PROCESS='true'
+if test x$enable_dependency_tracking = xyes ; then
+  if test x$GCC = xyes ; then
+    gcc_version=`gcc --version | head -1`
+    case "$gcc_version" in
+      2.*|*[[!0-9.]]2.*)
+        enable_dependency_tracking=no
+        AC_MSG_WARN([Dependency tracking disabled, gcc-3.x is needed])
+      ;;
+      *)
+        DEP_FLAGS='-MT $[]@ -MD -MP -MF $[]@.d'
+        DEP_PROCESS='true'
+      ;;
+    esac
+  else
+    enable_dependency_tracking=no
+    AC_MSG_WARN([Dependency tracking disabled])
+  fi
+fi
+
+if test x$enable_dependency_tracking = xyes ; then
+  DEP_INCLUDE='include '
+else
+  DEP_INCLUDE='# '
+fi
+
+AC_SUBST([DEP_INCLUDE])
+AC_SUBST([DEP_FLAGS])
+AC_SUBST([DEP_PROCESS])])
+
+dnl  GMP_TRY_ASSEMBLE(asm-code,[action-success][,action-fail])
+dnl  ----------------------------------------------------------
+dnl  Attempt to assemble the given code.
+dnl  Do "action-success" if this succeeds, "action-fail" if not.
+dnl
+dnl  conftest.o and conftest.out are available for inspection in
+dnl  "action-success".  If either action does a "break" out of a loop then
+dnl  an explicit "rm -f conftest*" will be necessary.
+dnl
+dnl  This is not unlike AC_TRY_COMPILE, but there's no default includes or
+dnl  anything in "asm-code", everything wanted must be given explicitly.
+
+AC_DEFUN([GMP_TRY_ASSEMBLE],
+[cat >conftest.s <<EOF
+[$1]
+EOF
+gmp_assemble="$CC $CFLAGS $CPPFLAGS -c conftest.s >conftest.out 2>&1"
+if AC_TRY_EVAL(gmp_assemble); then
+  cat conftest.out >&AC_FD_CC
+  ifelse([$2],,:,[$2])
+else
+  cat conftest.out >&AC_FD_CC
+  echo "configure: failed program was:" >&AC_FD_CC
+  cat conftest.s >&AC_FD_CC
+  ifelse([$3],,:,[$3])
+fi
+rm -f conftest*
+])
+
+dnl @synopsis AX_CREATE_STDINT_H [( HEADER-TO-GENERATE [, HEADERS-TO-CHECK])]
+dnl
+dnl the "ISO C9X: 7.18 Integer types <stdint.h>" section requires the
+dnl existence of an include file <stdint.h> that defines a set of 
+dnl typedefs, especially uint8_t,int32_t,uintptr_t.
+dnl Many older installations will not provide this file, but some will
+dnl have the very same definitions in <inttypes.h>. In other enviroments
+dnl we can use the inet-types in <sys/types.h> which would define the
+dnl typedefs int8_t and u_int8_t respectivly.
+dnl
+dnl This macros will create a local "_stdint.h" or the headerfile given as 
+dnl an argument. In many cases that file will just "#include <stdint.h>" 
+dnl or "#include <inttypes.h>", while in other environments it will provide 
+dnl the set of basic 'stdint's definitions/typedefs: 
+dnl   int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,intptr_t,uintptr_t
+dnl   int_least32_t.. int_fast32_t.. intmax_t
+dnl which may or may not rely on the definitions of other files,
+dnl or using the AC_CHECK_SIZEOF macro to determine the actual
+dnl sizeof each type.
+dnl
+dnl if your header files require the stdint-types you will want to create an
+dnl installable file mylib-int.h that all your other installable header
+dnl may include. So if you have a library package named "mylib", just use
+dnl      AX_CREATE_STDINT_H(mylib-int.h) 
+dnl in configure.ac and go to install that very header file in Makefile.am
+dnl along with the other headers (mylib.h) - and the mylib-specific headers
+dnl can simply use "#include <mylib-int.h>" to obtain the stdint-types.
+dnl
+dnl Remember, if the system already had a valid <stdint.h>, the generated
+dnl file will include it directly. No need for fuzzy HAVE_STDINT_H things...
+dnl
+dnl @, (status: used on new platforms) (see http://ac-archive.sf.net/gstdint/)
+dnl @version $Id: aclocal.m4,v 1.1 2007-05-03 20:49:15 nisse Exp $
+dnl @author  Guido Draheim <guidod@gmx.de> 
+
+AC_DEFUN([AX_CREATE_STDINT_H],
+[# ------ AX CREATE STDINT H -------------------------------------
+AC_MSG_CHECKING([for stdint types])
+ac_stdint_h=`echo ifelse($1, , _stdint.h, $1)`
+# try to shortcircuit - if the default include path of the compiler
+# can find a "stdint.h" header then we assume that all compilers can.
+AC_CACHE_VAL([ac_cv_header_stdint_t],[
+old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS=""
+old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS=""
+old_CFLAGS="$CFLAGS"     ; CFLAGS=""
+AC_TRY_COMPILE([#include <stdint.h>],[int_least32_t v = 0;],
+[ac_cv_stdint_result="(assuming C99 compatible system)"
+ ac_cv_header_stdint_t="stdint.h"; ],
+[ac_cv_header_stdint_t=""])
+CXXFLAGS="$old_CXXFLAGS"
+CPPFLAGS="$old_CPPFLAGS"
+CFLAGS="$old_CFLAGS" ])
+
+v="... $ac_cv_header_stdint_h"
+if test "$ac_stdint_h" = "stdint.h" ; then
+ AC_MSG_RESULT([(are you sure you want them in ./stdint.h?)])
+elif test "$ac_stdint_h" = "inttypes.h" ; then
+ AC_MSG_RESULT([(are you sure you want them in ./inttypes.h?)])
+elif test "_$ac_cv_header_stdint_t" = "_" ; then
+ AC_MSG_RESULT([(putting them into $ac_stdint_h)$v])
+else
+ ac_cv_header_stdint="$ac_cv_header_stdint_t"
+ AC_MSG_RESULT([$ac_cv_header_stdint (shortcircuit)])
+fi
+
+if test "_$ac_cv_header_stdint_t" = "_" ; then # can not shortcircuit..
+
+dnl .....intro message done, now do a few system checks.....
+dnl btw, all CHECK_TYPE macros do automatically "DEFINE" a type, therefore
+dnl we use the autoconf implementation detail _AC CHECK_TYPE_NEW instead
+
+inttype_headers=`echo $2 | sed -e 's/,/ /g'`
+
+ac_cv_stdint_result="(no helpful system typedefs seen)"
+AC_CACHE_CHECK([for stdint uintptr_t], [ac_cv_header_stdint_x],[
+ ac_cv_header_stdint_x="" # the 1997 typedefs (inttypes.h)
+  AC_MSG_RESULT([(..)])
+  for i in stdint.h inttypes.h sys/inttypes.h $inttype_headers ; do
+   unset ac_cv_type_uintptr_t 
+   unset ac_cv_type_uint64_t
+   _AC_CHECK_TYPE_NEW(uintptr_t,[ac_cv_header_stdint_x=$i],dnl
+     continue,[#include <$i>])
+   AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>])
+   ac_cv_stdint_result="(seen uintptr_t$and64 in $i)"
+   break;
+  done
+  AC_MSG_CHECKING([for stdint uintptr_t])
+ ])
+
+if test "_$ac_cv_header_stdint_x" = "_" ; then
+AC_CACHE_CHECK([for stdint uint32_t], [ac_cv_header_stdint_o],[
+ ac_cv_header_stdint_o="" # the 1995 typedefs (sys/inttypes.h)
+  AC_MSG_RESULT([(..)])
+  for i in inttypes.h sys/inttypes.h stdint.h $inttype_headers ; do
+   unset ac_cv_type_uint32_t
+   unset ac_cv_type_uint64_t
+   AC_CHECK_TYPE(uint32_t,[ac_cv_header_stdint_o=$i],dnl
+     continue,[#include <$i>])
+   AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>])
+   ac_cv_stdint_result="(seen uint32_t$and64 in $i)"
+   break;
+  done
+  AC_MSG_CHECKING([for stdint uint32_t])
+ ])
+fi
+
+if test "_$ac_cv_header_stdint_x" = "_" ; then
+if test "_$ac_cv_header_stdint_o" = "_" ; then
+AC_CACHE_CHECK([for stdint u_int32_t], [ac_cv_header_stdint_u],[
+ ac_cv_header_stdint_u="" # the BSD typedefs (sys/types.h)
+  AC_MSG_RESULT([(..)])
+  for i in sys/types.h inttypes.h sys/inttypes.h $inttype_headers ; do
+   unset ac_cv_type_u_int32_t
+   unset ac_cv_type_u_int64_t
+   AC_CHECK_TYPE(u_int32_t,[ac_cv_header_stdint_u=$i],dnl
+     continue,[#include <$i>])
+   AC_CHECK_TYPE(u_int64_t,[and64="/u_int64_t"],[and64=""],[#include<$i>])
+   ac_cv_stdint_result="(seen u_int32_t$and64 in $i)"
+   break;
+  done
+  AC_MSG_CHECKING([for stdint u_int32_t])
+ ])
+fi fi
+
+dnl if there was no good C99 header file, do some typedef checks...
+if test "_$ac_cv_header_stdint_x" = "_" ; then
+   AC_MSG_CHECKING([for stdint datatype model])
+   AC_MSG_RESULT([(..)])
+   AC_CHECK_SIZEOF(char)
+   AC_CHECK_SIZEOF(short)
+   AC_CHECK_SIZEOF(int)
+   AC_CHECK_SIZEOF(long)
+   AC_CHECK_SIZEOF(void*)
+   ac_cv_stdint_char_model=""
+   ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_char"
+   ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_short"
+   ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_int"
+   ac_cv_stdint_long_model=""
+   ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_int"
+   ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_long"
+   ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_voidp"
+   name="$ac_cv_stdint_long_model"
+   case "$ac_cv_stdint_char_model/$ac_cv_stdint_long_model" in
+    122/242)     name="$name,  IP16 (standard 16bit machine)" ;;
+    122/244)     name="$name,  LP32 (standard 32bit mac/win)" ;;
+    122/*)       name="$name        (unusual int16 model)" ;; 
+    124/444)     name="$name, ILP32 (standard 32bit unixish)" ;;
+    124/488)     name="$name,  LP64 (standard 64bit unixish)" ;;
+    124/448)     name="$name, LLP64 (unusual  64bit unixish)" ;;
+    124/*)       name="$name        (unusual int32 model)" ;; 
+    128/888)     name="$name, ILP64 (unusual  64bit numeric)" ;;
+    128/*)       name="$name        (unusual int64 model)" ;; 
+    222/*|444/*) name="$name        (unusual dsptype)" ;;
+     *)          name="$name        (very unusal model)" ;;
+   esac
+   AC_MSG_RESULT([combined for stdint datatype model...  $name])
+fi
+
+if test "_$ac_cv_header_stdint_x" != "_" ; then
+   ac_cv_header_stdint="$ac_cv_header_stdint_x"
+elif  test "_$ac_cv_header_stdint_o" != "_" ; then
+   ac_cv_header_stdint="$ac_cv_header_stdint_o"
+elif  test "_$ac_cv_header_stdint_u" != "_" ; then
+   ac_cv_header_stdint="$ac_cv_header_stdint_u"
+else
+   ac_cv_header_stdint="stddef.h"
+fi
+
+AC_MSG_CHECKING([for extra inttypes in chosen header])
+AC_MSG_RESULT([($ac_cv_header_stdint)])
+dnl see if int_least and int_fast types are present in _this_ header.
+unset ac_cv_type_int_least32_t
+unset ac_cv_type_int_fast32_t
+AC_CHECK_TYPE(int_least32_t,,,[#include <$ac_cv_header_stdint>])
+AC_CHECK_TYPE(int_fast32_t,,,[#include<$ac_cv_header_stdint>])
+AC_CHECK_TYPE(intmax_t,,,[#include <$ac_cv_header_stdint>])
+
+fi # shortcircut to system "stdint.h"
+# ------------------ PREPARE VARIABLES ------------------------------
+if test "$GCC" = "yes" ; then
+ac_cv_stdint_message="using gnu compiler "`$CC --version | head -1` 
+else
+ac_cv_stdint_message="using $CC"
+fi
+
+AC_MSG_RESULT([make use of $ac_cv_header_stdint in $ac_stdint_h dnl
+$ac_cv_stdint_result])
+
+# ----------------- DONE inttypes.h checks START header -------------
+AC_CONFIG_COMMANDS([$ac_stdint_h],[
+AC_MSG_NOTICE(creating $ac_stdint_h : $_ac_stdint_h)
+ac_stdint=$tmp/_stdint.h
+
+echo "#ifndef" $_ac_stdint_h >$ac_stdint
+echo "#define" $_ac_stdint_h "1" >>$ac_stdint
+echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint
+echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint
+echo "/* generated $ac_cv_stdint_message */" >>$ac_stdint
+if test "_$ac_cv_header_stdint_t" != "_" ; then 
+echo "#define _STDINT_HAVE_STDINT_H" "1" >>$ac_stdint
+fi
+
+cat >>$ac_stdint <<STDINT_EOF
+
+/* ................... shortcircuit part ........................... */
+
+#if defined HAVE_STDINT_H || defined _STDINT_HAVE_STDINT_H
+#include <stdint.h>
+#else
+#include <stddef.h>
+
+/* .................... configured part ............................ */
+
+STDINT_EOF
+
+echo "/* whether we have a C99 compatible stdint header file */" >>$ac_stdint
+if test "_$ac_cv_header_stdint_x" != "_" ; then
+  ac_header="$ac_cv_header_stdint_x"
+  echo "#define _STDINT_HEADER_INTPTR" '"'"$ac_header"'"' >>$ac_stdint
+else
+  echo "/* #undef _STDINT_HEADER_INTPTR */" >>$ac_stdint
+fi
+
+echo "/* whether we have a C96 compatible inttypes header file */" >>$ac_stdint
+if  test "_$ac_cv_header_stdint_o" != "_" ; then
+  ac_header="$ac_cv_header_stdint_o"
+  echo "#define _STDINT_HEADER_UINT32" '"'"$ac_header"'"' >>$ac_stdint
+else
+  echo "/* #undef _STDINT_HEADER_UINT32 */" >>$ac_stdint
+fi
+
+echo "/* whether we have a BSD compatible inet types header */" >>$ac_stdint
+if  test "_$ac_cv_header_stdint_u" != "_" ; then
+  ac_header="$ac_cv_header_stdint_u"
+  echo "#define _STDINT_HEADER_U_INT32" '"'"$ac_header"'"' >>$ac_stdint
+else
+  echo "/* #undef _STDINT_HEADER_U_INT32 */" >>$ac_stdint
+fi
+
+echo "" >>$ac_stdint
+
+if test "_$ac_header" != "_" ; then if test "$ac_header" != "stddef.h" ; then
+  echo "#include <$ac_header>" >>$ac_stdint
+  echo "" >>$ac_stdint
+fi fi
+
+echo "/* which 64bit typedef has been found */" >>$ac_stdint
+if test "$ac_cv_type_uint64_t" = "yes" ; then
+echo "#define   _STDINT_HAVE_UINT64_T" "1"  >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_UINT64_T */" >>$ac_stdint
+fi
+if test "$ac_cv_type_u_int64_t" = "yes" ; then
+echo "#define   _STDINT_HAVE_U_INT64_T" "1"  >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_U_INT64_T */" >>$ac_stdint
+fi
+echo "" >>$ac_stdint
+
+echo "/* which type model has been detected */" >>$ac_stdint
+if test "_$ac_cv_stdint_char_model" != "_" ; then
+echo "#define   _STDINT_CHAR_MODEL" "$ac_cv_stdint_char_model" >>$ac_stdint
+echo "#define   _STDINT_LONG_MODEL" "$ac_cv_stdint_long_model" >>$ac_stdint
+else
+echo "/* #undef _STDINT_CHAR_MODEL // skipped */" >>$ac_stdint
+echo "/* #undef _STDINT_LONG_MODEL // skipped */" >>$ac_stdint
+fi
+echo "" >>$ac_stdint
+
+echo "/* whether int_least types were detected */" >>$ac_stdint
+if test "$ac_cv_type_int_least32_t" = "yes"; then
+echo "#define   _STDINT_HAVE_INT_LEAST32_T" "1"  >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_INT_LEAST32_T */" >>$ac_stdint
+fi
+echo "/* whether int_fast types were detected */" >>$ac_stdint
+if test "$ac_cv_type_int_fast32_t" = "yes"; then
+echo "#define   _STDINT_HAVE_INT_FAST32_T" "1" >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_INT_FAST32_T */" >>$ac_stdint
+fi
+echo "/* whether intmax_t type was detected */" >>$ac_stdint
+if test "$ac_cv_type_intmax_t" = "yes"; then
+echo "#define   _STDINT_HAVE_INTMAX_T" "1" >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_INTMAX_T */" >>$ac_stdint
+fi
+echo "" >>$ac_stdint
+
+  cat >>$ac_stdint <<STDINT_EOF
+/* .................... detections part ............................ */
+
+/* whether we need to define bitspecific types from compiler base types */
+#ifndef _STDINT_HEADER_INTPTR
+#ifndef _STDINT_HEADER_UINT32
+#ifndef _STDINT_HEADER_U_INT32
+#define _STDINT_NEED_INT_MODEL_T
+#else
+#define _STDINT_HAVE_U_INT_TYPES
+#endif
+#endif
+#endif
+
+#ifdef _STDINT_HAVE_U_INT_TYPES
+#undef _STDINT_NEED_INT_MODEL_T
+#endif
+
+#ifdef  _STDINT_CHAR_MODEL
+#if     _STDINT_CHAR_MODEL+0 == 122 || _STDINT_CHAR_MODEL+0 == 124
+#ifndef _STDINT_BYTE_MODEL
+#define _STDINT_BYTE_MODEL 12
+#endif
+#endif
+#endif
+
+#ifndef _STDINT_HAVE_INT_LEAST32_T
+#define _STDINT_NEED_INT_LEAST_T
+#endif
+
+#ifndef _STDINT_HAVE_INT_FAST32_T
+#define _STDINT_NEED_INT_FAST_T
+#endif
+
+#ifndef _STDINT_HEADER_INTPTR
+#define _STDINT_NEED_INTPTR_T
+#ifndef _STDINT_HAVE_INTMAX_T
+#define _STDINT_NEED_INTMAX_T
+#endif
+#endif
+
+
+/* .................... definition part ............................ */
+
+/* some system headers have good uint64_t */
+#ifndef _HAVE_UINT64_T
+#if     defined _STDINT_HAVE_UINT64_T  || defined HAVE_UINT64_T
+#define _HAVE_UINT64_T
+#elif   defined _STDINT_HAVE_U_INT64_T || defined HAVE_U_INT64_T
+#define _HAVE_UINT64_T
+typedef u_int64_t uint64_t;
+#endif
+#endif
+
+#ifndef _HAVE_UINT64_T
+/* .. here are some common heuristics using compiler runtime specifics */
+#if defined __STDC_VERSION__ && defined __STDC_VERSION__ >= 199901L
+#define _HAVE_UINT64_T
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+
+#elif !defined __STRICT_ANSI__
+#if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__
+#define _HAVE_UINT64_T
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+#elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__
+/* note: all ELF-systems seem to have loff-support which needs 64-bit */
+#if !defined _NO_LONGLONG
+#define _HAVE_UINT64_T
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+#endif
+
+#elif defined __alpha || (defined __mips && defined _ABIN32)
+#if !defined _NO_LONGLONG
+typedef long int64_t;
+typedef unsigned long uint64_t;
+#endif
+  /* compiler/cpu type to define int64_t */
+#endif
+#endif
+#endif
+
+#if defined _STDINT_HAVE_U_INT_TYPES
+/* int8_t int16_t int32_t defined by inet code, redeclare the u_intXX types */
+typedef u_int8_t uint8_t;
+typedef u_int16_t uint16_t;
+typedef u_int32_t uint32_t;
+
+/* glibc compatibility */
+#ifndef __int8_t_defined
+#define __int8_t_defined
+#endif
+#endif
+
+#ifdef _STDINT_NEED_INT_MODEL_T
+/* we must guess all the basic types. Apart from byte-adressable system, */
+/* there a few 32-bit-only dsp-systems that we guard with BYTE_MODEL 8-} */
+/* (btw, those nibble-addressable systems are way off, or so we assume) */
+
+dnl   /* have a look at "64bit and data size neutrality" at */
+dnl   /* http://unix.org/version2/whatsnew/login_64bit.html */
+dnl   /* (the shorthand "ILP" types always have a "P" part) */
+
+#if defined _STDINT_BYTE_MODEL
+#if _STDINT_LONG_MODEL+0 == 242
+/* 2:4:2 =  IP16 = a normal 16-bit system                */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned long   uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          long    int32_t;
+#endif
+#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL == 444
+/* 2:4:4 =  LP32 = a 32-bit system derived from a 16-bit */
+/* 4:4:4 = ILP32 = a normal 32-bit system                */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned int    uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          int     int32_t;
+#endif
+#elif _STDINT_LONG_MODEL+0 == 484 || _STDINT_LONG_MODEL+0 == 488
+/* 4:8:4 =  IP32 = a 32-bit system prepared for 64-bit    */
+/* 4:8:8 =  LP64 = a normal 64-bit system                 */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned int    uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          int     int32_t;
+#endif
+/* this system has a "long" of 64bit */
+#ifndef _HAVE_UINT64_T
+#define _HAVE_UINT64_T
+typedef unsigned long   uint64_t;
+typedef          long    int64_t;
+#endif
+#elif _STDINT_LONG_MODEL+0 == 448
+/*      LLP64   a 64-bit system derived from a 32-bit system */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned int    uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          int     int32_t;
+#endif
+/* assuming the system has a "long long" */
+#ifndef _HAVE_UINT64_T
+#define _HAVE_UINT64_T
+typedef unsigned long long uint64_t;
+typedef          long long  int64_t;
+#endif
+#else
+#define _STDINT_NO_INT32_T
+#endif
+#else
+#define _STDINT_NO_INT8_T
+#define _STDINT_NO_INT32_T
+#endif
+#endif
+
+/*
+ * quote from SunOS-5.8 sys/inttypes.h:
+ * Use at your own risk.  As of February 1996, the committee is squarely
+ * behind the fixed sized types; the "least" and "fast" types are still being
+ * discussed.  The probability that the "fast" types may be removed before
+ * the standard is finalized is high enough that they are not currently
+ * implemented.
+ */
+
+#if defined _STDINT_NEED_INT_LEAST_T
+typedef  int8_t    int_least8_t;
+typedef  int16_t   int_least16_t;
+typedef  int32_t   int_least32_t;
+#ifdef _HAVE_UINT64_T
+typedef  int64_t   int_least64_t;
+#endif
+
+typedef uint8_t   uint_least8_t;
+typedef uint16_t  uint_least16_t;
+typedef uint32_t  uint_least32_t;
+#ifdef _HAVE_UINT64_T
+typedef uint64_t  uint_least64_t;
+#endif
+  /* least types */
+#endif
+
+#if defined _STDINT_NEED_INT_FAST_T
+typedef  int8_t    int_fast8_t; 
+typedef  int       int_fast16_t;
+typedef  int32_t   int_fast32_t;
+#ifdef _HAVE_UINT64_T
+typedef  int64_t   int_fast64_t;
+#endif
+
+typedef uint8_t   uint_fast8_t; 
+typedef unsigned  uint_fast16_t;
+typedef uint32_t  uint_fast32_t;
+#ifdef _HAVE_UINT64_T
+typedef uint64_t  uint_fast64_t;
+#endif
+  /* fast types */
+#endif
+
+#ifdef _STDINT_NEED_INTMAX_T
+#ifdef _HAVE_UINT64_T
+typedef  int64_t       intmax_t;
+typedef uint64_t      uintmax_t;
+#else
+typedef          long  intmax_t;
+typedef unsigned long uintmax_t;
+#endif
+#endif
+
+#ifdef _STDINT_NEED_INTPTR_T
+#ifndef __intptr_t_defined
+#define __intptr_t_defined
+/* we encourage using "long" to store pointer values, never use "int" ! */
+#if   _STDINT_LONG_MODEL+0 == 242 || _STDINT_LONG_MODEL+0 == 484
+typedef  unsinged int   uintptr_t;
+typedef           int    intptr_t;
+#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL+0 == 444
+typedef  unsigned long  uintptr_t;
+typedef           long   intptr_t;
+#elif _STDINT_LONG_MODEL+0 == 448 && defined _HAVE_UINT64_T
+typedef        uint64_t uintptr_t;
+typedef         int64_t  intptr_t;
+#else /* matches typical system types ILP32 and LP64 - but not IP16 or LLP64 */
+typedef  unsigned long  uintptr_t;
+typedef           long   intptr_t;
+#endif
+#endif
+#endif
+
+  /* shortcircuit*/
+#endif
+  /* once */
+#endif
+#endif
+STDINT_EOF
+    if cmp -s $ac_stdint_h $ac_stdint 2>/dev/null; then
+      AC_MSG_NOTICE([$ac_stdint_h is unchanged])
+    else
+      ac_dir=`AS_DIRNAME(["$ac_stdint_h"])`
+      AS_MKDIR_P(["$ac_dir"])
+      rm -f $ac_stdint_h
+      mv $ac_stdint $ac_stdint_h
+    fi
+],[# variables for create stdint.h replacement
+PACKAGE="$PACKAGE"
+VERSION="$VERSION"
+ac_stdint_h="$ac_stdint_h"
+_ac_stdint_h=AS_TR_CPP(_$PACKAGE-$ac_stdint_h)
+ac_cv_stdint_message="$ac_cv_stdint_message"
+ac_cv_header_stdint_t="$ac_cv_header_stdint_t"
+ac_cv_header_stdint_x="$ac_cv_header_stdint_x"
+ac_cv_header_stdint_o="$ac_cv_header_stdint_o"
+ac_cv_header_stdint_u="$ac_cv_header_stdint_u"
+ac_cv_type_uint64_t="$ac_cv_type_uint64_t"
+ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t"
+ac_cv_stdint_char_model="$ac_cv_stdint_char_model"
+ac_cv_stdint_long_model="$ac_cv_stdint_long_model"
+ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t"
+ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t"
+ac_cv_type_intmax_t="$ac_cv_type_intmax_t"
+])
+])
diff --git a/aes-decrypt-internal.c b/aes-decrypt-internal.c
new file mode 100644 (file)
index 0000000..9dff166
--- /dev/null
@@ -0,0 +1,83 @@
+/* aes-decrypt-internal.c
+ *
+ * Decryption function for the aes/rijndael block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "aes-internal.h"
+#include "macros.h"
+
+void
+_nettle_aes_decrypt(const struct aes_ctx *ctx,
+                   const struct aes_table *T,
+                   unsigned length, uint8_t *dst,
+                   const uint8_t *src)
+{
+  FOR_BLOCKS(length, dst, src, AES_BLOCK_SIZE)
+    {
+      uint32_t w0, w1, w2, w3;         /* working ciphertext */
+      uint32_t t0, t1, t2, t3;
+      unsigned round;
+      
+      /* Get clear text, using little-endian byte order.
+       * Also XOR with the first subkey. */
+
+      w0 = LE_READ_UINT32(src)      ^ ctx->keys[0];
+      w1 = LE_READ_UINT32(src + 4)  ^ ctx->keys[1];
+      w2 = LE_READ_UINT32(src + 8)  ^ ctx->keys[2];
+      w3 = LE_READ_UINT32(src + 12) ^ ctx->keys[3];
+
+      for (round = 1; round < ctx->nrounds; round++)
+       {
+         t0 = AES_ROUND(T, w0, w3, w2, w1, ctx->keys[4*round]);
+         t1 = AES_ROUND(T, w1, w0, w3, w2, ctx->keys[4*round + 1]);
+         t2 = AES_ROUND(T, w2, w1, w0, w3, ctx->keys[4*round + 2]);
+         t3 = AES_ROUND(T, w3, w2, w1, w0, ctx->keys[4*round + 3]);
+
+         /* We could unroll the loop twice, to avoid these
+            assignments. If all eight variables fit in registers,
+            that should give a slight speedup. */
+         w0 = t0;
+         w1 = t1;
+         w2 = t2;
+         w3 = t3;
+       }
+
+      /* Final round */
+
+      t0 = AES_FINAL_ROUND(T, w0, w3, w2, w1, ctx->keys[4*round]);
+      t1 = AES_FINAL_ROUND(T, w1, w0, w3, w2, ctx->keys[4*round + 1]);
+      t2 = AES_FINAL_ROUND(T, w2, w1, w0, w3, ctx->keys[4*round + 2]);
+      t3 = AES_FINAL_ROUND(T, w3, w2, w1, w0, ctx->keys[4*round + 3]);
+
+      LE_WRITE_UINT32(dst, t0);
+      LE_WRITE_UINT32(dst + 8, t2);
+      LE_WRITE_UINT32(dst + 4, t1);
+      LE_WRITE_UINT32(dst + 12, t3);
+    }
+}
diff --git a/aes-decrypt.c b/aes-decrypt.c
new file mode 100644 (file)
index 0000000..39b79c6
--- /dev/null
@@ -0,0 +1,347 @@
+/* aes-decrypt.c
+ *
+ * Decryption function for aes/rijndael block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "aes-internal.h"
+
+static const struct aes_table
+_aes_decrypt_table =
+  { /* isbox */
+    {
+      0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,
+      0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
+      0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,
+      0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,
+      0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,
+      0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,
+      0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,
+      0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,
+      0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,
+      0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,
+      0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,
+      0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,
+      0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,
+      0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,
+      0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,
+      0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,
+      0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,
+      0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,
+      0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,
+      0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,
+      0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,
+      0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,
+      0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,
+      0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,
+      0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,
+      0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,
+      0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,
+      0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,
+      0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,
+      0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,
+      0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,
+      0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d,
+    },
+    { /* itable */
+      { 
+       0x50a7f451,0x5365417e,0xc3a4171a,0x965e273a,
+       0xcb6bab3b,0xf1459d1f,0xab58faac,0x9303e34b,
+       0x55fa3020,0xf66d76ad,0x9176cc88,0x254c02f5,
+       0xfcd7e54f,0xd7cb2ac5,0x80443526,0x8fa362b5,
+       0x495ab1de,0x671bba25,0x980eea45,0xe1c0fe5d,
+       0x02752fc3,0x12f04c81,0xa397468d,0xc6f9d36b,
+       0xe75f8f03,0x959c9215,0xeb7a6dbf,0xda595295,
+       0x2d83bed4,0xd3217458,0x2969e049,0x44c8c98e,
+       0x6a89c275,0x78798ef4,0x6b3e5899,0xdd71b927,
+       0xb64fe1be,0x17ad88f0,0x66ac20c9,0xb43ace7d,
+       0x184adf63,0x82311ae5,0x60335197,0x457f5362,
+       0xe07764b1,0x84ae6bbb,0x1ca081fe,0x942b08f9,
+       0x58684870,0x19fd458f,0x876cde94,0xb7f87b52,
+       0x23d373ab,0xe2024b72,0x578f1fe3,0x2aab5566,
+       0x0728ebb2,0x03c2b52f,0x9a7bc586,0xa50837d3,
+       0xf2872830,0xb2a5bf23,0xba6a0302,0x5c8216ed,
+       0x2b1ccf8a,0x92b479a7,0xf0f207f3,0xa1e2694e,
+       0xcdf4da65,0xd5be0506,0x1f6234d1,0x8afea6c4,
+       0x9d532e34,0xa055f3a2,0x32e18a05,0x75ebf6a4,
+       0x39ec830b,0xaaef6040,0x069f715e,0x51106ebd,
+       0xf98a213e,0x3d06dd96,0xae053edd,0x46bde64d,
+       0xb58d5491,0x055dc471,0x6fd40604,0xff155060,
+       0x24fb9819,0x97e9bdd6,0xcc434089,0x779ed967,
+       0xbd42e8b0,0x888b8907,0x385b19e7,0xdbeec879,
+       0x470a7ca1,0xe90f427c,0xc91e84f8,0x00000000,
+       0x83868009,0x48ed2b32,0xac70111e,0x4e725a6c,
+       0xfbff0efd,0x5638850f,0x1ed5ae3d,0x27392d36,
+       0x64d90f0a,0x21a65c68,0xd1545b9b,0x3a2e3624,
+       0xb1670a0c,0x0fe75793,0xd296eeb4,0x9e919b1b,
+       0x4fc5c080,0xa220dc61,0x694b775a,0x161a121c,
+       0x0aba93e2,0xe52aa0c0,0x43e0223c,0x1d171b12,
+       0x0b0d090e,0xadc78bf2,0xb9a8b62d,0xc8a91e14,
+       0x8519f157,0x4c0775af,0xbbdd99ee,0xfd607fa3,
+       0x9f2601f7,0xbcf5725c,0xc53b6644,0x347efb5b,
+       0x7629438b,0xdcc623cb,0x68fcedb6,0x63f1e4b8,
+       0xcadc31d7,0x10856342,0x40229713,0x2011c684,
+       0x7d244a85,0xf83dbbd2,0x1132f9ae,0x6da129c7,
+       0x4b2f9e1d,0xf330b2dc,0xec52860d,0xd0e3c177,
+       0x6c16b32b,0x99b970a9,0xfa489411,0x2264e947,
+       0xc48cfca8,0x1a3ff0a0,0xd82c7d56,0xef903322,
+       0xc74e4987,0xc1d138d9,0xfea2ca8c,0x360bd498,
+       0xcf81f5a6,0x28de7aa5,0x268eb7da,0xa4bfad3f,
+       0xe49d3a2c,0x0d927850,0x9bcc5f6a,0x62467e54,
+       0xc2138df6,0xe8b8d890,0x5ef7392e,0xf5afc382,
+       0xbe805d9f,0x7c93d069,0xa92dd56f,0xb31225cf,
+       0x3b99acc8,0xa77d1810,0x6e639ce8,0x7bbb3bdb,
+       0x097826cd,0xf418596e,0x01b79aec,0xa89a4f83,
+       0x656e95e6,0x7ee6ffaa,0x08cfbc21,0xe6e815ef,
+       0xd99be7ba,0xce366f4a,0xd4099fea,0xd67cb029,
+       0xafb2a431,0x31233f2a,0x3094a5c6,0xc066a235,
+       0x37bc4e74,0xa6ca82fc,0xb0d090e0,0x15d8a733,
+       0x4a9804f1,0xf7daec41,0x0e50cd7f,0x2ff69117,
+       0x8dd64d76,0x4db0ef43,0x544daacc,0xdf0496e4,
+       0xe3b5d19e,0x1b886a4c,0xb81f2cc1,0x7f516546,
+       0x04ea5e9d,0x5d358c01,0x737487fa,0x2e410bfb,
+       0x5a1d67b3,0x52d2db92,0x335610e9,0x1347d66d,
+       0x8c61d79a,0x7a0ca137,0x8e14f859,0x893c13eb,
+       0xee27a9ce,0x35c961b7,0xede51ce1,0x3cb1477a,
+       0x59dfd29c,0x3f73f255,0x79ce1418,0xbf37c773,
+       0xeacdf753,0x5baafd5f,0x146f3ddf,0x86db4478,
+       0x81f3afca,0x3ec468b9,0x2c342438,0x5f40a3c2,
+       0x72c31d16,0x0c25e2bc,0x8b493c28,0x41950dff,
+       0x7101a839,0xdeb30c08,0x9ce4b4d8,0x90c15664,
+       0x6184cb7b,0x70b632d5,0x745c6c48,0x4257b8d0,
+      },
+#if !AES_SMALL
+      { /* Before: itable[1] */
+       0xa7f45150,0x65417e53,0xa4171ac3,0x5e273a96,
+       0x6bab3bcb,0x459d1ff1,0x58faacab,0x03e34b93,
+       0xfa302055,0x6d76adf6,0x76cc8891,0x4c02f525,
+       0xd7e54ffc,0xcb2ac5d7,0x44352680,0xa362b58f,
+       0x5ab1de49,0x1bba2567,0x0eea4598,0xc0fe5de1,
+       0x752fc302,0xf04c8112,0x97468da3,0xf9d36bc6,
+       0x5f8f03e7,0x9c921595,0x7a6dbfeb,0x595295da,
+       0x83bed42d,0x217458d3,0x69e04929,0xc8c98e44,
+       0x89c2756a,0x798ef478,0x3e58996b,0x71b927dd,
+       0x4fe1beb6,0xad88f017,0xac20c966,0x3ace7db4,
+       0x4adf6318,0x311ae582,0x33519760,0x7f536245,
+       0x7764b1e0,0xae6bbb84,0xa081fe1c,0x2b08f994,
+       0x68487058,0xfd458f19,0x6cde9487,0xf87b52b7,
+       0xd373ab23,0x024b72e2,0x8f1fe357,0xab55662a,
+       0x28ebb207,0xc2b52f03,0x7bc5869a,0x0837d3a5,
+       0x872830f2,0xa5bf23b2,0x6a0302ba,0x8216ed5c,
+       0x1ccf8a2b,0xb479a792,0xf207f3f0,0xe2694ea1,
+       0xf4da65cd,0xbe0506d5,0x6234d11f,0xfea6c48a,
+       0x532e349d,0x55f3a2a0,0xe18a0532,0xebf6a475,
+       0xec830b39,0xef6040aa,0x9f715e06,0x106ebd51,
+       0x8a213ef9,0x06dd963d,0x053eddae,0xbde64d46,
+       0x8d5491b5,0x5dc47105,0xd406046f,0x155060ff,
+       0xfb981924,0xe9bdd697,0x434089cc,0x9ed96777,
+       0x42e8b0bd,0x8b890788,0x5b19e738,0xeec879db,
+       0x0a7ca147,0x0f427ce9,0x1e84f8c9,0x00000000,
+       0x86800983,0xed2b3248,0x70111eac,0x725a6c4e,
+       0xff0efdfb,0x38850f56,0xd5ae3d1e,0x392d3627,
+       0xd90f0a64,0xa65c6821,0x545b9bd1,0x2e36243a,
+       0x670a0cb1,0xe757930f,0x96eeb4d2,0x919b1b9e,
+       0xc5c0804f,0x20dc61a2,0x4b775a69,0x1a121c16,
+       0xba93e20a,0x2aa0c0e5,0xe0223c43,0x171b121d,
+       0x0d090e0b,0xc78bf2ad,0xa8b62db9,0xa91e14c8,
+       0x19f15785,0x0775af4c,0xdd99eebb,0x607fa3fd,
+       0x2601f79f,0xf5725cbc,0x3b6644c5,0x7efb5b34,
+       0x29438b76,0xc623cbdc,0xfcedb668,0xf1e4b863,
+       0xdc31d7ca,0x85634210,0x22971340,0x11c68420,
+       0x244a857d,0x3dbbd2f8,0x32f9ae11,0xa129c76d,
+       0x2f9e1d4b,0x30b2dcf3,0x52860dec,0xe3c177d0,
+       0x16b32b6c,0xb970a999,0x489411fa,0x64e94722,
+       0x8cfca8c4,0x3ff0a01a,0x2c7d56d8,0x903322ef,
+       0x4e4987c7,0xd138d9c1,0xa2ca8cfe,0x0bd49836,
+       0x81f5a6cf,0xde7aa528,0x8eb7da26,0xbfad3fa4,
+       0x9d3a2ce4,0x9278500d,0xcc5f6a9b,0x467e5462,
+       0x138df6c2,0xb8d890e8,0xf7392e5e,0xafc382f5,
+       0x805d9fbe,0x93d0697c,0x2dd56fa9,0x1225cfb3,
+       0x99acc83b,0x7d1810a7,0x639ce86e,0xbb3bdb7b,
+       0x7826cd09,0x18596ef4,0xb79aec01,0x9a4f83a8,
+       0x6e95e665,0xe6ffaa7e,0xcfbc2108,0xe815efe6,
+       0x9be7bad9,0x366f4ace,0x099fead4,0x7cb029d6,
+       0xb2a431af,0x233f2a31,0x94a5c630,0x66a235c0,
+       0xbc4e7437,0xca82fca6,0xd090e0b0,0xd8a73315,
+       0x9804f14a,0xdaec41f7,0x50cd7f0e,0xf691172f,
+       0xd64d768d,0xb0ef434d,0x4daacc54,0x0496e4df,
+       0xb5d19ee3,0x886a4c1b,0x1f2cc1b8,0x5165467f,
+       0xea5e9d04,0x358c015d,0x7487fa73,0x410bfb2e,
+       0x1d67b35a,0xd2db9252,0x5610e933,0x47d66d13,
+       0x61d79a8c,0x0ca1377a,0x14f8598e,0x3c13eb89,
+       0x27a9ceee,0xc961b735,0xe51ce1ed,0xb1477a3c,
+       0xdfd29c59,0x73f2553f,0xce141879,0x37c773bf,
+       0xcdf753ea,0xaafd5f5b,0x6f3ddf14,0xdb447886,
+       0xf3afca81,0xc468b93e,0x3424382c,0x40a3c25f,
+       0xc31d1672,0x25e2bc0c,0x493c288b,0x950dff41,
+       0x01a83971,0xb30c08de,0xe4b4d89c,0xc1566490,
+       0x84cb7b61,0xb632d570,0x5c6c4874,0x57b8d042,
+      },{ /* Before: itable[2] */
+       0xf45150a7,0x417e5365,0x171ac3a4,0x273a965e,
+       0xab3bcb6b,0x9d1ff145,0xfaacab58,0xe34b9303,
+       0x302055fa,0x76adf66d,0xcc889176,0x02f5254c,
+       0xe54ffcd7,0x2ac5d7cb,0x35268044,0x62b58fa3,
+       0xb1de495a,0xba25671b,0xea45980e,0xfe5de1c0,
+       0x2fc30275,0x4c8112f0,0x468da397,0xd36bc6f9,
+       0x8f03e75f,0x9215959c,0x6dbfeb7a,0x5295da59,
+       0xbed42d83,0x7458d321,0xe0492969,0xc98e44c8,
+       0xc2756a89,0x8ef47879,0x58996b3e,0xb927dd71,
+       0xe1beb64f,0x88f017ad,0x20c966ac,0xce7db43a,
+       0xdf63184a,0x1ae58231,0x51976033,0x5362457f,
+       0x64b1e077,0x6bbb84ae,0x81fe1ca0,0x08f9942b,
+       0x48705868,0x458f19fd,0xde94876c,0x7b52b7f8,
+       0x73ab23d3,0x4b72e202,0x1fe3578f,0x55662aab,
+       0xebb20728,0xb52f03c2,0xc5869a7b,0x37d3a508,
+       0x2830f287,0xbf23b2a5,0x0302ba6a,0x16ed5c82,
+       0xcf8a2b1c,0x79a792b4,0x07f3f0f2,0x694ea1e2,
+       0xda65cdf4,0x0506d5be,0x34d11f62,0xa6c48afe,
+       0x2e349d53,0xf3a2a055,0x8a0532e1,0xf6a475eb,
+       0x830b39ec,0x6040aaef,0x715e069f,0x6ebd5110,
+       0x213ef98a,0xdd963d06,0x3eddae05,0xe64d46bd,
+       0x5491b58d,0xc471055d,0x06046fd4,0x5060ff15,
+       0x981924fb,0xbdd697e9,0x4089cc43,0xd967779e,
+       0xe8b0bd42,0x8907888b,0x19e7385b,0xc879dbee,
+       0x7ca1470a,0x427ce90f,0x84f8c91e,0x00000000,
+       0x80098386,0x2b3248ed,0x111eac70,0x5a6c4e72,
+       0x0efdfbff,0x850f5638,0xae3d1ed5,0x2d362739,
+       0x0f0a64d9,0x5c6821a6,0x5b9bd154,0x36243a2e,
+       0x0a0cb167,0x57930fe7,0xeeb4d296,0x9b1b9e91,
+       0xc0804fc5,0xdc61a220,0x775a694b,0x121c161a,
+       0x93e20aba,0xa0c0e52a,0x223c43e0,0x1b121d17,
+       0x090e0b0d,0x8bf2adc7,0xb62db9a8,0x1e14c8a9,
+       0xf1578519,0x75af4c07,0x99eebbdd,0x7fa3fd60,
+       0x01f79f26,0x725cbcf5,0x6644c53b,0xfb5b347e,
+       0x438b7629,0x23cbdcc6,0xedb668fc,0xe4b863f1,
+       0x31d7cadc,0x63421085,0x97134022,0xc6842011,
+       0x4a857d24,0xbbd2f83d,0xf9ae1132,0x29c76da1,
+       0x9e1d4b2f,0xb2dcf330,0x860dec52,0xc177d0e3,
+       0xb32b6c16,0x70a999b9,0x9411fa48,0xe9472264,
+       0xfca8c48c,0xf0a01a3f,0x7d56d82c,0x3322ef90,
+       0x4987c74e,0x38d9c1d1,0xca8cfea2,0xd498360b,
+       0xf5a6cf81,0x7aa528de,0xb7da268e,0xad3fa4bf,
+       0x3a2ce49d,0x78500d92,0x5f6a9bcc,0x7e546246,
+       0x8df6c213,0xd890e8b8,0x392e5ef7,0xc382f5af,
+       0x5d9fbe80,0xd0697c93,0xd56fa92d,0x25cfb312,
+       0xacc83b99,0x1810a77d,0x9ce86e63,0x3bdb7bbb,
+       0x26cd0978,0x596ef418,0x9aec01b7,0x4f83a89a,
+       0x95e6656e,0xffaa7ee6,0xbc2108cf,0x15efe6e8,
+       0xe7bad99b,0x6f4ace36,0x9fead409,0xb029d67c,
+       0xa431afb2,0x3f2a3123,0xa5c63094,0xa235c066,
+       0x4e7437bc,0x82fca6ca,0x90e0b0d0,0xa73315d8,
+       0x04f14a98,0xec41f7da,0xcd7f0e50,0x91172ff6,
+       0x4d768dd6,0xef434db0,0xaacc544d,0x96e4df04,
+       0xd19ee3b5,0x6a4c1b88,0x2cc1b81f,0x65467f51,
+       0x5e9d04ea,0x8c015d35,0x87fa7374,0x0bfb2e41,
+       0x67b35a1d,0xdb9252d2,0x10e93356,0xd66d1347,
+       0xd79a8c61,0xa1377a0c,0xf8598e14,0x13eb893c,
+       0xa9ceee27,0x61b735c9,0x1ce1ede5,0x477a3cb1,
+       0xd29c59df,0xf2553f73,0x141879ce,0xc773bf37,
+       0xf753eacd,0xfd5f5baa,0x3ddf146f,0x447886db,
+       0xafca81f3,0x68b93ec4,0x24382c34,0xa3c25f40,
+       0x1d1672c3,0xe2bc0c25,0x3c288b49,0x0dff4195,
+       0xa8397101,0x0c08deb3,0xb4d89ce4,0x566490c1,
+       0xcb7b6184,0x32d570b6,0x6c48745c,0xb8d04257,
+      },{ /* Before: itable[3] */
+       0x5150a7f4,0x7e536541,0x1ac3a417,0x3a965e27,
+       0x3bcb6bab,0x1ff1459d,0xacab58fa,0x4b9303e3,
+       0x2055fa30,0xadf66d76,0x889176cc,0xf5254c02,
+       0x4ffcd7e5,0xc5d7cb2a,0x26804435,0xb58fa362,
+       0xde495ab1,0x25671bba,0x45980eea,0x5de1c0fe,
+       0xc302752f,0x8112f04c,0x8da39746,0x6bc6f9d3,
+       0x03e75f8f,0x15959c92,0xbfeb7a6d,0x95da5952,
+       0xd42d83be,0x58d32174,0x492969e0,0x8e44c8c9,
+       0x756a89c2,0xf478798e,0x996b3e58,0x27dd71b9,
+       0xbeb64fe1,0xf017ad88,0xc966ac20,0x7db43ace,
+       0x63184adf,0xe582311a,0x97603351,0x62457f53,
+       0xb1e07764,0xbb84ae6b,0xfe1ca081,0xf9942b08,
+       0x70586848,0x8f19fd45,0x94876cde,0x52b7f87b,
+       0xab23d373,0x72e2024b,0xe3578f1f,0x662aab55,
+       0xb20728eb,0x2f03c2b5,0x869a7bc5,0xd3a50837,
+       0x30f28728,0x23b2a5bf,0x02ba6a03,0xed5c8216,
+       0x8a2b1ccf,0xa792b479,0xf3f0f207,0x4ea1e269,
+       0x65cdf4da,0x06d5be05,0xd11f6234,0xc48afea6,
+       0x349d532e,0xa2a055f3,0x0532e18a,0xa475ebf6,
+       0x0b39ec83,0x40aaef60,0x5e069f71,0xbd51106e,
+       0x3ef98a21,0x963d06dd,0xddae053e,0x4d46bde6,
+       0x91b58d54,0x71055dc4,0x046fd406,0x60ff1550,
+       0x1924fb98,0xd697e9bd,0x89cc4340,0x67779ed9,
+       0xb0bd42e8,0x07888b89,0xe7385b19,0x79dbeec8,
+       0xa1470a7c,0x7ce90f42,0xf8c91e84,0x00000000,
+       0x09838680,0x3248ed2b,0x1eac7011,0x6c4e725a,
+       0xfdfbff0e,0x0f563885,0x3d1ed5ae,0x3627392d,
+       0x0a64d90f,0x6821a65c,0x9bd1545b,0x243a2e36,
+       0x0cb1670a,0x930fe757,0xb4d296ee,0x1b9e919b,
+       0x804fc5c0,0x61a220dc,0x5a694b77,0x1c161a12,
+       0xe20aba93,0xc0e52aa0,0x3c43e022,0x121d171b,
+       0x0e0b0d09,0xf2adc78b,0x2db9a8b6,0x14c8a91e,
+       0x578519f1,0xaf4c0775,0xeebbdd99,0xa3fd607f,
+       0xf79f2601,0x5cbcf572,0x44c53b66,0x5b347efb,
+       0x8b762943,0xcbdcc623,0xb668fced,0xb863f1e4,
+       0xd7cadc31,0x42108563,0x13402297,0x842011c6,
+       0x857d244a,0xd2f83dbb,0xae1132f9,0xc76da129,
+       0x1d4b2f9e,0xdcf330b2,0x0dec5286,0x77d0e3c1,
+       0x2b6c16b3,0xa999b970,0x11fa4894,0x472264e9,
+       0xa8c48cfc,0xa01a3ff0,0x56d82c7d,0x22ef9033,
+       0x87c74e49,0xd9c1d138,0x8cfea2ca,0x98360bd4,
+       0xa6cf81f5,0xa528de7a,0xda268eb7,0x3fa4bfad,
+       0x2ce49d3a,0x500d9278,0x6a9bcc5f,0x5462467e,
+       0xf6c2138d,0x90e8b8d8,0x2e5ef739,0x82f5afc3,
+       0x9fbe805d,0x697c93d0,0x6fa92dd5,0xcfb31225,
+       0xc83b99ac,0x10a77d18,0xe86e639c,0xdb7bbb3b,
+       0xcd097826,0x6ef41859,0xec01b79a,0x83a89a4f,
+       0xe6656e95,0xaa7ee6ff,0x2108cfbc,0xefe6e815,
+       0xbad99be7,0x4ace366f,0xead4099f,0x29d67cb0,
+       0x31afb2a4,0x2a31233f,0xc63094a5,0x35c066a2,
+       0x7437bc4e,0xfca6ca82,0xe0b0d090,0x3315d8a7,
+       0xf14a9804,0x41f7daec,0x7f0e50cd,0x172ff691,
+       0x768dd64d,0x434db0ef,0xcc544daa,0xe4df0496,
+       0x9ee3b5d1,0x4c1b886a,0xc1b81f2c,0x467f5165,
+       0x9d04ea5e,0x015d358c,0xfa737487,0xfb2e410b,
+       0xb35a1d67,0x9252d2db,0xe9335610,0x6d1347d6,
+       0x9a8c61d7,0x377a0ca1,0x598e14f8,0xeb893c13,
+       0xceee27a9,0xb735c961,0xe1ede51c,0x7a3cb147,
+       0x9c59dfd2,0x553f73f2,0x1879ce14,0x73bf37c7,
+       0x53eacdf7,0x5f5baafd,0xdf146f3d,0x7886db44,
+       0xca81f3af,0xb93ec468,0x382c3424,0xc25f40a3,
+       0x1672c31d,0xbc0c25e2,0x288b493c,0xff41950d,
+       0x397101a8,0x08deb30c,0xd89ce4b4,0x6490c156,
+       0x7b6184cb,0xd570b632,0x48745c6c,0xd04257b8,
+      },
+#endif /* !AES_SMALL */  
+    }
+  };
+
+void
+aes_decrypt(const struct aes_ctx *ctx,
+           unsigned length, uint8_t *dst,
+           const uint8_t *src)
+{
+  assert(!(length % AES_BLOCK_SIZE) );
+  _aes_decrypt(ctx, &_aes_decrypt_table,
+              length, dst, src);
+}
diff --git a/aes-encrypt-internal.c b/aes-encrypt-internal.c
new file mode 100644 (file)
index 0000000..84ed6cf
--- /dev/null
@@ -0,0 +1,105 @@
+/* aes-encrypt-internal.c
+ *
+ * Encryption function for the aes/rijndael block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "aes-internal.h"
+#include "macros.h"
+
+void
+_nettle_aes_encrypt(const struct aes_ctx *ctx,
+                   const struct aes_table *T,
+                   unsigned length, uint8_t *dst,
+                   const uint8_t *src)
+{
+  FOR_BLOCKS(length, dst, src, AES_BLOCK_SIZE)
+    {
+      uint32_t w0, w1, w2, w3;         /* working ciphertext */
+      uint32_t t0, t1, t2, t3;
+      unsigned round;
+      
+      /* Get clear text, using little-endian byte order.
+       * Also XOR with the first subkey. */
+
+      w0 = LE_READ_UINT32(src)      ^ ctx->keys[0];
+      w1 = LE_READ_UINT32(src + 4)  ^ ctx->keys[1];
+      w2 = LE_READ_UINT32(src + 8)  ^ ctx->keys[2];
+      w3 = LE_READ_UINT32(src + 12) ^ ctx->keys[3];
+
+      for (round = 1; round < ctx->nrounds; round++)
+       {
+         t0 = AES_ROUND(T, w0, w1, w2, w3, ctx->keys[4*round]);
+         t1 = AES_ROUND(T, w1, w2, w3, w0, ctx->keys[4*round + 1]);
+         t2 = AES_ROUND(T, w2, w3, w0, w1, ctx->keys[4*round + 2]);
+         t3 = AES_ROUND(T, w3, w0, w1, w2, ctx->keys[4*round + 3]);
+
+         /* We could unroll the loop twice, to avoid these
+            assignments. If all eight variables fit in registers,
+            that should give a slight speedup. */
+         w0 = t0;
+         w1 = t1;
+         w2 = t2;
+         w3 = t3;
+       }
+
+      /* Final round */
+
+      t0 = AES_FINAL_ROUND(T, w0, w1, w2, w3, ctx->keys[4*round]);
+      t1 = AES_FINAL_ROUND(T, w1, w2, w3, w0, ctx->keys[4*round + 1]);
+      t2 = AES_FINAL_ROUND(T, w2, w3, w0, w1, ctx->keys[4*round + 2]);
+      t3 = AES_FINAL_ROUND(T, w3, w0, w1, w2, ctx->keys[4*round + 3]);
+
+      LE_WRITE_UINT32(dst, t0);
+      LE_WRITE_UINT32(dst + 8, t2);
+      LE_WRITE_UINT32(dst + 4, t1);
+      LE_WRITE_UINT32(dst + 12, t3);
+    }
+}
+
+/* Some stats, all for AES 128:
+
+   A. Table-driven indexing (the approach of the old unified
+      _aes_crypt function).
+   B. Unrolling the j-loop.
+
+   C. Eliminated the use of IDXk(j) in the main loop.
+
+   D. Put wtxt in four scalar variables.
+
+   E. Also put t in four scalar variables.
+
+       P4 2.2 GHz         AMD Duron 1.4GHz
+       
+       MB/s  code size
+   A   35.9  0x202        17 MB/s
+   B   37.3  0x334
+   C   33.0  0x2a7
+   D   40.7  0x3f9
+   E   42.9  0x44a        26 MB/s
+ */
diff --git a/aes-encrypt-table.c b/aes-encrypt-table.c
new file mode 100644 (file)
index 0000000..000498d
--- /dev/null
@@ -0,0 +1,346 @@
+/* aes-encrypt-table.c
+ *
+ * Encryption table for the aes/rijndael block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "aes-internal.h"
+
+/* Tables are assembled using little-endian byte order, including the
+ * pre-rotated variants. Generated by aesdata.c.
+ *
+ * Note that AES is byte order agnostic, we only need to be consistent
+ * and use the same byteorder when processing key, cleartext and
+ * ciphertext bytes.
+ *
+ * Little-endian means that the first row of the AES state arrays
+ * occupy the least significant byte of the words, which is also
+ * consistent with the row numbering. */
+
+const struct aes_table
+_aes_encrypt_table =
+  { /* sbox */
+    {
+      0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,
+      0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
+      0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,
+      0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
+      0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,
+      0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
+      0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,
+      0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
+      0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,
+      0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
+      0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,
+      0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
+      0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,
+      0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
+      0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,
+      0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
+      0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,
+      0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
+      0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,
+      0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
+      0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,
+      0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
+      0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,
+      0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
+      0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,
+      0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
+      0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,
+      0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
+      0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,
+      0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
+      0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,
+      0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16,
+    },
+    { /* dtable */
+      { 
+       0xa56363c6,0x847c7cf8,0x997777ee,0x8d7b7bf6,
+       0x0df2f2ff,0xbd6b6bd6,0xb16f6fde,0x54c5c591,
+       0x50303060,0x03010102,0xa96767ce,0x7d2b2b56,
+       0x19fefee7,0x62d7d7b5,0xe6abab4d,0x9a7676ec,
+       0x45caca8f,0x9d82821f,0x40c9c989,0x877d7dfa,
+       0x15fafaef,0xeb5959b2,0xc947478e,0x0bf0f0fb,
+       0xecadad41,0x67d4d4b3,0xfda2a25f,0xeaafaf45,
+       0xbf9c9c23,0xf7a4a453,0x967272e4,0x5bc0c09b,
+       0xc2b7b775,0x1cfdfde1,0xae93933d,0x6a26264c,
+       0x5a36366c,0x413f3f7e,0x02f7f7f5,0x4fcccc83,
+       0x5c343468,0xf4a5a551,0x34e5e5d1,0x08f1f1f9,
+       0x937171e2,0x73d8d8ab,0x53313162,0x3f15152a,
+       0x0c040408,0x52c7c795,0x65232346,0x5ec3c39d,
+       0x28181830,0xa1969637,0x0f05050a,0xb59a9a2f,
+       0x0907070e,0x36121224,0x9b80801b,0x3de2e2df,
+       0x26ebebcd,0x6927274e,0xcdb2b27f,0x9f7575ea,
+       0x1b090912,0x9e83831d,0x742c2c58,0x2e1a1a34,
+       0x2d1b1b36,0xb26e6edc,0xee5a5ab4,0xfba0a05b,
+       0xf65252a4,0x4d3b3b76,0x61d6d6b7,0xceb3b37d,
+       0x7b292952,0x3ee3e3dd,0x712f2f5e,0x97848413,
+       0xf55353a6,0x68d1d1b9,0x00000000,0x2cededc1,
+       0x60202040,0x1ffcfce3,0xc8b1b179,0xed5b5bb6,
+       0xbe6a6ad4,0x46cbcb8d,0xd9bebe67,0x4b393972,
+       0xde4a4a94,0xd44c4c98,0xe85858b0,0x4acfcf85,
+       0x6bd0d0bb,0x2aefefc5,0xe5aaaa4f,0x16fbfbed,
+       0xc5434386,0xd74d4d9a,0x55333366,0x94858511,
+       0xcf45458a,0x10f9f9e9,0x06020204,0x817f7ffe,
+       0xf05050a0,0x443c3c78,0xba9f9f25,0xe3a8a84b,
+       0xf35151a2,0xfea3a35d,0xc0404080,0x8a8f8f05,
+       0xad92923f,0xbc9d9d21,0x48383870,0x04f5f5f1,
+       0xdfbcbc63,0xc1b6b677,0x75dadaaf,0x63212142,
+       0x30101020,0x1affffe5,0x0ef3f3fd,0x6dd2d2bf,
+       0x4ccdcd81,0x140c0c18,0x35131326,0x2fececc3,
+       0xe15f5fbe,0xa2979735,0xcc444488,0x3917172e,
+       0x57c4c493,0xf2a7a755,0x827e7efc,0x473d3d7a,
+       0xac6464c8,0xe75d5dba,0x2b191932,0x957373e6,
+       0xa06060c0,0x98818119,0xd14f4f9e,0x7fdcdca3,
+       0x66222244,0x7e2a2a54,0xab90903b,0x8388880b,
+       0xca46468c,0x29eeeec7,0xd3b8b86b,0x3c141428,
+       0x79dedea7,0xe25e5ebc,0x1d0b0b16,0x76dbdbad,
+       0x3be0e0db,0x56323264,0x4e3a3a74,0x1e0a0a14,
+       0xdb494992,0x0a06060c,0x6c242448,0xe45c5cb8,
+       0x5dc2c29f,0x6ed3d3bd,0xefacac43,0xa66262c4,
+       0xa8919139,0xa4959531,0x37e4e4d3,0x8b7979f2,
+       0x32e7e7d5,0x43c8c88b,0x5937376e,0xb76d6dda,
+       0x8c8d8d01,0x64d5d5b1,0xd24e4e9c,0xe0a9a949,
+       0xb46c6cd8,0xfa5656ac,0x07f4f4f3,0x25eaeacf,
+       0xaf6565ca,0x8e7a7af4,0xe9aeae47,0x18080810,
+       0xd5baba6f,0x887878f0,0x6f25254a,0x722e2e5c,
+       0x241c1c38,0xf1a6a657,0xc7b4b473,0x51c6c697,
+       0x23e8e8cb,0x7cdddda1,0x9c7474e8,0x211f1f3e,
+       0xdd4b4b96,0xdcbdbd61,0x868b8b0d,0x858a8a0f,
+       0x907070e0,0x423e3e7c,0xc4b5b571,0xaa6666cc,
+       0xd8484890,0x05030306,0x01f6f6f7,0x120e0e1c,
+       0xa36161c2,0x5f35356a,0xf95757ae,0xd0b9b969,
+       0x91868617,0x58c1c199,0x271d1d3a,0xb99e9e27,
+       0x38e1e1d9,0x13f8f8eb,0xb398982b,0x33111122,
+       0xbb6969d2,0x70d9d9a9,0x898e8e07,0xa7949433,
+       0xb69b9b2d,0x221e1e3c,0x92878715,0x20e9e9c9,
+       0x49cece87,0xff5555aa,0x78282850,0x7adfdfa5,
+       0x8f8c8c03,0xf8a1a159,0x80898909,0x170d0d1a,
+       0xdabfbf65,0x31e6e6d7,0xc6424284,0xb86868d0,
+       0xc3414182,0xb0999929,0x772d2d5a,0x110f0f1e,
+       0xcbb0b07b,0xfc5454a8,0xd6bbbb6d,0x3a16162c,
+      },
+#if !AES_SMALL
+      { 
+       0x6363c6a5,0x7c7cf884,0x7777ee99,0x7b7bf68d,
+       0xf2f2ff0d,0x6b6bd6bd,0x6f6fdeb1,0xc5c59154,
+       0x30306050,0x01010203,0x6767cea9,0x2b2b567d,
+       0xfefee719,0xd7d7b562,0xabab4de6,0x7676ec9a,
+       0xcaca8f45,0x82821f9d,0xc9c98940,0x7d7dfa87,
+       0xfafaef15,0x5959b2eb,0x47478ec9,0xf0f0fb0b,
+       0xadad41ec,0xd4d4b367,0xa2a25ffd,0xafaf45ea,
+       0x9c9c23bf,0xa4a453f7,0x7272e496,0xc0c09b5b,
+       0xb7b775c2,0xfdfde11c,0x93933dae,0x26264c6a,
+       0x36366c5a,0x3f3f7e41,0xf7f7f502,0xcccc834f,
+       0x3434685c,0xa5a551f4,0xe5e5d134,0xf1f1f908,
+       0x7171e293,0xd8d8ab73,0x31316253,0x15152a3f,
+       0x0404080c,0xc7c79552,0x23234665,0xc3c39d5e,
+       0x18183028,0x969637a1,0x05050a0f,0x9a9a2fb5,
+       0x07070e09,0x12122436,0x80801b9b,0xe2e2df3d,
+       0xebebcd26,0x27274e69,0xb2b27fcd,0x7575ea9f,
+       0x0909121b,0x83831d9e,0x2c2c5874,0x1a1a342e,
+       0x1b1b362d,0x6e6edcb2,0x5a5ab4ee,0xa0a05bfb,
+       0x5252a4f6,0x3b3b764d,0xd6d6b761,0xb3b37dce,
+       0x2929527b,0xe3e3dd3e,0x2f2f5e71,0x84841397,
+       0x5353a6f5,0xd1d1b968,0x00000000,0xededc12c,
+       0x20204060,0xfcfce31f,0xb1b179c8,0x5b5bb6ed,
+       0x6a6ad4be,0xcbcb8d46,0xbebe67d9,0x3939724b,
+       0x4a4a94de,0x4c4c98d4,0x5858b0e8,0xcfcf854a,
+       0xd0d0bb6b,0xefefc52a,0xaaaa4fe5,0xfbfbed16,
+       0x434386c5,0x4d4d9ad7,0x33336655,0x85851194,
+       0x45458acf,0xf9f9e910,0x02020406,0x7f7ffe81,
+       0x5050a0f0,0x3c3c7844,0x9f9f25ba,0xa8a84be3,
+       0x5151a2f3,0xa3a35dfe,0x404080c0,0x8f8f058a,
+       0x92923fad,0x9d9d21bc,0x38387048,0xf5f5f104,
+       0xbcbc63df,0xb6b677c1,0xdadaaf75,0x21214263,
+       0x10102030,0xffffe51a,0xf3f3fd0e,0xd2d2bf6d,
+       0xcdcd814c,0x0c0c1814,0x13132635,0xececc32f,
+       0x5f5fbee1,0x979735a2,0x444488cc,0x17172e39,
+       0xc4c49357,0xa7a755f2,0x7e7efc82,0x3d3d7a47,
+       0x6464c8ac,0x5d5dbae7,0x1919322b,0x7373e695,
+       0x6060c0a0,0x81811998,0x4f4f9ed1,0xdcdca37f,
+       0x22224466,0x2a2a547e,0x90903bab,0x88880b83,
+       0x46468cca,0xeeeec729,0xb8b86bd3,0x1414283c,
+       0xdedea779,0x5e5ebce2,0x0b0b161d,0xdbdbad76,
+       0xe0e0db3b,0x32326456,0x3a3a744e,0x0a0a141e,
+       0x494992db,0x06060c0a,0x2424486c,0x5c5cb8e4,
+       0xc2c29f5d,0xd3d3bd6e,0xacac43ef,0x6262c4a6,
+       0x919139a8,0x959531a4,0xe4e4d337,0x7979f28b,
+       0xe7e7d532,0xc8c88b43,0x37376e59,0x6d6ddab7,
+       0x8d8d018c,0xd5d5b164,0x4e4e9cd2,0xa9a949e0,
+       0x6c6cd8b4,0x5656acfa,0xf4f4f307,0xeaeacf25,
+       0x6565caaf,0x7a7af48e,0xaeae47e9,0x08081018,
+       0xbaba6fd5,0x7878f088,0x25254a6f,0x2e2e5c72,
+       0x1c1c3824,0xa6a657f1,0xb4b473c7,0xc6c69751,
+       0xe8e8cb23,0xdddda17c,0x7474e89c,0x1f1f3e21,
+       0x4b4b96dd,0xbdbd61dc,0x8b8b0d86,0x8a8a0f85,
+       0x7070e090,0x3e3e7c42,0xb5b571c4,0x6666ccaa,
+       0x484890d8,0x03030605,0xf6f6f701,0x0e0e1c12,
+       0x6161c2a3,0x35356a5f,0x5757aef9,0xb9b969d0,
+       0x86861791,0xc1c19958,0x1d1d3a27,0x9e9e27b9,
+       0xe1e1d938,0xf8f8eb13,0x98982bb3,0x11112233,
+       0x6969d2bb,0xd9d9a970,0x8e8e0789,0x949433a7,
+       0x9b9b2db6,0x1e1e3c22,0x87871592,0xe9e9c920,
+       0xcece8749,0x5555aaff,0x28285078,0xdfdfa57a,
+       0x8c8c038f,0xa1a159f8,0x89890980,0x0d0d1a17,
+       0xbfbf65da,0xe6e6d731,0x424284c6,0x6868d0b8,
+       0x414182c3,0x999929b0,0x2d2d5a77,0x0f0f1e11,
+       0xb0b07bcb,0x5454a8fc,0xbbbb6dd6,0x16162c3a,
+      },{ 
+       0x63c6a563,0x7cf8847c,0x77ee9977,0x7bf68d7b,
+       0xf2ff0df2,0x6bd6bd6b,0x6fdeb16f,0xc59154c5,
+       0x30605030,0x01020301,0x67cea967,0x2b567d2b,
+       0xfee719fe,0xd7b562d7,0xab4de6ab,0x76ec9a76,
+       0xca8f45ca,0x821f9d82,0xc98940c9,0x7dfa877d,
+       0xfaef15fa,0x59b2eb59,0x478ec947,0xf0fb0bf0,
+       0xad41ecad,0xd4b367d4,0xa25ffda2,0xaf45eaaf,
+       0x9c23bf9c,0xa453f7a4,0x72e49672,0xc09b5bc0,
+       0xb775c2b7,0xfde11cfd,0x933dae93,0x264c6a26,
+       0x366c5a36,0x3f7e413f,0xf7f502f7,0xcc834fcc,
+       0x34685c34,0xa551f4a5,0xe5d134e5,0xf1f908f1,
+       0x71e29371,0xd8ab73d8,0x31625331,0x152a3f15,
+       0x04080c04,0xc79552c7,0x23466523,0xc39d5ec3,
+       0x18302818,0x9637a196,0x050a0f05,0x9a2fb59a,
+       0x070e0907,0x12243612,0x801b9b80,0xe2df3de2,
+       0xebcd26eb,0x274e6927,0xb27fcdb2,0x75ea9f75,
+       0x09121b09,0x831d9e83,0x2c58742c,0x1a342e1a,
+       0x1b362d1b,0x6edcb26e,0x5ab4ee5a,0xa05bfba0,
+       0x52a4f652,0x3b764d3b,0xd6b761d6,0xb37dceb3,
+       0x29527b29,0xe3dd3ee3,0x2f5e712f,0x84139784,
+       0x53a6f553,0xd1b968d1,0x00000000,0xedc12ced,
+       0x20406020,0xfce31ffc,0xb179c8b1,0x5bb6ed5b,
+       0x6ad4be6a,0xcb8d46cb,0xbe67d9be,0x39724b39,
+       0x4a94de4a,0x4c98d44c,0x58b0e858,0xcf854acf,
+       0xd0bb6bd0,0xefc52aef,0xaa4fe5aa,0xfbed16fb,
+       0x4386c543,0x4d9ad74d,0x33665533,0x85119485,
+       0x458acf45,0xf9e910f9,0x02040602,0x7ffe817f,
+       0x50a0f050,0x3c78443c,0x9f25ba9f,0xa84be3a8,
+       0x51a2f351,0xa35dfea3,0x4080c040,0x8f058a8f,
+       0x923fad92,0x9d21bc9d,0x38704838,0xf5f104f5,
+       0xbc63dfbc,0xb677c1b6,0xdaaf75da,0x21426321,
+       0x10203010,0xffe51aff,0xf3fd0ef3,0xd2bf6dd2,
+       0xcd814ccd,0x0c18140c,0x13263513,0xecc32fec,
+       0x5fbee15f,0x9735a297,0x4488cc44,0x172e3917,
+       0xc49357c4,0xa755f2a7,0x7efc827e,0x3d7a473d,
+       0x64c8ac64,0x5dbae75d,0x19322b19,0x73e69573,
+       0x60c0a060,0x81199881,0x4f9ed14f,0xdca37fdc,
+       0x22446622,0x2a547e2a,0x903bab90,0x880b8388,
+       0x468cca46,0xeec729ee,0xb86bd3b8,0x14283c14,
+       0xdea779de,0x5ebce25e,0x0b161d0b,0xdbad76db,
+       0xe0db3be0,0x32645632,0x3a744e3a,0x0a141e0a,
+       0x4992db49,0x060c0a06,0x24486c24,0x5cb8e45c,
+       0xc29f5dc2,0xd3bd6ed3,0xac43efac,0x62c4a662,
+       0x9139a891,0x9531a495,0xe4d337e4,0x79f28b79,
+       0xe7d532e7,0xc88b43c8,0x376e5937,0x6ddab76d,
+       0x8d018c8d,0xd5b164d5,0x4e9cd24e,0xa949e0a9,
+       0x6cd8b46c,0x56acfa56,0xf4f307f4,0xeacf25ea,
+       0x65caaf65,0x7af48e7a,0xae47e9ae,0x08101808,
+       0xba6fd5ba,0x78f08878,0x254a6f25,0x2e5c722e,
+       0x1c38241c,0xa657f1a6,0xb473c7b4,0xc69751c6,
+       0xe8cb23e8,0xdda17cdd,0x74e89c74,0x1f3e211f,
+       0x4b96dd4b,0xbd61dcbd,0x8b0d868b,0x8a0f858a,
+       0x70e09070,0x3e7c423e,0xb571c4b5,0x66ccaa66,
+       0x4890d848,0x03060503,0xf6f701f6,0x0e1c120e,
+       0x61c2a361,0x356a5f35,0x57aef957,0xb969d0b9,
+       0x86179186,0xc19958c1,0x1d3a271d,0x9e27b99e,
+       0xe1d938e1,0xf8eb13f8,0x982bb398,0x11223311,
+       0x69d2bb69,0xd9a970d9,0x8e07898e,0x9433a794,
+       0x9b2db69b,0x1e3c221e,0x87159287,0xe9c920e9,
+       0xce8749ce,0x55aaff55,0x28507828,0xdfa57adf,
+       0x8c038f8c,0xa159f8a1,0x89098089,0x0d1a170d,
+       0xbf65dabf,0xe6d731e6,0x4284c642,0x68d0b868,
+       0x4182c341,0x9929b099,0x2d5a772d,0x0f1e110f,
+       0xb07bcbb0,0x54a8fc54,0xbb6dd6bb,0x162c3a16,
+      },{ 
+       0xc6a56363,0xf8847c7c,0xee997777,0xf68d7b7b,
+       0xff0df2f2,0xd6bd6b6b,0xdeb16f6f,0x9154c5c5,
+       0x60503030,0x02030101,0xcea96767,0x567d2b2b,
+       0xe719fefe,0xb562d7d7,0x4de6abab,0xec9a7676,
+       0x8f45caca,0x1f9d8282,0x8940c9c9,0xfa877d7d,
+       0xef15fafa,0xb2eb5959,0x8ec94747,0xfb0bf0f0,
+       0x41ecadad,0xb367d4d4,0x5ffda2a2,0x45eaafaf,
+       0x23bf9c9c,0x53f7a4a4,0xe4967272,0x9b5bc0c0,
+       0x75c2b7b7,0xe11cfdfd,0x3dae9393,0x4c6a2626,
+       0x6c5a3636,0x7e413f3f,0xf502f7f7,0x834fcccc,
+       0x685c3434,0x51f4a5a5,0xd134e5e5,0xf908f1f1,
+       0xe2937171,0xab73d8d8,0x62533131,0x2a3f1515,
+       0x080c0404,0x9552c7c7,0x46652323,0x9d5ec3c3,
+       0x30281818,0x37a19696,0x0a0f0505,0x2fb59a9a,
+       0x0e090707,0x24361212,0x1b9b8080,0xdf3de2e2,
+       0xcd26ebeb,0x4e692727,0x7fcdb2b2,0xea9f7575,
+       0x121b0909,0x1d9e8383,0x58742c2c,0x342e1a1a,
+       0x362d1b1b,0xdcb26e6e,0xb4ee5a5a,0x5bfba0a0,
+       0xa4f65252,0x764d3b3b,0xb761d6d6,0x7dceb3b3,
+       0x527b2929,0xdd3ee3e3,0x5e712f2f,0x13978484,
+       0xa6f55353,0xb968d1d1,0x00000000,0xc12ceded,
+       0x40602020,0xe31ffcfc,0x79c8b1b1,0xb6ed5b5b,
+       0xd4be6a6a,0x8d46cbcb,0x67d9bebe,0x724b3939,
+       0x94de4a4a,0x98d44c4c,0xb0e85858,0x854acfcf,
+       0xbb6bd0d0,0xc52aefef,0x4fe5aaaa,0xed16fbfb,
+       0x86c54343,0x9ad74d4d,0x66553333,0x11948585,
+       0x8acf4545,0xe910f9f9,0x04060202,0xfe817f7f,
+       0xa0f05050,0x78443c3c,0x25ba9f9f,0x4be3a8a8,
+       0xa2f35151,0x5dfea3a3,0x80c04040,0x058a8f8f,
+       0x3fad9292,0x21bc9d9d,0x70483838,0xf104f5f5,
+       0x63dfbcbc,0x77c1b6b6,0xaf75dada,0x42632121,
+       0x20301010,0xe51affff,0xfd0ef3f3,0xbf6dd2d2,
+       0x814ccdcd,0x18140c0c,0x26351313,0xc32fecec,
+       0xbee15f5f,0x35a29797,0x88cc4444,0x2e391717,
+       0x9357c4c4,0x55f2a7a7,0xfc827e7e,0x7a473d3d,
+       0xc8ac6464,0xbae75d5d,0x322b1919,0xe6957373,
+       0xc0a06060,0x19988181,0x9ed14f4f,0xa37fdcdc,
+       0x44662222,0x547e2a2a,0x3bab9090,0x0b838888,
+       0x8cca4646,0xc729eeee,0x6bd3b8b8,0x283c1414,
+       0xa779dede,0xbce25e5e,0x161d0b0b,0xad76dbdb,
+       0xdb3be0e0,0x64563232,0x744e3a3a,0x141e0a0a,
+       0x92db4949,0x0c0a0606,0x486c2424,0xb8e45c5c,
+       0x9f5dc2c2,0xbd6ed3d3,0x43efacac,0xc4a66262,
+       0x39a89191,0x31a49595,0xd337e4e4,0xf28b7979,
+       0xd532e7e7,0x8b43c8c8,0x6e593737,0xdab76d6d,
+       0x018c8d8d,0xb164d5d5,0x9cd24e4e,0x49e0a9a9,
+       0xd8b46c6c,0xacfa5656,0xf307f4f4,0xcf25eaea,
+       0xcaaf6565,0xf48e7a7a,0x47e9aeae,0x10180808,
+       0x6fd5baba,0xf0887878,0x4a6f2525,0x5c722e2e,
+       0x38241c1c,0x57f1a6a6,0x73c7b4b4,0x9751c6c6,
+       0xcb23e8e8,0xa17cdddd,0xe89c7474,0x3e211f1f,
+       0x96dd4b4b,0x61dcbdbd,0x0d868b8b,0x0f858a8a,
+       0xe0907070,0x7c423e3e,0x71c4b5b5,0xccaa6666,
+       0x90d84848,0x06050303,0xf701f6f6,0x1c120e0e,
+       0xc2a36161,0x6a5f3535,0xaef95757,0x69d0b9b9,
+       0x17918686,0x9958c1c1,0x3a271d1d,0x27b99e9e,
+       0xd938e1e1,0xeb13f8f8,0x2bb39898,0x22331111,
+       0xd2bb6969,0xa970d9d9,0x07898e8e,0x33a79494,
+       0x2db69b9b,0x3c221e1e,0x15928787,0xc920e9e9,
+       0x8749cece,0xaaff5555,0x50782828,0xa57adfdf,
+       0x038f8c8c,0x59f8a1a1,0x09808989,0x1a170d0d,
+       0x65dabfbf,0xd731e6e6,0x84c64242,0xd0b86868,
+       0x82c34141,0x29b09999,0x5a772d2d,0x1e110f0f,
+       0x7bcbb0b0,0xa8fc5454,0x6dd6bbbb,0x2c3a1616,
+      },
+#endif /* !AES_SMALL */
+    }
+  };
diff --git a/aes-encrypt.c b/aes-encrypt.c
new file mode 100644 (file)
index 0000000..19fe071
--- /dev/null
@@ -0,0 +1,45 @@
+/* aes-encrypt.c
+ *
+ * Encryption function for the aes/rijndael block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "aes-internal.h"
+
+/* The main point on this function is to help the assembler
+   implementations of _nettle_aes_encrypt to get the table pointer.
+   For PIC code, the details can be complex and system dependent. */
+void
+aes_encrypt(const struct aes_ctx *ctx,
+           unsigned length, uint8_t *dst,
+           const uint8_t *src)
+{
+  assert(!(length % AES_BLOCK_SIZE) );
+  _aes_encrypt(ctx, &_aes_encrypt_table,
+              length, dst, src);
+}
diff --git a/aes-internal.h b/aes-internal.h
new file mode 100644 (file)
index 0000000..a1e8d02
--- /dev/null
@@ -0,0 +1,96 @@
+/* aes-internal.h
+ *
+ * The aes/rijndael block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_AES_INTERNAL_H_INCLUDED
+#define NETTLE_AES_INTERNAL_H_INCLUDED
+
+#include "aes.h"
+
+/* Name mangling */
+#define _aes_encrypt _nettle_aes_encrypt
+#define _aes_decrypt _nettle_aes_decrypt
+#define _aes_encrypt_table _nettle_aes_encrypt_table
+
+/* Define to use only small tables. */
+#ifndef AES_SMALL
+# define AES_SMALL 0
+#endif
+
+#if AES_SMALL
+# define AES_TABLE_SIZE 1
+#else
+# define AES_TABLE_SIZE 4
+#endif
+
+struct aes_table
+{
+  uint8_t sbox[0x100];
+  uint32_t table[AES_TABLE_SIZE][0x100];
+};
+
+void
+_aes_encrypt(const struct aes_ctx *ctx,
+            const struct aes_table *T,
+            unsigned length, uint8_t *dst,
+            const uint8_t *src);
+
+void
+_aes_decrypt(const struct aes_ctx *ctx,
+            const struct aes_table *T,
+            unsigned length, uint8_t *dst,
+            const uint8_t *src);
+
+/* Macros */
+#define ROTBYTE(x) (((x) >> 8) | (((x) & 0xff) << 24))
+#define ROTRBYTE(x) (((x) << 8) | (((x) >> 24) & 0xff))
+#define SUBBYTE(x, box) (((box)[((x) & 0xff)]) | \
+                        ((box)[(((x) >> 8) & 0xff)] << 8) | \
+                        ((box)[(((x) >> 16) & 0xff)] << 16) | \
+                        ((box)[(((x) >> 24) & 0xff)] << 24))
+
+/* Get the byte with index 0, 1, 2 and 3 */
+#define B0(x) ((x) & 0xff)
+#define B1(x) (((x) >> 8) & 0xff)
+#define B2(x) (((x) >> 16) & 0xff)
+#define B3(x) (((x) >> 24) & 0xff)
+
+#define AES_ROUND(T, w0, w1, w2, w3, k)                \
+((  T->table[0][ B0(w0) ]                      \
+  ^ T->table[1][ B1(w1) ]                      \
+  ^ T->table[2][ B2(w2) ]                      \
+  ^ T->table[3][ B3(w3) ]) ^ (k))
+
+#define AES_FINAL_ROUND(T, w0, w1, w2, w3, k)          \
+((   (uint32_t) T->sbox[ B0(w0) ]                      \
+  | ((uint32_t) T->sbox[ B1(w1) ] << 8)                        \
+  | ((uint32_t) T->sbox[ B2(w2) ] << 16)               \
+  | ((uint32_t) T->sbox[ B3(w3) ] << 24)) ^ (k))
+     
+/* Globally visible so that the same sbox table can be used by aes_set_encrypt_key */
+
+extern const struct aes_table _aes_encrypt_table;
+#define aes_sbox (_aes_encrypt_table.sbox)
+
+#endif /* NETTLE_AES_INTERNAL_H_INCLUDED */
diff --git a/aes-meta.c b/aes-meta.c
new file mode 100644 (file)
index 0000000..7b6fc5a
--- /dev/null
@@ -0,0 +1,38 @@
+/* aes-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "aes.h"
+
+const struct nettle_cipher nettle_aes128
+= _NETTLE_CIPHER_SEP(aes, AES, 128);
+
+const struct nettle_cipher nettle_aes192
+= _NETTLE_CIPHER_SEP(aes, AES, 192);
+
+const struct nettle_cipher nettle_aes256
+= _NETTLE_CIPHER_SEP(aes, AES, 256);
diff --git a/aes-set-decrypt-key.c b/aes-set-decrypt-key.c
new file mode 100644 (file)
index 0000000..ec44118
--- /dev/null
@@ -0,0 +1,186 @@
+/* aes-set-decrypt-key.c
+ *
+ * Inverse key setup for the aes/rijndael block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2000, 2001, 2002 Rafael R. Sevilla, Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* Originally written by Rafael R. Sevilla <dido@pacific.net.ph> */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "aes-internal.h"
+
+/* Tables for computations in the AES GF2 field. */
+static const uint8_t gf2_log[0x100] =
+{
+  0x00,0x00,0x19,0x01,0x32,0x02,0x1a,0xc6,
+  0x4b,0xc7,0x1b,0x68,0x33,0xee,0xdf,0x03,
+  0x64,0x04,0xe0,0x0e,0x34,0x8d,0x81,0xef,
+  0x4c,0x71,0x08,0xc8,0xf8,0x69,0x1c,0xc1,
+  0x7d,0xc2,0x1d,0xb5,0xf9,0xb9,0x27,0x6a,
+  0x4d,0xe4,0xa6,0x72,0x9a,0xc9,0x09,0x78,
+  0x65,0x2f,0x8a,0x05,0x21,0x0f,0xe1,0x24,
+  0x12,0xf0,0x82,0x45,0x35,0x93,0xda,0x8e,
+  0x96,0x8f,0xdb,0xbd,0x36,0xd0,0xce,0x94,
+  0x13,0x5c,0xd2,0xf1,0x40,0x46,0x83,0x38,
+  0x66,0xdd,0xfd,0x30,0xbf,0x06,0x8b,0x62,
+  0xb3,0x25,0xe2,0x98,0x22,0x88,0x91,0x10,
+  0x7e,0x6e,0x48,0xc3,0xa3,0xb6,0x1e,0x42,
+  0x3a,0x6b,0x28,0x54,0xfa,0x85,0x3d,0xba,
+  0x2b,0x79,0x0a,0x15,0x9b,0x9f,0x5e,0xca,
+  0x4e,0xd4,0xac,0xe5,0xf3,0x73,0xa7,0x57,
+  0xaf,0x58,0xa8,0x50,0xf4,0xea,0xd6,0x74,
+  0x4f,0xae,0xe9,0xd5,0xe7,0xe6,0xad,0xe8,
+  0x2c,0xd7,0x75,0x7a,0xeb,0x16,0x0b,0xf5,
+  0x59,0xcb,0x5f,0xb0,0x9c,0xa9,0x51,0xa0,
+  0x7f,0x0c,0xf6,0x6f,0x17,0xc4,0x49,0xec,
+  0xd8,0x43,0x1f,0x2d,0xa4,0x76,0x7b,0xb7,
+  0xcc,0xbb,0x3e,0x5a,0xfb,0x60,0xb1,0x86,
+  0x3b,0x52,0xa1,0x6c,0xaa,0x55,0x29,0x9d,
+  0x97,0xb2,0x87,0x90,0x61,0xbe,0xdc,0xfc,
+  0xbc,0x95,0xcf,0xcd,0x37,0x3f,0x5b,0xd1,
+  0x53,0x39,0x84,0x3c,0x41,0xa2,0x6d,0x47,
+  0x14,0x2a,0x9e,0x5d,0x56,0xf2,0xd3,0xab,
+  0x44,0x11,0x92,0xd9,0x23,0x20,0x2e,0x89,
+  0xb4,0x7c,0xb8,0x26,0x77,0x99,0xe3,0xa5,
+  0x67,0x4a,0xed,0xde,0xc5,0x31,0xfe,0x18,
+  0x0d,0x63,0x8c,0x80,0xc0,0xf7,0x70,0x07,
+};
+
+static const uint8_t gf2_exp[0x100] =
+{
+  0x01,0x03,0x05,0x0f,0x11,0x33,0x55,0xff,
+  0x1a,0x2e,0x72,0x96,0xa1,0xf8,0x13,0x35,
+  0x5f,0xe1,0x38,0x48,0xd8,0x73,0x95,0xa4,
+  0xf7,0x02,0x06,0x0a,0x1e,0x22,0x66,0xaa,
+  0xe5,0x34,0x5c,0xe4,0x37,0x59,0xeb,0x26,
+  0x6a,0xbe,0xd9,0x70,0x90,0xab,0xe6,0x31,
+  0x53,0xf5,0x04,0x0c,0x14,0x3c,0x44,0xcc,
+  0x4f,0xd1,0x68,0xb8,0xd3,0x6e,0xb2,0xcd,
+  0x4c,0xd4,0x67,0xa9,0xe0,0x3b,0x4d,0xd7,
+  0x62,0xa6,0xf1,0x08,0x18,0x28,0x78,0x88,
+  0x83,0x9e,0xb9,0xd0,0x6b,0xbd,0xdc,0x7f,
+  0x81,0x98,0xb3,0xce,0x49,0xdb,0x76,0x9a,
+  0xb5,0xc4,0x57,0xf9,0x10,0x30,0x50,0xf0,
+  0x0b,0x1d,0x27,0x69,0xbb,0xd6,0x61,0xa3,
+  0xfe,0x19,0x2b,0x7d,0x87,0x92,0xad,0xec,
+  0x2f,0x71,0x93,0xae,0xe9,0x20,0x60,0xa0,
+  0xfb,0x16,0x3a,0x4e,0xd2,0x6d,0xb7,0xc2,
+  0x5d,0xe7,0x32,0x56,0xfa,0x15,0x3f,0x41,
+  0xc3,0x5e,0xe2,0x3d,0x47,0xc9,0x40,0xc0,
+  0x5b,0xed,0x2c,0x74,0x9c,0xbf,0xda,0x75,
+  0x9f,0xba,0xd5,0x64,0xac,0xef,0x2a,0x7e,
+  0x82,0x9d,0xbc,0xdf,0x7a,0x8e,0x89,0x80,
+  0x9b,0xb6,0xc1,0x58,0xe8,0x23,0x65,0xaf,
+  0xea,0x25,0x6f,0xb1,0xc8,0x43,0xc5,0x54,
+  0xfc,0x1f,0x21,0x63,0xa5,0xf4,0x07,0x09,
+  0x1b,0x2d,0x77,0x99,0xb0,0xcb,0x46,0xca,
+  0x45,0xcf,0x4a,0xde,0x79,0x8b,0x86,0x91,
+  0xa8,0xe3,0x3e,0x42,0xc6,0x51,0xf3,0x0e,
+  0x12,0x36,0x5a,0xee,0x29,0x7b,0x8d,0x8c,
+  0x8f,0x8a,0x85,0x94,0xa7,0xf2,0x0d,0x17,
+  0x39,0x4b,0xdd,0x7c,0x84,0x97,0xa2,0xfd,
+  0x1c,0x24,0x6c,0xb4,0xc7,0x52,0xf6,0x01,
+};
+
+static unsigned
+mult(unsigned a, unsigned b)
+{
+  return (a && b) ? gf2_exp[ (gf2_log[a] + gf2_log[b]) % 255] : 0;
+}
+
+static void
+inv_mix_column(uint32_t *a)
+{
+  uint8_t c[4][4];
+  unsigned i, j;
+       
+  for (j = 0; j < 4; j++)
+    {
+      for(i = 0; i < 4; i++)
+       {
+         c[j][i] = mult(0xe, (a[j] >> i*8) & 0xff)
+           ^ mult(0xb, (a[j] >> ((i+1)%4)*8) & 0xff)
+           ^ mult(0xd, (a[j] >> ((i+2)%4)*8) & 0xff)
+           ^ mult(0x9, (a[j] >> ((i+3)%4)*8) & 0xff);
+       }
+    }
+  for (i = 0; i < 4; i++)
+    {
+      a[i] = 0;
+      for(j = 0; j < 4; j++)
+       a[i] |= c[i][j] << (j*8);
+    }
+}
+
+#define SWAP(a, b) \
+do { uint32_t t_swap = (a); (a) = (b); (b) = t_swap; } while(0)
+
+void
+aes_invert_key(struct aes_ctx *dst,
+              const struct aes_ctx *src)
+{
+  unsigned nrounds;
+  unsigned i;
+
+  nrounds = src->nrounds;
+
+  /* Reverse the order of subkeys, in groups of 4. */
+  /* FIXME: Instead of reordering the subkeys, change the access order
+     of aes_decrypt, since it's a separate function anyway? */
+  if (src == dst)
+    {
+      unsigned j, k;
+
+      for (i = 0, j = nrounds * 4;
+          i < j;
+          i += 4, j -= 4)
+       for (k = 0; k<4; k++)
+         SWAP(dst->keys[i+k], dst->keys[j+k]);
+    }
+  else
+    {
+      unsigned k;
+
+      dst->nrounds = nrounds;
+      for (i = 0; i <= nrounds * 4; i += 4)
+       for (k = 0; k < 4; k++)
+         dst->keys[i+k] = src->keys[nrounds * 4 - i + k];
+    }
+
+  /* Transform all subkeys but the first and last. */
+  for (i = 4; i < 4 * nrounds; i += 4)
+    inv_mix_column(dst->keys + i);
+}
+
+void
+aes_set_decrypt_key(struct aes_ctx *ctx,
+                   unsigned keysize, const uint8_t *key)
+{
+  /* We first create subkeys for encryption,
+   * then modify the subkeys for decryption. */
+  aes_set_encrypt_key(ctx, keysize, key);
+  aes_invert_key(ctx, ctx);
+}
+
diff --git a/aes-set-encrypt-key.c b/aes-set-encrypt-key.c
new file mode 100644 (file)
index 0000000..9c60c03
--- /dev/null
@@ -0,0 +1,96 @@
+/* aes-set-encrypt-key.c
+ *
+ * Key setup for the aes/rijndael block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2000, 2001, 2002 Rafael R. Sevilla, Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* Originally written by Rafael R. Sevilla <dido@pacific.net.ph> */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "aes-internal.h"
+
+static unsigned
+xtime(unsigned x)
+{
+  assert (x < 0x100);
+
+  x <<= 1;
+  if (x & 0x100)
+    x ^= 0x11b;
+
+  assert (x < 0x100);
+
+  return x;
+}
+
+void
+aes_set_encrypt_key(struct aes_ctx *ctx,
+                   unsigned keysize, const uint8_t *key)
+{
+  unsigned nk, nr, i, lastkey;
+  uint32_t temp, rcon;
+
+  assert(keysize >= AES_MIN_KEY_SIZE);
+  assert(keysize <= AES_MAX_KEY_SIZE);
+  
+  /* Truncate keysizes to the valid key sizes provided by Rijndael */
+  if (keysize == 32) {
+    nk = 8;
+    nr = 14;
+  } else if (keysize >= 24) {
+    nk = 6;
+    nr = 12;
+  } else { /* must be 16 or more */
+    nk = 4;
+    nr = 10;
+  }
+
+  lastkey = (AES_BLOCK_SIZE/4) * (nr + 1);
+  ctx->nrounds = nr;
+  rcon = 1;
+  for (i=0; i<nk; i++)
+    {
+      ctx->keys[i] = key[i*4] + (key[i*4+1]<<8) + (key[i*4+2]<<16) +
+       (key[i*4+3]<<24);
+    }
+
+  for (i=nk; i<lastkey; i++)
+    {
+      temp = ctx->keys[i-1];
+      if (i % nk == 0)
+       {
+         temp = SUBBYTE(ROTBYTE(temp), aes_sbox) ^ rcon;
+         rcon = (uint32_t)xtime((uint8_t)rcon&0xff);
+       }
+      else if (nk > 6 && (i%nk) == 4)
+       {
+         temp = SUBBYTE(temp, aes_sbox);
+       }
+      ctx->keys[i] = ctx->keys[i-nk] ^ temp;
+    }
+}
+  
diff --git a/aes.h b/aes.h
new file mode 100644 (file)
index 0000000..23cc0cf
--- /dev/null
+++ b/aes.h
@@ -0,0 +1,85 @@
+/* aes.h
+ *
+ * The aes/rijndael block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_AES_H_INCLUDED
+#define NETTLE_AES_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define aes_set_encrypt_key nettle_aes_set_encrypt_key
+#define aes_set_decrypt_key nettle_aes_set_decrypt_key
+#define aes_invert_key nettle_aes_invert_key
+#define aes_encrypt nettle_aes_encrypt
+#define aes_decrypt nettle_aes_decrypt
+
+#define AES_BLOCK_SIZE 16
+
+/* Variable key size between 128 and 256 bits. But the only valid
+ * values are 16 (128 bits), 24 (192 bits) and 32 (256 bits). */
+#define AES_MIN_KEY_SIZE 16
+#define AES_MAX_KEY_SIZE 32
+
+#define AES_KEY_SIZE 32
+
+/* FIXME: Change to put nrounds first, to make it possible to use a
+   truncated ctx struct, with less subkeys, for the shorter key
+   sizes? */
+struct aes_ctx
+{
+  uint32_t keys[60];  /* maximum size of key schedule */
+  unsigned  nrounds;  /* number of rounds to use for our key size */
+};
+
+void
+aes_set_encrypt_key(struct aes_ctx *ctx,
+                   unsigned length, const uint8_t *key);
+
+void
+aes_set_decrypt_key(struct aes_ctx *ctx,
+                  unsigned length, const uint8_t *key);
+
+void
+aes_invert_key(struct aes_ctx *dst,
+              const struct aes_ctx *src);
+
+void
+aes_encrypt(const struct aes_ctx *ctx,
+           unsigned length, uint8_t *dst,
+           const uint8_t *src);
+void
+aes_decrypt(const struct aes_ctx *ctx,
+           unsigned length, uint8_t *dst,
+           const uint8_t *src);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_AES_H_INCLUDED */
diff --git a/aesdata.c b/aesdata.c
new file mode 100644 (file)
index 0000000..9077c54
--- /dev/null
+++ b/aesdata.c
@@ -0,0 +1,299 @@
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "nettle-types.h"
+
+#if 1
+# define BYTE_FORMAT "0x%02x"
+# define BYTE_COLUMNS 8
+#else
+# define BYTE_FORMAT "%3d"
+# define BYTE_COLUMNS 0x10
+#endif
+
+#define WORD_FORMAT "0x%08x"
+#define WORD_COLUMNS 4
+
+uint8_t sbox[0x100];
+uint8_t isbox[0x100];
+
+uint8_t gf2_log[0x100];
+uint8_t gf2_exp[0x100];
+
+uint32_t dtable[4][0x100];
+uint32_t itable[4][0x100];
+
+static unsigned
+xtime(unsigned x)
+{
+  assert (x < 0x100);
+
+  x <<= 1;
+  if (x & 0x100)
+    x ^= 0x11b;
+
+  assert (x < 0x100);
+
+  return x;
+}
+
+/* Computes the exponentiatiom and logarithm tables for GF_2, to the
+ * base x+1 (0x03). The unit element is 1 (0x01).*/
+static void
+compute_log(void)
+{
+  unsigned i = 0;
+  unsigned x = 1;
+
+  memset(gf2_log, 0, 0x100);
+  
+  for (i = 0; i < 0x100; i++, x = x ^ xtime(x))
+    {
+      gf2_exp[i] = x;
+      gf2_log[x] = i;
+    }
+  /* Invalid. */
+  gf2_log[0] = 0;
+  /* The loop above sets gf2_log[1] = 0xff, which is correct,
+   * but gf2_log[1] = 0 is nicer. */
+  gf2_log[1] = 0;
+}
+
+static unsigned
+mult(unsigned a, unsigned b)
+{
+  return (a && b) ? gf2_exp[ (gf2_log[a] + gf2_log[b]) % 255] : 0;
+}
+
+static unsigned
+invert(unsigned x)
+{
+  return x ? gf2_exp[0xff - gf2_log[x]] : 0;
+}
+
+static unsigned
+affine(unsigned x)
+{
+  return 0xff &
+    (0x63^x^(x>>4)^(x<<4)^(x>>5)^(x<<3)^(x>>6)^(x<<2)^(x>>7)^(x<<1));
+}
+     
+static void
+compute_sbox(void)
+{
+  unsigned i;
+  for (i = 0; i<0x100; i++)
+    {
+      sbox[i] = affine(invert(i));
+      isbox[sbox[i]] = i;
+    }
+}
+
+/* Generate little endian tables, i.e. the first row of the AES state
+ * arrays occupies the least significant byte of the words.
+ *
+ * The sbox values are multiplied with the column of GF2 coefficients
+ * of the polynomial 03 x^3 + x^2 + x + 02. */
+static void
+compute_dtable(void)
+{
+  unsigned i;
+  for (i = 0; i<0x100; i++)
+    {
+      unsigned s = sbox[i];
+      unsigned j;
+      uint32_t t  =( ( (s ^ xtime(s)) << 24)
+                    | (s << 16) | (s << 8)
+                    | xtime(s) );
+
+      for (j = 0; j<4; j++, t = (t << 8) | (t >> 24))
+       dtable[j][i] = t;
+    }
+}
+
+/* The inverse sbox values are multiplied with the column of GF2 coefficients
+ * of the polynomial inverse 0b x^3 + 0d x^2 + 09 x + 0e. */
+static void
+compute_itable(void)
+{
+  unsigned i;
+  for (i = 0; i<0x100; i++)
+    {
+      unsigned s = isbox[i];
+      unsigned j;
+      uint32_t t = ( (mult(s, 0xb) << 24)
+                  | (mult(s, 0xd) << 16)
+                  | (mult(s, 0x9) << 8)
+                  | (mult(s, 0xe) ));
+      
+      for (j = 0; j<4; j++, t = (t << 8) | (t >> 24))
+       itable[j][i] = t;
+    }
+}
+
+static void
+display_byte_table(const char *name, uint8_t *table)
+{
+  unsigned i, j;
+
+  printf("uint8_t %s[0x100] =\n{", name);
+
+  for (i = 0; i<0x100; i+= BYTE_COLUMNS)
+    {
+      printf("\n  ");
+      for (j = 0; j<BYTE_COLUMNS; j++)
+       printf(BYTE_FORMAT ",", table[i + j]);
+    }
+
+  printf("\n};\n\n");
+}
+
+static void
+display_table(const char *name, uint32_t table[][0x100])
+{
+  unsigned i, j, k;
+  
+  printf("uint32_t %s[4][0x100] =\n{\n  ", name);
+
+  for (k = 0; k<4; k++)
+    {
+      printf("{ ");
+      for (i = 0; i<0x100; i+= WORD_COLUMNS)
+       {
+         printf("\n    ");
+         for (j = 0; j<WORD_COLUMNS; j++)
+           printf(WORD_FORMAT ",", table[k][i + j]);
+       }
+      printf("\n  },");
+    }
+  printf("\n};\n\n");
+}
+
+static void
+display_polynomial(const unsigned *p)
+{
+  printf("(%x x^3 + %x x^2 + %x x + %x)",
+        p[3], p[2], p[1], p[0]);
+}
+
+int
+main(int argc, char **argv)
+{
+  compute_log();
+  if (argc == 1)
+    {
+      display_byte_table("gf2_log", gf2_log);
+      display_byte_table("gf2_exp", gf2_exp);
+
+      compute_sbox();
+      display_byte_table("sbox", sbox);
+      display_byte_table("isbox", isbox);
+
+      compute_dtable();
+      display_table("dtable", dtable);
+
+      compute_itable();
+      display_table("itable", itable);
+  
+      return 0;
+    }
+  else if (argc == 2)
+    {
+      unsigned a;
+      for (a = 1; a<0x100; a++)
+       {
+         unsigned a1 = invert(a);
+         unsigned b;
+         unsigned u;
+         if (a1 == 0)
+           printf("invert(%x) = 0 !\n", a);
+
+         u = mult(a, a1);
+         if (u != 1)
+           printf("invert(%x) = %x; product = %x\n",
+                  a, a1, u);
+         
+         for (b = 1; b<0x100; b++)
+           {
+             unsigned b1 = invert(b);
+             unsigned c = mult(a, b);
+
+             if (c == 0)
+               printf("%x x %x = 0\n", a, b);
+
+             u = mult(c, a1);
+             if (u != b)
+               printf("%x x %x = %x, invert(%x) = %x, %x x %x = %x\n",
+                      a, b, c, a, a1, c, a1, u);
+             
+             u = mult(c, b1);
+             if (u != a)
+               printf("%x x %x = %x, invert(%x) = %x, %x x %x = %x\n",
+                      a, b, c, b, b1, c, b1, u);
+           }
+       }
+      return 0;
+    }
+  else if (argc == 4)
+    {
+      unsigned a, b, c;
+      int op = argv[2][0];
+      a = strtoul(argv[1], NULL, 16);
+      b = strtoul(argv[3], NULL, 16);
+      switch (op)
+       {
+       case '+':
+         c = a ^ b;
+         break;
+       case '*':
+       case 'x':
+         c = mult(a,b);
+         break;
+       case '/':
+         c = mult(a, invert(b));
+         break;
+       default:
+         return 1;
+       }
+      printf("%x %c %x = %x\n", a, op, b, c);
+      return 0;
+    }
+#if 0
+  else if (argc == 5)
+    {
+      /* Compute gcd(a, x^4+1) */
+      unsigned d[4];
+      unsigned u[4];
+      
+      for (i = 0; i<4; i++)
+       a[i] = strtoul(argv[1+i], NULL, 16);
+    }
+#endif
+  else if (argc == 9)
+    {
+      unsigned a[4];
+      unsigned b[4];
+      unsigned c[4];
+      unsigned i;
+      for (i = 0; i<4; i++)
+       {
+         a[i] = strtoul(argv[1+i], NULL, 16);
+         b[i] = strtoul(argv[5+i], NULL, 16);
+       }
+
+      c[0] = mult(a[0],b[0])^mult(a[3],b[1])^mult(a[2],b[2])^mult(a[1],b[3]);
+      c[1] = mult(a[1],b[0])^mult(a[0],b[1])^mult(a[3],b[2])^mult(a[2],b[3]);
+      c[2] = mult(a[2],b[0])^mult(a[1],b[1])^mult(a[0],b[2])^mult(a[3],b[3]);
+      c[3] = mult(a[3],b[0])^mult(a[2],b[1])^mult(a[1],b[2])^mult(a[0],b[3]);
+
+      display_polynomial(a); printf(" * "); display_polynomial(b);
+      printf(" = "); display_polynomial(c); printf("\n");
+    }
+  return 1;
+}
diff --git a/arcfour-crypt.c b/arcfour-crypt.c
new file mode 100644 (file)
index 0000000..78f6831
--- /dev/null
@@ -0,0 +1,53 @@
+/* arcfour-crypt.c
+ *
+ * The arcfour/rc4 stream cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2004 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "arcfour.h"
+
+void
+arcfour_crypt(struct arcfour_ctx *ctx,
+             unsigned length, uint8_t *dst,
+             const uint8_t *src)
+{
+  register uint8_t i, j;
+  register int si, sj;
+
+  i = ctx->i; j = ctx->j;
+  while(length--)
+    {
+      i++; i &= 0xff;
+      si = ctx->S[i];
+      j += si; j &= 0xff;
+      sj = ctx->S[i] = ctx->S[j];
+      ctx->S[j] = si;
+      *dst++ = *src++ ^ ctx->S[ (si + sj) & 0xff ];
+    }
+  ctx->i = i; ctx->j = j;
+}
diff --git a/arcfour-meta.c b/arcfour-meta.c
new file mode 100644 (file)
index 0000000..d5f1467
--- /dev/null
@@ -0,0 +1,38 @@
+/* arcfour-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "arcfour.h"
+
+const struct nettle_cipher nettle_arcfour128 =
+  { "arcfour128", sizeof(struct arcfour_ctx),
+    0, 16,
+    (nettle_set_key_func *) arcfour_set_key,
+    (nettle_set_key_func *) arcfour_set_key,
+    (nettle_crypt_func *) arcfour_crypt,
+    (nettle_crypt_func *) arcfour_crypt
+  };
diff --git a/arcfour.c b/arcfour.c
new file mode 100644 (file)
index 0000000..3e15a40
--- /dev/null
+++ b/arcfour.c
@@ -0,0 +1,58 @@
+/* arcfour.c
+ *
+ * The arcfour/rc4 stream cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "arcfour.h"
+
+#define SWAP(a,b) do { int _t = a; a = b; b = _t; } while(0)
+
+void
+arcfour_set_key(struct arcfour_ctx *ctx,
+               unsigned length, const uint8_t *key)
+{
+  unsigned i, j, k;
+  
+  assert(length >= ARCFOUR_MIN_KEY_SIZE);
+  assert(length <= ARCFOUR_MAX_KEY_SIZE);
+
+  /* Initialize context */
+  for (i = 0; i<256; i++)
+    ctx->S[i] = i;
+
+  for (i = j = k = 0; i<256; i++)
+    {
+      j += ctx->S[i] + key[k]; j &= 0xff;
+      SWAP(ctx->S[i], ctx->S[j]);
+      /* Repeat key as needed */
+      k = (k + 1) % length;
+    }
+  ctx->i = ctx->j = 0;
+}
+
diff --git a/arcfour.h b/arcfour.h
new file mode 100644 (file)
index 0000000..7ef21f0
--- /dev/null
+++ b/arcfour.h
@@ -0,0 +1,70 @@
+/* arcfour.h
+ *
+ * The arcfour/rc4 stream cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_ARCFOUR_H_INCLUDED
+#define NETTLE_ARCFOUR_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define arcfour_set_key nettle_arcfour_set_key
+#define arcfour_crypt nettle_arcfour_crypt
+
+/* Minimum and maximum keysizes, and a reasonable default. In
+ * octets.*/
+#define ARCFOUR_MIN_KEY_SIZE 1
+#define ARCFOUR_MAX_KEY_SIZE 256
+#define ARCFOUR_KEY_SIZE 16
+
+struct arcfour_ctx
+{
+  uint8_t S[256];
+  uint8_t i;
+  uint8_t j;
+};
+
+void
+arcfour_set_key(struct arcfour_ctx *ctx,
+               unsigned length, const uint8_t *key);
+
+void
+arcfour_crypt(struct arcfour_ctx *ctx,
+             unsigned length, uint8_t *dst,
+             const uint8_t *src);
+
+void
+arcfour_stream(struct arcfour_ctx *ctx,
+              unsigned length, uint8_t *dst);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_ARCFOUR_H_INCLUDED */
+
diff --git a/arctwo-meta.c b/arctwo-meta.c
new file mode 100644 (file)
index 0000000..3401b9d
--- /dev/null
@@ -0,0 +1,48 @@
+/* arctwo-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2004 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "arctwo.h"
+
+const struct nettle_cipher nettle_arctwo40
+= _NETTLE_CIPHER (arctwo, ARCTWO, 40);
+
+const struct nettle_cipher nettle_arctwo64
+= _NETTLE_CIPHER (arctwo, ARCTWO, 64);
+
+const struct nettle_cipher nettle_arctwo128
+= _NETTLE_CIPHER (arctwo, ARCTWO, 128);
+
+/* Map Gutmann variant. */
+#define arctwo_gutmann_ctx arctwo_ctx
+#define arctwo_gutmann_encrypt arctwo_encrypt
+#define arctwo_gutmann_decrypt arctwo_decrypt
+#define arctwo_gutmann_ctx arctwo_ctx
+#define arctwo_gutmann_set_key arctwo_set_key_gutmann
+
+const struct nettle_cipher nettle_arctwo_gutmann128
+= _NETTLE_CIPHER (arctwo_gutmann, ARCTWO, 128);
diff --git a/arctwo.c b/arctwo.c
new file mode 100644 (file)
index 0000000..9793467
--- /dev/null
+++ b/arctwo.c
@@ -0,0 +1,230 @@
+/* arctwo.c
+ *
+ * The cipher described in rfc2268; aka Ron's Cipher 2.
+ */
+   
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2004 Simon Josefsson
+ * Copyright (C) 2003 Nikos Mavroyanopoulos
+ * Copyright (C) 2004 Free Software Foundation, Inc.
+ * Copyright (C) 2004 Niels Möller
+ *
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* This implementation was written by Nikos Mavroyanopoulos for GNUTLS
+ * as a Libgcrypt module (gnutls/lib/x509/rc2.c) and later adapted for
+ * direct use by Libgcrypt by Werner Koch and later adapted for direct
+ * use by Nettle by Simon Josefsson and Niels Möller.
+ *
+ * The implementation here is based on Peter Gutmann's RRC.2 paper and
+ * RFC 2268.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "arctwo.h"
+
+#include "macros.h"
+
+static const uint8_t arctwo_sbox[] = {
+  0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed,
+  0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d,
+  0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e,
+  0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2,
+  0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13,
+  0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
+  0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b,
+  0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82,
+  0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c,
+  0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc,
+  0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1,
+  0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
+  0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57,
+  0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03,
+  0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7,
+  0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7,
+  0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7,
+  0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
+  0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74,
+  0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec,
+  0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc,
+  0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39,
+  0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a,
+  0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
+  0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae,
+  0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9,
+  0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c,
+  0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9,
+  0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0,
+  0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
+  0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77,
+  0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad
+};
+
+#define rotl16(x,n) (((x) << ((uint16_t)(n))) | ((x) >> (16 - (uint16_t)(n))))
+#define rotr16(x,n) (((x) >> ((uint16_t)(n))) | ((x) << (16 - (uint16_t)(n))))
+
+void
+arctwo_encrypt (struct arctwo_ctx *ctx,
+               unsigned length, uint8_t *dst, const uint8_t *src)
+{
+  FOR_BLOCKS (length, dst, src, ARCTWO_BLOCK_SIZE)
+  {
+    register unsigned i;
+    uint16_t w0, w1, w2, w3;
+
+    w0 = LE_READ_UINT16 (&src[0]);
+    w1 = LE_READ_UINT16 (&src[2]);
+    w2 = LE_READ_UINT16 (&src[4]);
+    w3 = LE_READ_UINT16 (&src[6]);
+
+    for (i = 0; i < 16; i++)
+      {
+       register unsigned j = i * 4;
+       /* For some reason I cannot combine those steps. */
+       w0 += (w1 & ~w3) + (w2 & w3) + ctx->S[j];
+       w0 = rotl16 (w0, 1);
+
+       w1 += (w2 & ~w0) + (w3 & w0) + ctx->S[j + 1];
+       w1 = rotl16 (w1, 2);
+
+       w2 += (w3 & ~w1) + (w0 & w1) + ctx->S[j + 2];
+       w2 = rotl16 (w2, 3);
+
+       w3 += (w0 & ~w2) + (w1 & w2) + ctx->S[j + 3];
+       w3 = rotl16 (w3, 5);
+
+       if (i == 4 || i == 10)
+         {
+           w0 += ctx->S[w3 & 63];
+           w1 += ctx->S[w0 & 63];
+           w2 += ctx->S[w1 & 63];
+           w3 += ctx->S[w2 & 63];
+         }
+      }
+    LE_WRITE_UINT16 (&dst[0], w0);
+    LE_WRITE_UINT16 (&dst[2], w1);
+    LE_WRITE_UINT16 (&dst[4], w2);
+    LE_WRITE_UINT16 (&dst[6], w3);
+  }
+}
+
+void
+arctwo_decrypt (struct arctwo_ctx *ctx,
+               unsigned length, uint8_t *dst, const uint8_t *src)
+{
+  FOR_BLOCKS (length, dst, src, ARCTWO_BLOCK_SIZE)
+  {
+    register unsigned i;
+    uint16_t w0, w1, w2, w3;
+
+    w0 = LE_READ_UINT16 (&src[0]);
+    w1 = LE_READ_UINT16 (&src[2]);
+    w2 = LE_READ_UINT16 (&src[4]);
+    w3 = LE_READ_UINT16 (&src[6]);
+
+    for (i = 16; i-- > 0; )
+      {
+       register unsigned j = i * 4;
+
+       w3 = rotr16 (w3, 5);
+       w3 -= (w0 & ~w2) + (w1 & w2) + ctx->S[j + 3];
+
+       w2 = rotr16 (w2, 3);
+       w2 -= (w3 & ~w1) + (w0 & w1) + ctx->S[j + 2];
+
+       w1 = rotr16 (w1, 2);
+       w1 -= (w2 & ~w0) + (w3 & w0) + ctx->S[j + 1];
+
+       w0 = rotr16 (w0, 1);
+       w0 -= (w1 & ~w3) + (w2 & w3) + ctx->S[j];
+
+       if (i == 5 || i == 11)
+         {
+           w3 = w3 - ctx->S[w2 & 63];
+           w2 = w2 - ctx->S[w1 & 63];
+           w1 = w1 - ctx->S[w0 & 63];
+           w0 = w0 - ctx->S[w3 & 63];
+         }
+
+      }
+    LE_WRITE_UINT16 (&dst[0], w0);
+    LE_WRITE_UINT16 (&dst[2], w1);
+    LE_WRITE_UINT16 (&dst[4], w2);
+    LE_WRITE_UINT16 (&dst[6], w3);
+  }
+}
+
+void
+arctwo_set_key_ekb (struct arctwo_ctx *ctx,
+                   unsigned length, const uint8_t *key, unsigned ekb)
+{
+  unsigned i;
+  /* Expanded key, treated as octets */
+  uint8_t S[128];
+  uint8_t x;
+
+  assert (length >= ARCTWO_MIN_KEY_SIZE);
+  assert (length <= ARCTWO_MAX_KEY_SIZE);
+  assert (ekb <= 1024);
+
+  for (i = 0; i < length; i++)
+    S[i] = key[i];
+
+  /* Phase 1: Expand input key to 128 bytes */
+  for (i = length; i < ARCTWO_MAX_KEY_SIZE; i++)
+    S[i] = arctwo_sbox[(S[i - length] + S[i - 1]) & 255];
+
+  S[0] = arctwo_sbox[S[0]];
+
+  /* Reduce effective key size to ekb bits, if requested by caller. */
+  if (ekb > 0 && ekb < 1024)
+    {
+      int len = (ekb + 7) >> 3;
+      i = 128 - len;
+      x = arctwo_sbox[S[i] & (255 >> (7 & -ekb))];
+      S[i] = x;
+
+      while (i--)
+       {
+         x = arctwo_sbox[x ^ S[i + len]];
+         S[i] = x;
+       }
+    }
+
+  /* Make the expanded key endian independent. */
+  for (i = 0; i < 64; i++)
+    ctx->S[i] = LE_READ_UINT16(S + i * 2);
+}
+
+void
+arctwo_set_key (struct arctwo_ctx *ctx, unsigned length, const uint8_t *key)
+{
+  arctwo_set_key_ekb (ctx, length, key, 8 * length);
+}
+
+void
+arctwo_set_key_gutmann (struct arctwo_ctx *ctx,
+                       unsigned length, const uint8_t *key)
+{
+  arctwo_set_key_ekb (ctx, length, key, 0);
+}
diff --git a/arctwo.h b/arctwo.h
new file mode 100644 (file)
index 0000000..cf3c96d
--- /dev/null
+++ b/arctwo.h
@@ -0,0 +1,82 @@
+/* arctwo.h
+ *
+ * The arctwo/rfc2268 block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2004 Simon Josefsson
+ * Copyright (C) 2002, 2004 Niels Möller
+ *
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_ARCTWO_H_INCLUDED
+#define NETTLE_ARCTWO_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define arctwo_set_key nettle_arctwo_set_key
+#define arctwo_set_key_ekb nettle_arctwo_set_key_ekb
+#define arctwo_encrypt nettle_arctwo_encrypt
+#define arctwo_decrypt nettle_arctwo_decrypt
+#define arctwo_set_key_gutmann nettle_arctwo_set_key_gutmann
+
+#define ARCTWO_BLOCK_SIZE 8
+
+/* Variable key size from 1 byte to 128 bytes. */
+#define ARCTWO_MIN_KEY_SIZE 1
+#define ARCTWO_MAX_KEY_SIZE 128
+
+#define ARCTWO_KEY_SIZE 8
+
+struct arctwo_ctx
+{
+  uint16_t S[64];
+};
+
+/* Key expansion function that takes the "effective key bits", 1-1024,
+   as an explicit argument. 0 means maximum key bits. */
+void
+arctwo_set_key_ekb (struct arctwo_ctx *ctx,
+                   unsigned length, const uint8_t * key, unsigned ekb);
+
+/* Equvivalent to arctwo_set_key_ekb, with ekb = 8 * length */
+void
+arctwo_set_key (struct arctwo_ctx *ctx, unsigned length, const uint8_t *key);
+
+/* Equvivalent to arctwo_set_key_ekb, with ekb = 1024 */
+void
+arctwo_set_key_gutmann (struct arctwo_ctx *ctx,
+                       unsigned length, const uint8_t *key);
+
+void
+arctwo_encrypt (struct arctwo_ctx *ctx,
+               unsigned length, uint8_t *dst, const uint8_t *src);
+void
+arctwo_decrypt (struct arctwo_ctx *ctx,
+               unsigned length, uint8_t *dst, const uint8_t *src);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_ARCTWO_H_INCLUDED */
diff --git a/asm.m4 b/asm.m4
new file mode 100644 (file)
index 0000000..e2721d4
--- /dev/null
+++ b/asm.m4
@@ -0,0 +1,65 @@
+changequote(<,>)dnl
+dnl (progn (modify-syntax-entry ?< "(>") (modify-syntax-entry ?> ")<") )
+
+dnl FORTRAN style comment character
+define(<C>, <
+dnl>)dnl
+
+dnl Including files from the srcdir
+define(<include_src>, <include(srcdir/$1)>)dnl
+
+dnl Pseudo ops
+
+define(<PROLOGUE>,
+<ifelse(ELF_STYLE,yes,
+<.globl C_NAME($1)
+.type C_NAME($1),TYPE_FUNCTION
+C_NAME($1):>,
+<.globl C_NAME($1)
+C_NAME($1):>)>)
+
+define(<EPILOGUE>,
+<ifelse(ELF_STYLE,yes,
+<.size C_NAME($1), . - C_NAME($1)>,<>)>)
+
+dnl Argument to ALIGN is always logarithmic
+dnl Can't use << operator with our choice of quote characters...
+define(<ALIGN>,
+<.align ifelse(ALIGN_LOG,yes,$1,eval(2 ** $1))>)
+
+dnl Struct defining macros
+
+dnl STRUCTURE(prefix) 
+define(<STRUCTURE>, <define(<SOFFSET>, 0)define(<SPREFIX>, <$1>)>)dnl
+
+dnl STRUCT(name, size)
+define(<STRUCT>,
+<define(SPREFIX<_>$1, SOFFSET)dnl
+ define(<SOFFSET>, eval(SOFFSET + ($2)))>)dnl
+
+dnl UCHAR(name)
+define(<UCHAR>, <STRUCT(<$1>, 1)>)dnl
+
+dnl UNSIGNED(name)
+define(<UNSIGNED>, <STRUCT(<$1>, 4)>)dnl
+
+dnl Offsets in arcfour_ctx
+STRUCTURE(ARCFOUR)
+  STRUCT(S, 256)
+  UCHAR(I)
+  UCHAR(J)
+
+dnl Offsets in aes_ctx and aes_table
+STRUCTURE(AES)
+  STRUCT(KEYS, 4*60)
+  UNSIGNED(NROUNDS)
+
+define(AES_SBOX_SIZE,  256)dnl
+define(AES_TABLE_SIZE, 1024)dnl
+
+STRUCTURE(AES)
+  STRUCT(SBOX, AES_SBOX_SIZE)
+  STRUCT(TABLE0, AES_TABLE_SIZE)
+  STRUCT(TABLE1, AES_TABLE_SIZE)
+  STRUCT(TABLE2, AES_TABLE_SIZE)
+  STRUCT(TABLE3, AES_TABLE_SIZE)
diff --git a/asn1.h b/asn1.h
new file mode 100644 (file)
index 0000000..7933ce2
--- /dev/null
+++ b/asn1.h
@@ -0,0 +1,144 @@
+/* asn1.h
+ *
+ * Some very limited asn.1 support.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2005 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_ASN1_H_INCLUDED
+#define NETTLE_ASN1_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define asn1_der_iterator_first nettle_asn1_der_iterator_first
+#define asn1_der_iterator_next nettle_asn1_der_iterator_next
+#define asn1_der_decode_constructed nettle_asn1_der_decode_constructed
+#define asn1_der_decode_constructed_last nettle_asn1_der_decode_constructed_last
+#define asn1_der_decode_bitstring nettle_asn1_der_decode_bitstring
+#define asn1_der_decode_bitstring_last nettle_asn1_der_decode_bitstring_last
+#define asn1_der_get_uint32 nettle_asn1_der_get_uint32
+#define asn1_der_get_bignum nettle_asn1_der_get_bignum
+
+
+/* enum asn1_type keeps the class number and the constructive in bits
+   13-14, and the constructive flag in bit 12. The remaining 14 bits
+   are the tag (although currently, only tags in the range 0-30 are
+   supported). */
+
+enum
+  {
+    ASN1_TYPE_CONSTRUCTED = 1 << 12,
+
+    ASN1_CLASS_UNIVERSAL = 0,
+    ASN1_CLASS_APPLICATION = 1 << 13,
+    ASN1_CLASS_CONTEXT_SPECIFIC = 2 << 13,
+    ASN1_CLASS_PRIVATE = 3 << 13,
+
+    ASN1_CLASS_MASK = 3 << 13,
+    ASN1_CLASS_SHIFT = 13,
+  };
+
+enum asn1_type
+  {
+    ASN1_BOOLEAN = 1,
+    ASN1_INTEGER = 2,
+    ASN1_BITSTRING = 3,
+    ASN1_OCTETSTRING = 4,
+    ASN1_NULL = 5,
+    ASN1_IDENTIFIER = 6,
+    ASN1_REAL = 9,
+    ASN1_ENUMERATED = 10,
+    ASN1_UTF8STRING = 12,
+    ASN1_SEQUENCE = 16 | ASN1_TYPE_CONSTRUCTED,
+    ASN1_SET = 17 | ASN1_TYPE_CONSTRUCTED,
+    ASN1_PRINTABLESTRING = 19,
+    ASN1_TELETEXSTRING = 20,
+    ASN1_IA5STRING = 22,
+    ASN1_UTC = 23,
+    ASN1_UNIVERSALSTRING = 28,
+    ASN1_BMPSTRING = 30,
+  };
+
+enum asn1_iterator_result
+  {
+    ASN1_ITERATOR_ERROR,
+    ASN1_ITERATOR_PRIMITIVE,
+    ASN1_ITERATOR_CONSTRUCTED,
+    ASN1_ITERATOR_END,
+  };
+
+/* Parsing DER objects. */
+struct asn1_der_iterator
+{
+  unsigned buffer_length;
+  const uint8_t *buffer;
+
+  /* Next object to parse. */
+  unsigned pos;
+
+  enum asn1_type type;
+
+  /* Pointer to the current object */
+  unsigned length;
+  const uint8_t *data;
+};
+
+/* Initializes the iterator. */
+enum asn1_iterator_result
+asn1_der_iterator_first(struct asn1_der_iterator *iterator,
+                       unsigned length, const uint8_t *input);
+
+enum asn1_iterator_result
+asn1_der_iterator_next(struct asn1_der_iterator *iterator);
+
+/* Starts parsing of a constructed object. */
+enum asn1_iterator_result
+asn1_der_decode_constructed(struct asn1_der_iterator *i,
+                           struct asn1_der_iterator *contents);
+
+/* For the common case that we have a sequence at the end of the
+   object. Checks that the current object is the final one, and then
+   reinitializes the iterator to parse its ontents. */
+enum asn1_iterator_result
+asn1_der_decode_constructed_last(struct asn1_der_iterator *i);
+
+enum asn1_iterator_result
+asn1_der_decode_bitstring(struct asn1_der_iterator *i,
+                         struct asn1_der_iterator *contents);
+
+enum asn1_iterator_result
+asn1_der_decode_bitstring_last(struct asn1_der_iterator *i);
+
+/* All these functions return 1 on success, 0 on failure */
+int
+asn1_der_get_uint32(struct asn1_der_iterator *i,
+                   uint32_t *x);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_ASN1_H_INCLUDED */
diff --git a/base16-decode.c b/base16-decode.c
new file mode 100644 (file)
index 0000000..2689411
--- /dev/null
@@ -0,0 +1,130 @@
+/* base16-encode.c
+ *
+ * Hex decoding.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "base16.h"
+
+void
+base16_decode_init(struct base16_decode_ctx *ctx)
+{
+  ctx->word = ctx->bits = 0;
+}
+
+enum { HEX_INVALID = -1, HEX_SPACE=-2 };
+
+static const signed char
+hex_decode_table[0x80] =
+  {
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -1, -1, -2, -1, -1, 
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
+    -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  };
+
+/* Decodes a single byte. Returns amount of output (0 or 1), or -1 on
+ * errors. */
+int
+base16_decode_single(struct base16_decode_ctx *ctx,
+                    uint8_t *dst,
+                    uint8_t src)
+{
+  int digit;
+
+  if (src >= 0x80)
+    return -1;
+
+  digit = hex_decode_table[src];
+  switch (digit)
+    {
+    case -1:
+      return -1;
+    case -2:
+      return 0;
+    default:
+      assert(digit >= 0);
+      assert(digit < 0x10);
+
+      if (ctx->bits)
+       {
+         *dst = (ctx->word << 4) | digit;
+         ctx->bits = 0;
+         return 1;
+       }
+      else
+       {
+         ctx->word = digit;
+         ctx->bits = 4;
+         return 0;
+       }
+    }
+}
+
+int
+base16_decode_update(struct base16_decode_ctx *ctx,
+                    unsigned *dst_length,
+                    uint8_t *dst,
+                    unsigned src_length,
+                    const uint8_t *src)
+{
+  unsigned done;
+  unsigned i;
+
+  assert(*dst_length >= BASE16_DECODE_LENGTH(src_length));
+  
+  for (i = 0, done = 0; i<src_length; i++)
+    switch(base16_decode_single(ctx, dst + done, src[i]))
+      {
+      case -1:
+       return 0;
+      case 1:
+       done++;
+       /* Fall through */
+      case 0:
+       break;
+      default:
+       abort();
+      }
+  
+  assert(done <= BASE16_DECODE_LENGTH(src_length));
+
+  *dst_length = done;
+  return 1;
+}
+
+int
+base16_decode_final(struct base16_decode_ctx *ctx)
+{
+  return ctx->bits == 0;
+}
diff --git a/base16-encode.c b/base16-encode.c
new file mode 100644 (file)
index 0000000..b2267ab
--- /dev/null
@@ -0,0 +1,57 @@
+/* base16-encode.c
+ *
+ * Hex encoding.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "base16.h"
+
+
+static const uint8_t
+hex_digits[16] = "0123456789abcdef";
+
+#define DIGIT(x) (hex_digits[(x) & 0xf])
+
+/* Encodes a single byte. Always stores two digits in dst[0] and dst[1]. */
+void
+base16_encode_single(uint8_t *dst,
+                    uint8_t src)
+{
+  dst[0] = DIGIT(src/0x10);
+  dst[1] = DIGIT(src);
+}
+
+/* Always stores BASE16_ENCODE_LENGTH(length) digits in dst. */
+void
+base16_encode_update(uint8_t *dst,
+                    unsigned length,
+                    const uint8_t *src)
+{
+  unsigned i;
+  
+  for (i = 0, dst; i<length; i++, dst += 2)
+    base16_encode_single(dst, src[i]);
+}
diff --git a/base16-meta.c b/base16-meta.c
new file mode 100644 (file)
index 0000000..cfa76b6
--- /dev/null
@@ -0,0 +1,67 @@
+/* base16-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "base16.h"
+
+/* Same as the macros with the same name */
+static unsigned
+base16_encode_length(unsigned length)
+{
+  return BASE16_ENCODE_LENGTH(length);
+}
+
+static unsigned
+base16_decode_length(unsigned length)
+{
+  return BASE16_DECODE_LENGTH(length);
+}
+
+static void
+base16_encode_init(void *ctx)
+{ (void) ctx; }
+
+static unsigned
+base16_encode_update_wrapper(void *ctx UNUSED, uint8_t *dst,
+                            unsigned length, const uint8_t *src)
+{
+  base16_encode_update(dst, length, src);
+  return BASE16_ENCODE_LENGTH(length);
+}
+
+#undef base16_encode_update
+#define base16_encode_update base16_encode_update_wrapper
+
+static unsigned
+base16_encode_final(void *ctx, uint8_t *dst)
+{ (void) ctx; (void) dst; return 0; }
+
+
+#define BASE16_ENCODE_FINAL_LENGTH 0
+
+const struct nettle_armor nettle_base16
+= _NETTLE_ARMOR_0(base16, BASE16);
diff --git a/base16.h b/base16.h
new file mode 100644 (file)
index 0000000..960ce77
--- /dev/null
+++ b/base16.h
@@ -0,0 +1,106 @@
+/* base16.h
+ *
+ * Hex encoding and decoding, following spki conventions (i.e.
+ * allowing whitespace between digits).
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_BASE16_H_INCLUDED
+#define NETTLE_BASE16_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define base16_encode_single nettle_base16_encode_single
+#define base16_encode_update nettle_base16_encode_update
+#define base16_decode_init nettle_base16_decode_init
+#define base16_decode_single nettle_base16_decode_single
+#define base16_decode_update nettle_base16_decode_update
+#define base16_decode_final nettle_base16_decode_final
+
+/* Base16 encoding */
+
+/* Maximum length of output for base16_encode_update. */
+#define BASE16_ENCODE_LENGTH(length) ((length) * 2)
+
+/* Encodes a single byte. Always stores two digits in dst[0] and dst[1]. */
+void
+base16_encode_single(uint8_t *dst,
+                    uint8_t src);
+
+/* Always stores BASE16_ENCODE_LENGTH(length) digits in dst. */
+void
+base16_encode_update(uint8_t *dst,
+                    unsigned length,
+                    const uint8_t *src);
+
+
+/* Base16 decoding */
+
+/* Maximum length of output for base16_decode_update. */
+/* We have at most 4 buffered bits, and a total of (length + 1) * 4 bits. */
+#define BASE16_DECODE_LENGTH(length) (((length) + 1) / 2)
+
+struct base16_decode_ctx
+{
+  unsigned word;   /* Leftover bits */
+  unsigned bits;   /* Number buffered bits */
+};
+
+void
+base16_decode_init(struct base16_decode_ctx *ctx);
+
+/* Decodes a single byte. Returns amount of output (0 or 1), or -1 on
+ * errors. */
+int
+base16_decode_single(struct base16_decode_ctx *ctx,
+                    uint8_t *dst,
+                    uint8_t src);
+
+/* Returns 1 on success, 0 on error. DST should point to an area of
+ * size at least BASE16_DECODE_LENGTH(length), and for sanity
+ * checking, *DST_LENGTH should be initialized to the size of that
+ * area before the call. *DST_LENGTH is updated to the amount of
+ * decoded output. */
+
+/* Currently results in an assertion failure if *DST_LENGTH is
+ * too small. FIXME: Return some error instead? */
+int
+base16_decode_update(struct base16_decode_ctx *ctx,
+                    unsigned *dst_length,
+                    uint8_t *dst,
+                    unsigned src_length,
+                    const uint8_t *src);
+
+/* Returns 1 on success. */
+int
+base16_decode_final(struct base16_decode_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_BASE16_H_INCLUDED */
diff --git a/base64-decode.c b/base64-decode.c
new file mode 100644 (file)
index 0000000..ac3bc38
--- /dev/null
@@ -0,0 +1,151 @@
+/* base64-encode.c
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "base64.h"
+
+#define TABLE_INVALID -1
+#define TABLE_SPACE -2
+#define TABLE_END -3
+
+static const signed char
+decode_table[0x100] =
+{
+  /* White space is HT, VT, FF, CR, LF and SPC */
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -1, -1, 
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -3, -1, -1,
+  -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+  -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+};
+
+void
+base64_decode_init(struct base64_decode_ctx *ctx)
+{
+  ctx->word = ctx->bits = ctx->padding = 0;
+}
+
+int
+base64_decode_single(struct base64_decode_ctx *ctx,
+                    uint8_t *dst,
+                    uint8_t src)
+{
+  int data;
+  
+  data = decode_table[src];
+
+  switch(data)
+    {
+    default:
+      assert(data >= 0 && data < 0x40);
+
+      if (ctx->padding)
+       return -1;
+      
+      ctx->word = ctx->word << 6 | data;
+      ctx->bits += 6;
+
+      if (ctx->bits >= 8)
+       {
+         ctx->bits -= 8;
+         dst[0] = ctx->word >> ctx->bits;
+         return 1;
+       }
+      else return 0;
+
+    case TABLE_INVALID:
+      return -1;
+
+    case TABLE_SPACE:
+      return 0;
+      
+    case TABLE_END:
+      /* There can be at most two padding characters. */
+      if (!ctx->bits || ctx->padding > 2)
+       return -1;
+      
+      if (ctx->word & ( (1<<ctx->bits) - 1))
+       /* We shouldn't have any leftover bits */
+       return -1;
+
+      ctx->padding++;
+      ctx->bits -= 2;
+      return 0;
+    }
+}
+
+int
+base64_decode_update(struct base64_decode_ctx *ctx,
+                    unsigned *dst_length,
+                    uint8_t *dst,
+                    unsigned src_length,
+                    const uint8_t *src)
+{
+  unsigned done;
+  unsigned i;
+
+  assert(*dst_length >= BASE64_DECODE_LENGTH(src_length));
+  
+  for (i = 0, done = 0; i<src_length; i++)
+    switch(base64_decode_single(ctx, dst + done, src[i]))
+      {
+      case -1:
+       return 0;
+      case 1:
+       done++;
+       /* Fall through */
+      case 0:
+       break;
+      default:
+       abort();
+      }
+  
+  assert(done <= BASE64_DECODE_LENGTH(src_length));
+
+  *dst_length = done;
+  return 1;
+}
+
+int
+base64_decode_final(struct base64_decode_ctx *ctx)
+{
+  return ctx->bits == 0;
+}
diff --git a/base64-encode.c b/base64-encode.c
new file mode 100644 (file)
index 0000000..6fc5e6b
--- /dev/null
@@ -0,0 +1,229 @@
+/* base64-encode.c
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "base64.h"
+
+static const uint8_t encode_table[64] =
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+  "abcdefghijklmnopqrstuvwxyz"
+  "0123456789+/";
+
+#define ENCODE(x) (encode_table[0x3F & (x)])
+
+void
+base64_encode_raw(uint8_t *dst, unsigned length, const uint8_t *src)
+{
+  const uint8_t *in = src + length;
+  uint8_t *out = dst + BASE64_ENCODE_RAW_LENGTH(length);
+
+  unsigned left_over = length % 3;
+
+  if (left_over)
+    {
+      in -= left_over;
+      *--out = '=';
+      switch(left_over)
+       {
+       case 1:
+         *--out = '=';
+         *--out = ENCODE(in[0] << 4);
+         break;
+         
+       case 2:
+         *--out = ENCODE( in[1] << 2);
+         *--out = ENCODE((in[0] << 4) | (in[1] >> 4));
+         break;
+
+       default:
+         abort();
+       }
+      *--out = ENCODE(in[0] >> 2);
+    }
+  
+  while (in > src)
+    {
+      in -= 3;
+      *--out = ENCODE( in[2]);
+      *--out = ENCODE((in[1] << 2) | (in[2] >> 6));
+      *--out = ENCODE((in[0] << 4) | (in[1] >> 4));
+      *--out = ENCODE( in[0] >> 2);      
+    }
+  assert(in == src);
+  assert(out == dst);
+}
+
+#if 0
+unsigned 
+base64_encode(uint8_t *dst,
+             unsigned src_length,
+             const uint8_t *src)
+{
+  unsigned dst_length = BASE64_ENCODE_RAW_LENGTH(src_length);
+  unsigned n = src_length / 3;
+  unsigned left_over  = src_length % 3;
+  unsigned done = 0;
+  
+  if (left_over)
+    {
+      const uint8_t *in = src + n * 3;
+      uint8_t *out = dst + dst_length;
+
+      switch(left_over)
+       {
+       case 1:
+         *--out = '=';
+         *--out = ENCODE(in[0] << 4);
+         break;
+         
+       case 2:
+         *--out = ENCODE( in[1] << 2);
+         *--out = ENCODE((in[0] << 4) | (in[1] >> 4));
+         break;
+
+       default:
+         abort();
+       }
+      *--out = ENCODE(in[0] >> 2);
+
+      done = 4;
+    }
+  base64_encode_raw(n, dst, src);
+  done += n * 4;
+
+  assert(done == dst_length);
+
+  return done;
+}
+#endif
+
+void
+base64_encode_group(uint8_t *dst, uint32_t group)
+{
+  *dst++ = ENCODE(group >> 18);
+  *dst++ = ENCODE(group >> 12);
+  *dst++ = ENCODE(group >> 6);
+  *dst++ = ENCODE(group);
+}
+
+void
+base64_encode_init(struct base64_encode_ctx *ctx)
+{
+  ctx->word = ctx->bits = 0;
+}
+
+/* Encodes a single byte. */
+unsigned
+base64_encode_single(struct base64_encode_ctx *ctx,
+                    uint8_t *dst,
+                    uint8_t src)
+{
+  unsigned done = 0;
+  unsigned word = ctx->word << 8 | src;
+  unsigned bits = ctx->bits + 8;
+  
+  while (bits >= 6)
+    {
+      bits -= 6;
+      dst[done++] = ENCODE(word >> bits);
+    }
+
+  ctx->bits = bits;
+  ctx->word = word;
+
+  assert(done <= 2);
+  
+  return done;
+}
+
+/* Returns the number of output characters. DST should point to an
+ * area of size at least BASE64_ENCODE_LENGTH(length). */
+unsigned
+base64_encode_update(struct base64_encode_ctx *ctx,
+                    uint8_t *dst,
+                    unsigned length,
+                    const uint8_t *src)
+{
+  unsigned done = 0;
+  unsigned left = length;
+  unsigned left_over;
+  unsigned bulk;
+  
+  while (ctx->bits && left)
+    {
+      left--;
+      done += base64_encode_single(ctx, dst + done, *src++);
+    }
+  
+  left_over = left % 3;
+  bulk = left - left_over;
+  
+  if (bulk)
+    {
+      assert(!(bulk % 3));
+      
+      base64_encode_raw(dst + done, bulk, src);
+      done += BASE64_ENCODE_RAW_LENGTH(bulk);
+      src += bulk;
+      left = left_over;
+    }
+
+  while (left)
+    {
+      left--;
+      done += base64_encode_single(ctx, dst + done, *src++);
+    }
+
+  assert(done <= BASE64_ENCODE_LENGTH(length));
+
+  return done;
+}
+
+/* DST should point to an area of size at least
+ * BASE64_ENCODE_FINAL_SIZE */
+unsigned
+base64_encode_final(struct base64_encode_ctx *ctx,
+                   uint8_t *dst)
+{
+  unsigned done = 0;
+  unsigned bits = ctx->bits;
+  
+  if (bits)
+    {
+      dst[done++] = ENCODE(ctx->word << (6 - ctx->bits));
+      for (; bits < 6; bits += 2)
+       dst[done++] = '=';
+
+      ctx->bits = 0;
+    }
+
+  assert(done <= BASE64_ENCODE_FINAL_LENGTH);
+  return done;
+}
diff --git a/base64-meta.c b/base64-meta.c
new file mode 100644 (file)
index 0000000..608e7b6
--- /dev/null
@@ -0,0 +1,45 @@
+/* base64-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Dan Egnor, Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "base64.h"
+
+/* Same as the macros with the same name */
+static unsigned
+base64_encode_length(unsigned length)
+{
+  return BASE64_ENCODE_LENGTH(length);
+}
+
+static unsigned
+base64_decode_length(unsigned length)
+{
+  return BASE64_DECODE_LENGTH(length);
+}
+
+const struct nettle_armor nettle_base64
+= _NETTLE_ARMOR(base64, BASE64);
diff --git a/base64.h b/base64.h
new file mode 100644 (file)
index 0000000..2be1865
--- /dev/null
+++ b/base64.h
@@ -0,0 +1,153 @@
+/* base64.h
+ *
+ * "ASCII armor" codecs.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller, Dan Egnor
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_BASE64_H_INCLUDED
+#define NETTLE_BASE64_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define base64_encode_init nettle_base64_encode_init
+#define base64_encode_single nettle_base64_encode_single
+#define base64_encode_update nettle_base64_encode_update
+#define base64_encode_final nettle_base64_encode_final
+#define base64_encode_raw nettle_base64_encode_raw
+#define base64_encode_group nettle_base64_encode_group
+#define base64_decode_init nettle_base64_decode_init
+#define base64_decode_single nettle_base64_decode_single
+#define base64_decode_update nettle_base64_decode_update
+#define base64_decode_final nettle_base64_decode_final
+
+#define BASE64_BINARY_BLOCK_SIZE 3
+#define BASE64_TEXT_BLOCK_SIZE 4
+
+/* Base64 encoding */
+
+/* Maximum length of output for base64_encode_update. NOTE: Doesn't
+ * include any padding that base64_encode_final may add. */
+/* We have at most 4 buffered bits, and a total of (4 + length * 8) bits. */
+#define BASE64_ENCODE_LENGTH(length) (((length) * 8 + 4)/6)
+
+/* Maximum lengbth of output generated by base64_encode_final. */
+#define BASE64_ENCODE_FINAL_LENGTH 3
+
+/* Exact length of output generated by base64_encode_raw, including
+ * padding. */
+#define BASE64_ENCODE_RAW_LENGTH(length) ((((length) + 2)/3)*4)
+
+struct base64_encode_ctx
+{
+  unsigned word;   /* Leftover bits */
+  unsigned bits;  /* Number of bits, always 0, 2, or 4. */
+};
+
+void
+base64_encode_init(struct base64_encode_ctx *ctx);
+
+/* Encodes a single byte. Returns amount of output (always 1 or 2). */
+unsigned
+base64_encode_single(struct base64_encode_ctx *ctx,
+                    uint8_t *dst,
+                    uint8_t src);
+
+/* Returns the number of output characters. DST should point to an
+ * area of size at least BASE64_ENCODE_LENGTH(length). */
+unsigned
+base64_encode_update(struct base64_encode_ctx *ctx,
+                    uint8_t *dst,
+                    unsigned length,
+                    const uint8_t *src);
+
+/* DST should point to an area of size at least
+ * BASE64_ENCODE_FINAL_LENGTH */
+unsigned
+base64_encode_final(struct base64_encode_ctx *ctx,
+                   uint8_t *dst);
+
+/* Lower level functions */
+
+/* Encodes a string in one go, including any padding at the end.
+ * Generates exactly BASE64_ENCODE_RAW_LENGTH(length) bytes of output.
+ * Supports overlapped operation, if src <= dst. */
+void
+base64_encode_raw(uint8_t *dst, unsigned length, const uint8_t *src);
+
+void
+base64_encode_group(uint8_t *dst, uint32_t group);
+
+
+/* Base64 decoding */
+
+/* Maximum length of output for base64_decode_update. */
+/* We have at most 6 buffered bits, and a total of (length + 1) * 6 bits. */
+#define BASE64_DECODE_LENGTH(length) ((((length) + 1) * 6) / 8)
+
+struct base64_decode_ctx
+{
+  unsigned word;   /* Leftover bits */
+  unsigned bits;   /* Number buffered bits */
+
+  /* Number of padding characters encountered */
+  unsigned padding;
+};
+
+void
+base64_decode_init(struct base64_decode_ctx *ctx);
+
+/* Decodes a single byte. Returns amount of output (0 or 1), or -1 on
+ * errors. */
+int
+base64_decode_single(struct base64_decode_ctx *ctx,
+                    uint8_t *dst,
+                    uint8_t src);
+
+/* Returns 1 on success, 0 on error. DST should point to an area of
+ * size at least BASE64_DECODE_LENGTH(length), and for sanity
+ * checking, *DST_LENGTH should be initialized to the size of that
+ * area before the call. *DST_LENGTH is updated to the amount of
+ * decoded output. */
+
+/* Currently results in an assertion failure if *DST_LENGTH is
+ * too small. FIXME: Return some error instead? */
+int
+base64_decode_update(struct base64_decode_ctx *ctx,
+                    unsigned *dst_length,
+                    uint8_t *dst,
+                    unsigned src_length,
+                    const uint8_t *src);
+
+/* Returns 1 on success. */
+int
+base64_decode_final(struct base64_decode_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_BASE64_H_INCLUDED */
diff --git a/bignum-next-prime.c b/bignum-next-prime.c
new file mode 100644 (file)
index 0000000..91ba8fd
--- /dev/null
@@ -0,0 +1,162 @@
+/* bignum-next-prime.c
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <limits.h>
+/* Needed for alloca on freebsd */
+#include <stdlib.h>
+
+#include "bignum.h"
+
+#include "nettle-internal.h"
+
+/* From gmp.h */
+/* Test for gcc >= maj.min, as per __GNUC_PREREQ in glibc */
+#if defined (__GNUC__) && defined (__GNUC_MINOR__)
+#define GNUC_PREREQ(maj, min) \
+  ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+#define GNUC_PREREQ(maj, min)  0
+#endif
+
+#if GNUC_PREREQ (3,0)
+# define UNLIKELY(cond) __builtin_expect ((cond) != 0, 0)
+#else
+# define UNLIKELY(cond) cond
+#endif
+
+/* From some benchmarking using the examples nextprime(200!) and
+   nextprime(240!), it seems that it pays off to use a prime list up
+   to around 5000--10000 primes. There are 6541 odd primes less than
+   2^16. */
+static const uint16_t primes[] = {
+  /* Generated by
+
+     ./examples/eratosthenes 65535 \
+     | awk '{ if (NR % 10 == 2) printf ("\n"); if (NR > 1) printf("%d, ", $1); }
+            END { printf("\n"); }' > prime-list.h
+  */
+  #include "prime-list.h"
+};
+
+#define NUMBER_OF_PRIMES (sizeof(primes) / sizeof(primes[0]))
+
+#ifdef mpz_millerrabin
+# define PRIME_P mpz_millerrabin
+#else
+# define PRIME_P mpz_probab_prime_p
+#endif
+
+/* NOTE: The mpz_nextprime in current GMP is unoptimized. */
+void
+nettle_next_prime(mpz_t p, mpz_t n, unsigned count, unsigned prime_limit,
+                 void *progress_ctx, nettle_progress_func progress)
+{
+  mpz_t tmp;
+  TMP_DECL(moduli, unsigned, NUMBER_OF_PRIMES);
+  
+  unsigned difference;
+
+  if (prime_limit > NUMBER_OF_PRIMES)
+    prime_limit = NUMBER_OF_PRIMES;
+  
+  /* First handle tiny numbers */
+  if (mpz_cmp_ui(n, 2) <= 0)
+    {
+      mpz_set_ui(p, 2);
+      return;
+    }
+  mpz_set(p, n);
+  mpz_setbit(p, 0);
+
+  if (mpz_cmp_ui(p, 8) < 0)
+    return;
+
+  mpz_init(tmp);
+
+  if (mpz_cmp_ui(p, primes[prime_limit-1]) <= 0)
+    /* Use only 3, 5 and 7 */
+    /* FIXME: Could do binary search in the table. */
+    prime_limit = 3;
+  
+  /* Compute residues modulo small odd primes */
+  /* FIXME: Could be sped up by collecting limb-sized products of the
+     primes, to reduce the calls to mpz_fdiv_ui */
+
+  /* FIXME: Could also handle the first few primes separately; compute
+     the residue mod 15015 = 3 * 7 * 11 * 13, and tabulate the steps
+     between the 5760 odd numbers in this interval that have no factor
+     in common with 15015.
+   */
+  TMP_ALLOC(moduli, prime_limit);
+  {
+    unsigned i;
+    for (i = 0; i < prime_limit; i++)
+      moduli[i] = mpz_fdiv_ui(p, primes[i]);
+  }
+  
+  for (difference = 0; ; difference += 2)
+    {
+      int composite = 0;
+      unsigned i;
+      
+      if (difference >= UINT_MAX - 10)
+       { /* Should not happen, at least not very often... */
+         mpz_add_ui(p, p, difference);
+         difference = 0;
+       }
+
+      /* First check residues */
+      for (i = 0; i < prime_limit; i++)
+       {
+         if (moduli[i] == 0)
+           composite = 1;
+
+         moduli[i] += 2;
+         if (UNLIKELY(moduli[i] >= primes[i]))
+           moduli[i] -= primes[i];
+       }
+      if (composite)
+       continue;
+      
+      mpz_add_ui(p, p, difference);
+      difference = 0;
+
+      if (progress)
+       progress(progress_ctx, '.');
+
+      /* Miller-Rabin test */
+      if (PRIME_P(p, count))
+       break;
+
+#if 0
+      if (progress)
+       progress(progress_ctx, '*');
+#endif
+    }
+  mpz_clear(tmp);
+}
diff --git a/bignum-random-prime.c b/bignum-random-prime.c
new file mode 100644 (file)
index 0000000..bc2938f
--- /dev/null
@@ -0,0 +1,415 @@
+/* bignum-random-prime.c
+ *
+ * Generation of random provable primes.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifndef RANDOM_PRIME_VERBOSE
+#define RANDOM_PRIME_VERBOSE 0
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+
+#if RANDOM_PRIME_VERBOSE
+#include <stdio.h>
+#define VERBOSE(x) (fputs((x), stderr))
+#else
+#define VERBOSE(x)
+#endif
+
+#include "bignum.h"
+
+#include "macros.h"
+
+/* Use a table of p_2 = 3 to p_{172} = 1021, used for sieving numbers
+   of up to 20 bits. */
+
+#define NPRIMES 171
+#define TRIAL_DIV_BITS 20
+#define TRIAL_DIV_MASK ((1 << TRIAL_DIV_BITS) - 1)
+
+/* A 20-bit number x is divisible by p iff
+
+     ((x * inverse) & TRIAL_DIV_MASK) <= limit
+*/
+struct trial_div_info {
+  uint32_t inverse; /* p^{-1} (mod 2^20) */
+  uint32_t limit;   /* floor( (2^20 - 1) / p) */
+};
+
+static const uint16_t
+primes[NPRIMES] = {
+  3,5,7,11,13,17,19,23,
+  29,31,37,41,43,47,53,59,
+  61,67,71,73,79,83,89,97,
+  101,103,107,109,113,127,131,137,
+  139,149,151,157,163,167,173,179,
+  181,191,193,197,199,211,223,227,
+  229,233,239,241,251,257,263,269,
+  271,277,281,283,293,307,311,313,
+  317,331,337,347,349,353,359,367,
+  373,379,383,389,397,401,409,419,
+  421,431,433,439,443,449,457,461,
+  463,467,479,487,491,499,503,509,
+  521,523,541,547,557,563,569,571,
+  577,587,593,599,601,607,613,617,
+  619,631,641,643,647,653,659,661,
+  673,677,683,691,701,709,719,727,
+  733,739,743,751,757,761,769,773,
+  787,797,809,811,821,823,827,829,
+  839,853,857,859,863,877,881,883,
+  887,907,911,919,929,937,941,947,
+  953,967,971,977,983,991,997,1009,
+  1013,1019,1021,
+};
+
+static const uint32_t
+prime_square[NPRIMES+1] = {
+  9,25,49,121,169,289,361,529,
+  841,961,1369,1681,1849,2209,2809,3481,
+  3721,4489,5041,5329,6241,6889,7921,9409,
+  10201,10609,11449,11881,12769,16129,17161,18769,
+  19321,22201,22801,24649,26569,27889,29929,32041,
+  32761,36481,37249,38809,39601,44521,49729,51529,
+  52441,54289,57121,58081,63001,66049,69169,72361,
+  73441,76729,78961,80089,85849,94249,96721,97969,
+  100489,109561,113569,120409,121801,124609,128881,134689,
+  139129,143641,146689,151321,157609,160801,167281,175561,
+  177241,185761,187489,192721,196249,201601,208849,212521,
+  214369,218089,229441,237169,241081,249001,253009,259081,
+  271441,273529,292681,299209,310249,316969,323761,326041,
+  332929,344569,351649,358801,361201,368449,375769,380689,
+  383161,398161,410881,413449,418609,426409,434281,436921,
+  452929,458329,466489,477481,491401,502681,516961,528529,
+  537289,546121,552049,564001,573049,579121,591361,597529,
+  619369,635209,654481,657721,674041,677329,683929,687241,
+  703921,727609,734449,737881,744769,769129,776161,779689,
+  786769,822649,829921,844561,863041,877969,885481,896809,
+  908209,935089,942841,954529,966289,982081,994009,1018081,
+  1026169,1038361,1042441,1L<<20
+};
+
+static const struct trial_div_info
+trial_div_table[NPRIMES] = {
+  {699051,349525},{838861,209715},{748983,149796},{953251,95325},
+  {806597,80659},{61681,61680},{772635,55188},{866215,45590},
+  {180789,36157},{1014751,33825},{793517,28339},{1023001,25575},
+  {48771,24385},{870095,22310},{217629,19784},{710899,17772},
+  {825109,17189},{281707,15650},{502135,14768},{258553,14364},
+  {464559,13273},{934875,12633},{1001449,11781},{172961,10810},
+  {176493,10381},{203607,10180},{568387,9799},{788837,9619},
+  {770193,9279},{1032063,8256},{544299,8004},{619961,7653},
+  {550691,7543},{182973,7037},{229159,6944},{427445,6678},
+  {701195,6432},{370455,6278},{90917,6061},{175739,5857},
+  {585117,5793},{225087,5489},{298817,5433},{228877,5322},
+  {442615,5269},{546651,4969},{244511,4702},{83147,4619},
+  {769261,4578},{841561,4500},{732687,4387},{978961,4350},
+  {133683,4177},{65281,4080},{629943,3986},{374213,3898},
+  {708079,3869},{280125,3785},{641833,3731},{618771,3705},
+  {930477,3578},{778747,3415},{623751,3371},{40201,3350},
+  {122389,3307},{950371,3167},{1042353,3111},{18131,3021},
+  {285429,3004},{549537,2970},{166487,2920},{294287,2857},
+  {919261,2811},{636339,2766},{900735,2737},{118605,2695},
+  {10565,2641},{188273,2614},{115369,2563},{735755,2502},
+  {458285,2490},{914767,2432},{370513,2421},{1027079,2388},
+  {629619,2366},{462401,2335},{649337,2294},{316165,2274},
+  {484655,2264},{65115,2245},{326175,2189},{1016279,2153},
+  {990915,2135},{556859,2101},{462791,2084},{844629,2060},
+  {404537,2012},{457123,2004},{577589,1938},{638347,1916},
+  {892325,1882},{182523,1862},{1002505,1842},{624371,1836},
+  {69057,1817},{210787,1786},{558769,1768},{395623,1750},
+  {992745,1744},{317855,1727},{384877,1710},{372185,1699},
+  {105027,1693},{423751,1661},{408961,1635},{908331,1630},
+  {74551,1620},{36933,1605},{617371,1591},{506045,1586},
+  {24929,1558},{529709,1548},{1042435,1535},{31867,1517},
+  {166037,1495},{928781,1478},{508975,1458},{4327,1442},
+  {779637,1430},{742091,1418},{258263,1411},{879631,1396},
+  {72029,1385},{728905,1377},{589057,1363},{348621,1356},
+  {671515,1332},{710453,1315},{84249,1296},{959363,1292},
+  {685853,1277},{467591,1274},{646643,1267},{683029,1264},
+  {439927,1249},{254461,1229},{660713,1223},{554195,1220},
+  {202911,1215},{753253,1195},{941457,1190},{776635,1187},
+  {509511,1182},{986147,1156},{768879,1151},{699431,1140},
+  {696417,1128},{86169,1119},{808997,1114},{25467,1107},
+  {201353,1100},{708087,1084},{1018339,1079},{341297,1073},
+  {434151,1066},{96287,1058},{950765,1051},{298257,1039},
+  {675933,1035},{167731,1029},{815445,1027},
+};
+
+/* Element j gives the index of the first prime of size 3+j bits */
+static uint8_t
+prime_by_size[9] = {
+  1,3,5,10,17,30,53,96,171
+};
+
+/* Combined Miller-Rabin test to the base a, and checking the
+   conditions from Pocklington's theorem. */
+static int
+miller_rabin_pocklington(mpz_t n, mpz_t nm1, mpz_t nm1dq, mpz_t a)
+{
+  mpz_t r;
+  mpz_t y;
+  int is_prime = 0;
+
+  /* Avoid the mp_bitcnt_t type for compatibility with older GMP
+     versions. */
+  unsigned k;
+  unsigned j;
+
+  VERBOSE(".");
+
+  if (mpz_even_p(n) || mpz_cmp_ui(n, 3) < 0)
+    return 0;
+
+  mpz_init(r);
+  mpz_init(y);
+
+  k = mpz_scan1(nm1, 0);
+  assert(k > 0);
+
+  mpz_fdiv_q_2exp (r, nm1, k);
+
+  mpz_powm(y, a, r, n);
+
+  if (mpz_cmp_ui(y, 1) == 0 || mpz_cmp(y, nm1) == 0)
+    goto passed_miller_rabin;
+    
+  for (j = 1; j < k; j++)
+    {
+      mpz_powm_ui (y, y, 2, n);
+
+      if (mpz_cmp_ui (y, 1) == 0)
+       break;
+
+      if (mpz_cmp (y, nm1) == 0)
+       {
+       passed_miller_rabin:
+         /* We know that a^{n-1} = 1 (mod n)
+
+            Remains to check that gcd(a^{(n-1)/q} - 1, n) == 1 */      
+         VERBOSE("x");
+
+         mpz_powm(y, a, nm1dq, n);
+         mpz_sub_ui(y, y, 1);
+         mpz_gcd(y, y, n);
+         is_prime = mpz_cmp_ui (y, 1) == 0;
+         VERBOSE(is_prime ? "\n" : "");
+         break;
+       }
+
+    }
+
+  mpz_clear(r);
+  mpz_clear(y);
+
+  return is_prime;
+}
+
+/* The algorithm is based on the following special case of
+   Pocklington's theorem:
+
+   Assume that n = 1 + f q, where q is a prime, q > sqrt(n) - 1. If we
+   can find an a such that
+
+     a^{n-1} = 1 (mod n)
+     gcd(a^f - 1, n) = 1
+
+   then n is prime.
+
+   Proof: Assume that n is composite, with smallest prime factor p <=
+   sqrt(n). Since q is prime, and q > sqrt(n) - 1 >= p - 1, q and p-1
+   are coprime, so that we can define u = q^{-1} (mod (p-1)). The
+   assumption a^{n-1} = 1 (mod n) implies that also a^{n-1} = 1 (mod
+   p). Since p is prime, we have a^{(p-1)} = 1 (mod p). Now, r =
+   (n-1)/q = (n-1) u (mod (p-1)), and it follows that a^r = a^{(n-1)
+   u} = 1 (mod p). Then p is a common factor of a^r - 1 and n. This
+   contradicts gcd(a^r - 1, n) = 1, and concludes the proof.
+
+   If n is specified as k bits, we need q of size ceil(k/2) + 1 bits
+   (or more) to make the theorem apply.
+*/
+
+/* Generate a prime number p of size bits with 2 p0q dividing (p-1).
+   p0 must be of size >= ceil(bits/2) + 1. The extra factor q can be
+   omitted. If top_bits_set is one, the top most two bits are one,
+   suitable for RSA primes. */
+void
+_nettle_generate_pocklington_prime (mpz_t p, mpz_t r,
+                                   unsigned bits, int top_bits_set, 
+                                   void *ctx, nettle_random_func random, 
+                                   const mpz_t p0,
+                                   const mpz_t q,
+                                   const mpz_t p0q)
+{
+  mpz_t r_min, r_range, pm1,a;
+  
+  assert (2*mpz_sizeinbase (p0, 2) > bits + 1);
+
+  mpz_init (r_min);
+  mpz_init (r_range);
+  mpz_init (pm1);
+  mpz_init (a);
+
+  if (top_bits_set)
+    {
+      /* i = floor (2^{bits-3} / p0q), then 3I + 3 <= r <= 4I, with I
+        - 2 possible values. */
+      mpz_set_ui (r_min, 1);
+      mpz_mul_2exp (r_min, r_min, bits-3);
+      mpz_fdiv_q (r_min, r_min, p0q);
+      mpz_sub_ui (r_range, r_min, 2);
+      mpz_mul_ui (r_min, r_min, 3);
+      mpz_add_ui (r_min, r_min, 3);
+    }
+  else
+    {
+      /* i = floor (2^{bits-2} / p0q), I + 1 <= r <= 2I */
+      mpz_set_ui (r_range, 1);
+      mpz_mul_2exp (r_range, r_range, bits-2);
+      mpz_fdiv_q (r_range, r_range, p0q);
+      mpz_add_ui (r_min, r_range, 1);
+    }
+  for (;;)
+    {
+      uint8_t buf[1];
+
+      nettle_mpz_random (r, ctx, random, r_range);
+      mpz_add (r, r, r_min);
+
+      /* Set p = 2*r*p0q + 1 */
+      mpz_mul_2exp(r, r, 1);
+      mpz_mul (pm1, r, p0q);
+      mpz_add_ui (p, pm1, 1);
+
+      assert(mpz_sizeinbase(p, 2) == bits);
+
+      /* Should use GMP trial division interface when that
+        materializes, we don't need any testing beyond trial
+        division. */
+      if (!mpz_probab_prime_p (p, 1))
+       continue;
+
+      random(ctx, sizeof(buf), buf);
+         
+      mpz_set_ui (a, buf[0] + 2);
+
+      if (q)
+       {
+         mpz_t e;
+         int is_prime;
+         
+         mpz_init (e);
+
+         mpz_mul (e, r, q);
+         is_prime = miller_rabin_pocklington(p, pm1, e, a);
+         mpz_clear (e);
+
+         if (is_prime)
+           break;
+       }
+      else if (miller_rabin_pocklington(p, pm1, r, a))
+       break;
+    }
+  mpz_clear (r_min);
+  mpz_clear (r_range);
+  mpz_clear (pm1);
+  mpz_clear (a);
+}
+
+/* Generate random prime of a given size. Maurer's algorithm (Alg.
+   6.42 Handbook of applied cryptography), but with ratio = 1/2 (like
+   the variant in fips186-3). */
+void
+nettle_random_prime(mpz_t p, unsigned bits, int top_bits_set,
+                   void *random_ctx, nettle_random_func random,
+                   void *progress_ctx, nettle_progress_func progress)
+{
+  assert (bits >= 3);
+  if (bits <= 10)
+    {
+      unsigned first;
+      unsigned choices;
+      uint8_t buf;
+
+      assert (!top_bits_set);
+
+      random (random_ctx, sizeof(buf), &buf);
+
+      first = prime_by_size[bits-3];
+      choices = prime_by_size[bits-2] - first;
+      
+      mpz_set_ui (p, primes[first + buf % choices]);
+    }
+  else if (bits <= 20)
+    {
+      unsigned long highbit;
+      uint8_t buf[3];
+      unsigned long x;
+      unsigned j;
+      
+      assert (!top_bits_set);
+
+      highbit = 1L << (bits - 1);
+
+    again:
+      random (random_ctx, sizeof(buf), buf);
+      x = READ_UINT24(buf);
+      x &= (highbit - 1);
+      x |= highbit | 1;
+
+      for (j = 0; prime_square[j] <= x; j++)
+       {
+         unsigned q = x * trial_div_table[j].inverse & TRIAL_DIV_MASK;
+         if (q <= trial_div_table[j].limit)
+           goto again;
+       }
+      mpz_set_ui (p, x);
+    }
+  else
+    {
+      mpz_t q, r;
+
+      mpz_init (q);
+      mpz_init (r);
+
+     /* Bit size ceil(k/2) + 1, slightly larger than used in Alg. 4.62
+       in Handbook of Applied Cryptography (which seems to be
+       incorrect for odd k). */
+      nettle_random_prime (q, (bits+3)/2, 0, random_ctx, random,
+                          progress_ctx, progress);
+
+      _nettle_generate_pocklington_prime (p, r, bits, top_bits_set,
+                                         random_ctx, random,
+                                         q, NULL, q);
+      
+      if (progress)
+       progress (progress_ctx, 'x');
+
+      mpz_clear (q);
+      mpz_clear (r);
+    }
+}
diff --git a/bignum-random.c b/bignum-random.c
new file mode 100644 (file)
index 0000000..dc2fd1c
--- /dev/null
@@ -0,0 +1,85 @@
+/* bignum-random.c
+ *
+ * Generating big random numbers
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+
+#include "bignum.h"
+#include "nettle-internal.h"
+
+void
+nettle_mpz_random_size(mpz_t x,
+                      void *ctx, nettle_random_func random,
+                      unsigned bits)
+{
+  unsigned length = (bits + 7) / 8;
+  TMP_DECL(data, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8);
+  TMP_ALLOC(data, length);
+
+  random(ctx, length, data);
+
+  nettle_mpz_set_str_256_u(x, length, data);
+
+  if (bits % 8)
+    mpz_fdiv_r_2exp(x, x, bits);
+}
+
+/* Returns a random number x, 0 <= x < n */
+void
+nettle_mpz_random(mpz_t x,
+                 void *ctx, nettle_random_func random,
+                 const mpz_t n)
+{
+  /* NOTE: This leaves some bias, which may be bad for DSA. A better
+   * way might be to generate a random number of mpz_sizeinbase(n, 2)
+   * bits, and loop until one smaller than n is found. */
+
+  /* From Daniel Bleichenbacher (via coderpunks):
+   *
+   * There is still a theoretical attack possible with 8 extra bits.
+   * But, the attack would need about 2^66 signatures 2^66 memory and
+   * 2^66 time (if I remember that correctly). Compare that to DSA,
+   * where the attack requires 2^22 signatures 2^40 memory and 2^64
+   * time. And of course, the numbers above are not a real threat for
+   * PGP. Using 16 extra bits (i.e. generating a 176 bit random number
+   * and reducing it modulo q) will defeat even this theoretical
+   * attack.
+   * 
+   * More generally log_2(q)/8 extra bits are enough to defeat my
+   * attack. NIST also plans to update the standard.
+   */
+
+  /* Add a few bits extra, to decrease the bias from the final modulo
+   * operation. */
+
+  nettle_mpz_random_size(x, 
+                        ctx, random,
+                        mpz_sizeinbase(n, 2) + 16);
+  
+  mpz_fdiv_r(x, x, n);
+}
diff --git a/bignum.c b/bignum.c
new file mode 100644 (file)
index 0000000..bb18791
--- /dev/null
+++ b/bignum.c
@@ -0,0 +1,195 @@
+/* bignum.c
+ *
+ * bignum operations that are missing from gmp.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <string.h>
+
+#include "bignum.h"
+
+/* Two's complement negation means that -x = ~x + 1, ~x = -(x+1),
+ * and we use that x = ~~x = ~(-x-1).
+ *
+ * Examples:
+ *
+ *   x  ~x = -x+1     ~~x = x
+ *  -1          0          ff
+ *  -2          1          fe
+ * -7f         7e          81
+ * -80         7f          80
+ * -81         80        ff7f
+ */
+
+/* Including extra sign bit, if needed. Also one byte for zero. */
+unsigned
+nettle_mpz_sizeinbase_256_s(const mpz_t x)
+{
+  if (mpz_sgn(x) >= 0)
+    return 1 + mpz_sizeinbase(x, 2) / 8;
+  else
+    {
+      /* We'll output ~~x, so we need as many bits as for ~x */
+      unsigned size;
+      mpz_t c;
+
+      mpz_init(c);
+      mpz_com(c, x); /* Same as c = - x - 1 = |x| + 1 */
+      size = 1 + mpz_sizeinbase(c,2) / 8;
+      mpz_clear(c);
+
+      return size;
+    }
+}
+
+unsigned
+nettle_mpz_sizeinbase_256_u(const mpz_t x)
+{
+  return (mpz_sizeinbase(x,2) + 7) / 8;
+}
+
+static void
+nettle_mpz_to_octets(unsigned length, uint8_t *s,
+                    const mpz_t x, uint8_t sign)
+{
+  uint8_t *dst = s + length - 1;
+  unsigned size = mpz_size(x);
+  unsigned i;
+  
+  for (i = 0; i<size; i++)
+    {
+      mp_limb_t limb = mpz_getlimbn(x, i);
+      unsigned j;
+
+      for (j = 0; length && j < sizeof(mp_limb_t); j++)
+        {
+          *dst-- = sign ^ (limb & 0xff);
+          limb >>= 8;
+          length--;
+       }
+    }
+  
+  if (length)
+    memset(s, sign, length);
+}
+
+void
+nettle_mpz_get_str_256(unsigned length, uint8_t *s, const mpz_t x)
+{
+  if (!length)
+    {
+      /* x must be zero */
+      assert(!mpz_sgn(x));
+      return;
+    }
+
+  if (mpz_sgn(x) >= 0)
+    {
+      assert(nettle_mpz_sizeinbase_256_u(x) <= length);
+      nettle_mpz_to_octets(length, s, x, 0);
+    }
+  else
+    {
+      mpz_t c;
+      mpz_init(c);
+      mpz_com(c, x);
+
+      assert(nettle_mpz_sizeinbase_256_u(c) <= length);
+      nettle_mpz_to_octets(length, s, c, 0xff);
+
+      mpz_clear(c);
+    }
+}
+
+/* Converting from strings */
+
+#ifdef mpz_import
+/* Was introduced in GMP-4.1 */
+# define nettle_mpz_from_octets(x, length, s) \
+   mpz_import((x), (length), 1, 1, 0, 0, (s))
+#else
+static void
+nettle_mpz_from_octets(mpz_t x,
+                      unsigned length, const uint8_t *s)
+{
+  unsigned i;
+
+  mpz_set_ui(x, 0);
+
+  for (i = 0; i < length; i++)
+    {
+      mpz_mul_2exp(x, x, 8);
+      mpz_add_ui(x, x, s[i]);
+    }
+}
+#endif
+
+void
+nettle_mpz_set_str_256_u(mpz_t x,
+                        unsigned length, const uint8_t *s)
+{
+  nettle_mpz_from_octets(x, length, s);
+}
+
+void
+nettle_mpz_init_set_str_256_u(mpz_t x,
+                             unsigned length, const uint8_t *s)
+{
+  mpz_init(x);
+  nettle_mpz_from_octets(x, length, s);
+}
+
+void
+nettle_mpz_set_str_256_s(mpz_t x,
+                        unsigned length, const uint8_t *s)
+{
+  if (!length)
+    {
+      mpz_set_ui(x, 0);
+      return;
+    }
+  
+  nettle_mpz_from_octets(x, length, s);
+
+  if (s[0] & 0x80)
+    {
+      mpz_t t;
+
+      mpz_init_set_ui(t, 1);
+      mpz_mul_2exp(t, t, length*8);
+      mpz_sub(x, x, t);
+      mpz_clear(t);
+    }
+}
+
+void
+nettle_mpz_init_set_str_256_s(mpz_t x,
+                             unsigned length, const uint8_t *s)
+{
+  mpz_init(x);
+  nettle_mpz_set_str_256_s(x, length, s);
+}
diff --git a/bignum.h b/bignum.h
new file mode 100644 (file)
index 0000000..06287d2
--- /dev/null
+++ b/bignum.h
@@ -0,0 +1,121 @@
+/* bignum.h
+ *
+ * bignum operations that are missing from gmp.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_BIGNUM_H_INCLUDED
+#define NETTLE_BIGNUM_H_INCLUDED
+
+#include "nettle-meta.h"
+
+#include <gmp.h>
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Size needed for signed encoding, including extra sign byte if
+ * necessary. */
+unsigned
+nettle_mpz_sizeinbase_256_s(const mpz_t x);
+
+/* Size needed for unsigned encoding */
+unsigned
+nettle_mpz_sizeinbase_256_u(const mpz_t x);
+
+/* Writes an integer as length octets, using big endian byte order,
+ * and two's complement for negative numbers. */
+void
+nettle_mpz_get_str_256(unsigned length, uint8_t *s, const mpz_t x);
+
+/* Reads a big endian, two's complement, integer. */
+void
+nettle_mpz_set_str_256_s(mpz_t x,
+                        unsigned length, const uint8_t *s);
+
+void
+nettle_mpz_init_set_str_256_s(mpz_t x,
+                             unsigned length, const uint8_t *s);
+
+/* Similar, but for unsigned format. These function don't interpret
+ * the most significant bit as the sign. */
+void
+nettle_mpz_set_str_256_u(mpz_t x,
+                        unsigned length, const uint8_t *s);
+
+void
+nettle_mpz_init_set_str_256_u(mpz_t x,
+                             unsigned length, const uint8_t *s);
+
+/* Returns a uniformly distributed random number 0 <= x < 2^n */
+void
+nettle_mpz_random_size(mpz_t x,
+                      void *ctx, nettle_random_func random,
+                      unsigned bits);
+
+/* Returns a number x, almost uniformly random in the range
+ * 0 <= x < n. */
+void
+nettle_mpz_random(mpz_t x, 
+                 void *ctx, nettle_random_func random,
+                 const mpz_t n);
+
+void
+nettle_next_prime(mpz_t p, mpz_t n, unsigned count, unsigned prime_limit,
+                 void *progress_ctx, nettle_progress_func progress);
+
+void
+nettle_random_prime(mpz_t p, unsigned bits, int top_bits_set,
+                   void *ctx, nettle_random_func random,
+                   void *progress_ctx, nettle_progress_func progress);
+
+void
+_nettle_generate_pocklington_prime (mpz_t p, mpz_t r,
+                                   unsigned bits, int top_bits_set, 
+                                   void *ctx, nettle_random_func random, 
+                                   const mpz_t p0,
+                                   const mpz_t q,
+                                   const mpz_t p0q);
+  
+/* sexp parsing */
+struct sexp_iterator;
+
+/* If LIMIT is non-zero, the number must be at most LIMIT bits.
+ * Implies sexp_iterator_next. */
+int
+nettle_mpz_set_sexp(mpz_t x, unsigned limit, struct sexp_iterator *i);
+
+
+/* der parsing */
+struct asn1_der_iterator;
+
+int
+nettle_asn1_der_get_bignum(struct asn1_der_iterator *iterator,
+                          mpz_t x, unsigned max_bits);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_BIGNUM_H_INCLUDED */
diff --git a/blowfish.c b/blowfish.c
new file mode 100644 (file)
index 0000000..77b8796
--- /dev/null
@@ -0,0 +1,414 @@
+/* blowfish.c
+ *
+ * The blowfish block cipher.
+ *
+ * For a description of the algorithm, see:
+ *   Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
+ *   ISBN 0-471-11709-9. Pages 336 ff.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2010  Simon Josefsson
+ * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* This file is derived from cipher/blowfish.c in Libgcrypt v1.4.6.
+   The adaption to Nettle was made by Simon Josefsson on 2010-11-23.
+   Changes include removing the selftest, renaming u32/byte types to
+   uint32_t/uint8_t, renaming BLOWFISH_ROUNDS to _BLOWFISH_ROUNDS
+   (from Nettle's blowfish.h), dropping the libgcrypt wrapper
+   functions, fixing #include's, remove support for non-16 rounds
+   (there are no test vectors), adding FOR_BLOCK iterations, and
+   running indent on the code. */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "blowfish.h"
+
+#include "macros.h"
+
+/* precomputed S boxes */
+static const struct blowfish_ctx
+initial_ctx = {
+  {
+    { /* ks0 */
+      0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96,
+      0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
+      0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658,
+      0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
+      0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E,
+      0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
+      0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6,
+      0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
+      0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C,
+      0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
+      0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, 0xEF845D5D, 0xE98575B1,
+      0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
+      0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A,
+      0x670C9C61, 0xABD388F0, 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
+      0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176,
+      0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
+      0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706,
+      0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
+      0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B,
+      0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
+      0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C,
+      0xCC814544, 0xAF5EBD09, 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
+      0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A,
+      0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
+      0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760,
+      0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
+      0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, 0x695B27B0, 0xBBCA58C8,
+      0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
+      0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33,
+      0x62FB1341, 0xCEE4C6E8, 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
+      0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0,
+      0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
+      0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777,
+      0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
+      0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, 0x165FA266, 0x80957705,
+      0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
+      0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E,
+      0x226800BB, 0x57B8E0AF, 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
+      0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9,
+      0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
+      0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F,
+      0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
+      0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A
+    },
+    { /* ks1 */
+      0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D,
+      0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
+      0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65,
+      0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
+      0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9,
+      0x3C971814, 0x6B6A70A1, 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
+      0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D,
+      0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
+      0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC,
+      0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
+      0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, 0x4E548B38, 0x4F6DB908,
+      0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
+      0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124,
+      0x501ADDE6, 0x9F84CD87, 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
+      0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908,
+      0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
+      0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B,
+      0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
+      0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, 0x771FE71C, 0x4E3D06FA,
+      0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
+      0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D,
+      0x1939260F, 0x19C27960, 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
+      0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5,
+      0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
+      0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96,
+      0x0334FE1E, 0xAA0363CF, 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
+      0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, 0x648B1EAF, 0x19BDF0CA,
+      0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
+      0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77,
+      0x11ED935F, 0x16681281, 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
+      0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054,
+      0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
+      0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA,
+      0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
+      0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, 0xCF62A1F2, 0x5B8D2646,
+      0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
+      0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA,
+      0x1DADF43E, 0x233F7061, 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
+      0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E,
+      0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
+      0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD,
+      0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
+      0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7
+    },
+    { /* ks2 */
+      0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7,
+      0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
+      0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, 0x4D95FC1D, 0x96B591AF,
+      0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
+      0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4,
+      0x0A2C86DA, 0xE9B66DFB, 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
+      0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC,
+      0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
+      0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332,
+      0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
+      0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, 0x55A867BC, 0xA1159A58,
+      0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
+      0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22,
+      0x48C1133F, 0xC70F86DC, 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
+      0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60,
+      0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
+      0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99,
+      0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
+      0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, 0x0A476341, 0x992EFF74,
+      0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
+      0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3,
+      0xB5390F92, 0x690FED0B, 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
+      0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, 0x37392EB3, 0xCC115979,
+      0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
+      0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA,
+      0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
+      0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, 0x9DBC8057, 0xF0F7C086,
+      0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
+      0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24,
+      0x55464299, 0xBF582E61, 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
+      0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84,
+      0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
+      0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09,
+      0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
+      0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, 0xDCB7DA83, 0x573906FE,
+      0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
+      0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0,
+      0x006058AA, 0x30DC7D62, 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
+      0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188,
+      0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
+      0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8,
+      0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
+      0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0
+    },
+    { /* ks3 */
+      0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742,
+      0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
+      0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, 0x5748AB2F, 0xBC946E79,
+      0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
+      0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A,
+      0x63EF8CE2, 0x9A86EE22, 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
+      0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1,
+      0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
+      0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797,
+      0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
+      0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, 0xE029AC71, 0xE019A5E6,
+      0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
+      0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA,
+      0x03A16125, 0x0564F0BD, 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
+      0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5,
+      0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
+      0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE,
+      0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
+      0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, 0xB39A460A, 0x6445C0DD,
+      0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
+      0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB,
+      0x8D6612AE, 0xBF3C6F47, 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
+      0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC,
+      0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
+      0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC,
+      0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
+      0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, 0x1A908749, 0xD44FBD9A,
+      0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
+      0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A,
+      0x0F91FC71, 0x9B941525, 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
+      0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B,
+      0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
+      0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E,
+      0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
+      0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, 0xF523F357, 0xA6327623,
+      0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
+      0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A,
+      0x45E1D006, 0xC3F27B9A, 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
+      0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3,
+      0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
+      0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C,
+      0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
+      0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6
+    }
+  },
+  { /* ps */
+    0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0,
+    0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
+    0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B
+  }
+};
+
+/* It's unfortunate to have to pick the bytes apart in the round
+ * function. Werner's gnupg/libgcrypt code took the address of x, and
+ * then read the individual bytes depending on the endianness. But
+ * since xr and xl ought to live in registers, copying via memory is a
+ * bad idea. */
+
+#define F(c, x) \
+  ((( (c->s[0][(x>>24) &0xff] + c->s[1][(x>>16) & 0xff]) \
+      ^ c->s[2][(x>>8) & 0xff]) + c->s[3][x & 0xff]) & 0xffffffff)
+
+#define R(c, l,r,i)  do { l ^= c->p[i]; r ^= F(c,l); } while(0)
+
+static void
+encrypt (const struct blowfish_ctx *ctx, uint32_t * ret_xl,
+           uint32_t * ret_xr)
+{
+  uint32_t xl, xr;
+
+  xl = *ret_xl;
+  xr = *ret_xr;
+
+  R (ctx, xl, xr, 0);
+  R (ctx, xr, xl, 1);
+  R (ctx, xl, xr, 2);
+  R (ctx, xr, xl, 3);
+  R (ctx, xl, xr, 4);
+  R (ctx, xr, xl, 5);
+  R (ctx, xl, xr, 6);
+  R (ctx, xr, xl, 7);
+  R (ctx, xl, xr, 8);
+  R (ctx, xr, xl, 9);
+  R (ctx, xl, xr, 10);
+  R (ctx, xr, xl, 11);
+  R (ctx, xl, xr, 12);
+  R (ctx, xr, xl, 13);
+  R (ctx, xl, xr, 14);
+  R (ctx, xr, xl, 15);
+
+  xl ^= ctx->p[_BLOWFISH_ROUNDS];
+  xr ^= ctx->p[_BLOWFISH_ROUNDS + 1];
+
+  *ret_xl = xr;
+  *ret_xr = xl;
+}
+
+static void
+decrypt (const struct blowfish_ctx *ctx, uint32_t * ret_xl, uint32_t * ret_xr)
+{
+  uint32_t xl, xr;
+
+  xl = *ret_xl;
+  xr = *ret_xr;
+
+  R (ctx, xl, xr, 17);
+  R (ctx, xr, xl, 16);
+  R (ctx, xl, xr, 15);
+  R (ctx, xr, xl, 14);
+  R (ctx, xl, xr, 13);
+  R (ctx, xr, xl, 12);
+  R (ctx, xl, xr, 11);
+  R (ctx, xr, xl, 10);
+  R (ctx, xl, xr, 9);
+  R (ctx, xr, xl, 8);
+  R (ctx, xl, xr, 7);
+  R (ctx, xr, xl, 6);
+  R (ctx, xl, xr, 5);
+  R (ctx, xr, xl, 4);
+  R (ctx, xl, xr, 3);
+  R (ctx, xr, xl, 2);
+
+  xl ^= ctx->p[1];
+  xr ^= ctx->p[0];
+
+  *ret_xl = xr;
+  *ret_xr = xl;
+}
+
+#undef F
+#undef R
+
+void
+blowfish_encrypt (const struct blowfish_ctx *ctx,
+                 unsigned length, uint8_t * dst, const uint8_t * src)
+{
+  FOR_BLOCKS (length, dst, src, BLOWFISH_BLOCK_SIZE)
+    {
+      uint32_t d1, d2;
+
+      d1 = src[0] << 24 | src[1] << 16 | src[2] << 8 | src[3];
+      d2 = src[4] << 24 | src[5] << 16 | src[6] << 8 | src[7];
+      encrypt (ctx, &d1, &d2);
+      dst[0] = (d1 >> 24) & 0xff;
+      dst[1] = (d1 >> 16) & 0xff;
+      dst[2] = (d1 >> 8) & 0xff;
+      dst[3] = d1 & 0xff;
+      dst[4] = (d2 >> 24) & 0xff;
+      dst[5] = (d2 >> 16) & 0xff;
+      dst[6] = (d2 >> 8) & 0xff;
+      dst[7] = d2 & 0xff;
+    }
+}
+
+void
+blowfish_decrypt (const struct blowfish_ctx *ctx,
+                 unsigned length, uint8_t * dst, const uint8_t * src)
+{
+  FOR_BLOCKS (length, dst, src, BLOWFISH_BLOCK_SIZE)
+    {
+      uint32_t d1, d2;
+
+      d1 = src[0] << 24 | src[1] << 16 | src[2] << 8 | src[3];
+      d2 = src[4] << 24 | src[5] << 16 | src[6] << 8 | src[7];
+      decrypt (ctx, &d1, &d2);
+      dst[0] = (d1 >> 24) & 0xff;
+      dst[1] = (d1 >> 16) & 0xff;
+      dst[2] = (d1 >> 8) & 0xff;
+      dst[3] = d1 & 0xff;
+      dst[4] = (d2 >> 24) & 0xff;
+      dst[5] = (d2 >> 16) & 0xff;
+      dst[6] = (d2 >> 8) & 0xff;
+      dst[7] = d2 & 0xff;
+    }
+}
+
+int
+blowfish_set_key (struct blowfish_ctx *ctx,
+                 unsigned length, const uint8_t * key)
+{
+  int i, j;
+  uint32_t data, datal, datar;
+
+  *ctx = initial_ctx;
+
+  for (i = j = 0; i < _BLOWFISH_ROUNDS + 2; i++)
+    {
+      data = (key[j] << 24) | (key[(j+1) % length] << 16)
+       | (key[(j+2) % length] << 8) | key[(j+3) % length];
+      ctx->p[i] ^= data;
+      j = (j + 4) % length;
+    }
+
+  datal = datar = 0;
+  for (i = 0; i < _BLOWFISH_ROUNDS + 2; i += 2)
+    {
+      encrypt (ctx, &datal, &datar);
+      ctx->p[i] = datal;
+      ctx->p[i + 1] = datar;
+    }
+  
+  for (j = 0; j < 4; j++)
+    for (i = 0; i < 256; i += 2)
+      {
+       encrypt (ctx, &datal, &datar);
+       ctx->s[j][i] = datal;
+       ctx->s[j][i + 1] = datar;
+    }
+
+  /* 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 ((ctx->s[0][i] == ctx->s[0][j])
+             || (ctx->s[1][i] == ctx->s[1][j])
+             || (ctx->s[2][i] == ctx->s[2][j])
+             || (ctx->s[3][i] == ctx->s[3][j]))
+           return 0;
+       }
+    }
+
+  return 1;
+}
diff --git a/blowfish.h b/blowfish.h
new file mode 100644 (file)
index 0000000..3775b4b
--- /dev/null
@@ -0,0 +1,76 @@
+/* blowfish.h
+ *
+ * Blowfish block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 1998, 2001 FSF, Ray Dassen, Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_BLOWFISH_H_INCLUDED
+#define NETTLE_BLOWFISH_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define blowfish_set_key nettle_blowfish_set_key
+#define blowfish_encrypt nettle_blowfish_encrypt
+#define blowfish_decrypt nettle_blowfish_decrypt
+
+#define BLOWFISH_BLOCK_SIZE 8
+
+/* Variable key size between 64 and 448 bits. */
+#define BLOWFISH_MIN_KEY_SIZE 8
+#define BLOWFISH_MAX_KEY_SIZE 56
+
+/* Default to 128 bits */
+#define BLOWFISH_KEY_SIZE 16
+
+#define _BLOWFISH_ROUNDS 16
+
+struct blowfish_ctx
+{
+  uint32_t s[4][256];
+  uint32_t p[_BLOWFISH_ROUNDS+2];
+};
+
+/* On success, returns 1 and sets ctx->status to BLOWFISH_OK (zero).
+ * On error, returns 0 and sets ctx->status to BLOWFISH_WEAK_KEY. */
+int
+blowfish_set_key(struct blowfish_ctx *ctx,
+                 unsigned length, const uint8_t *key);
+
+void
+blowfish_encrypt(const struct blowfish_ctx *ctx,
+                 unsigned length, uint8_t *dst,
+                 const uint8_t *src);
+void
+blowfish_decrypt(const struct blowfish_ctx *ctx,
+                 unsigned length, uint8_t *dst,
+                 const uint8_t *src);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_BLOWFISH_H_INCLUDED */
diff --git a/buffer-init.c b/buffer-init.c
new file mode 100644 (file)
index 0000000..1eccd7f
--- /dev/null
@@ -0,0 +1,41 @@
+/* buffer-init.c
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+
+#include "buffer.h"
+#include "realloc.h"
+
+/* This is in a separate file so that we don't link in realloc in
+ * programs that don't need it. */
+
+void
+nettle_buffer_init(struct nettle_buffer *buffer)
+{
+  nettle_buffer_init_realloc(buffer, NULL, nettle_realloc);
+}
diff --git a/buffer.c b/buffer.c
new file mode 100644 (file)
index 0000000..73dddd1
--- /dev/null
+++ b/buffer.c
@@ -0,0 +1,134 @@
+/* buffer.c
+ *
+ * A bare-bones string stream.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "buffer.h"
+
+int
+nettle_buffer_grow(struct nettle_buffer *buffer,
+                  unsigned length)
+{
+  assert(buffer->size <= buffer->alloc);
+  
+  if (buffer->size + length > buffer->alloc)
+    {
+      unsigned alloc;
+      uint8_t *p;
+      
+      if (!buffer->realloc)
+       return 0;
+      
+      alloc = buffer->alloc * 2 + length + 100;
+      p = buffer->realloc(buffer->realloc_ctx, buffer->contents, alloc);
+      if (!p)
+       return 0;
+      
+      buffer->contents = p;
+      buffer->alloc = alloc;
+    }
+  return 1;
+}
+
+void
+nettle_buffer_init_realloc(struct nettle_buffer *buffer,
+                          void *realloc_ctx,
+                          nettle_realloc_func *realloc)
+{
+  buffer->contents = NULL;
+  buffer->alloc = 0;
+  buffer->realloc = realloc;
+  buffer->realloc_ctx = realloc_ctx;
+  buffer->size = 0;
+}
+
+void
+nettle_buffer_init_size(struct nettle_buffer *buffer,
+                       unsigned length, uint8_t *space)
+{
+  buffer->contents = space;
+  buffer->alloc = length;
+  buffer->realloc = NULL;
+  buffer->realloc_ctx = NULL;
+  buffer->size = 0;
+}
+
+void
+nettle_buffer_clear(struct nettle_buffer *buffer)
+{
+  if (buffer->realloc)
+    buffer->realloc(buffer->realloc_ctx, buffer->contents, 0);
+
+  buffer->contents = NULL;
+  buffer->alloc = 0;
+  buffer->size = 0;
+}
+
+void
+nettle_buffer_reset(struct nettle_buffer *buffer)
+{
+  buffer->size = 0;
+}
+
+uint8_t *
+nettle_buffer_space(struct nettle_buffer *buffer,
+                   unsigned length)
+{
+  uint8_t *p;
+
+  if (!nettle_buffer_grow(buffer, length))
+    return NULL;
+
+  p = buffer->contents + buffer->size;
+  buffer->size += length;
+  return p;
+}
+     
+int
+nettle_buffer_write(struct nettle_buffer *buffer,
+                   unsigned length, const uint8_t *data)
+{
+  uint8_t *p = nettle_buffer_space(buffer, length);
+  if (p)
+    {
+      memcpy(p, data, length);
+      return 1;
+    }
+  else
+    return 0;
+}
+
+int
+nettle_buffer_copy(struct nettle_buffer *dst,
+                  const struct nettle_buffer *src)
+{
+  return nettle_buffer_write(dst, src->size, src->contents);
+}
diff --git a/buffer.h b/buffer.h
new file mode 100644 (file)
index 0000000..d312a9f
--- /dev/null
+++ b/buffer.h
@@ -0,0 +1,98 @@
+/* buffer.h
+ *
+ * A bare-bones string stream.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_BUFFER_H_INCLUDED
+#define NETTLE_BUFFER_H_INCLUDED
+
+#include "realloc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct nettle_buffer
+{
+  uint8_t *contents;
+  /* Allocated size */
+  unsigned alloc;
+
+  void *realloc_ctx;
+  nettle_realloc_func *realloc;
+
+  /* Current size */
+  unsigned size;
+};
+
+/* Initializes a buffer that uses plain realloc */
+void
+nettle_buffer_init(struct nettle_buffer *buffer);
+
+void
+nettle_buffer_init_realloc(struct nettle_buffer *buffer,
+                          void *realloc_ctx,
+                          nettle_realloc_func *realloc);
+
+/* Initializes a buffer of fix size */
+void
+nettle_buffer_init_size(struct nettle_buffer *buffer,
+                       unsigned length, uint8_t *space);
+
+void
+nettle_buffer_clear(struct nettle_buffer *buffer);
+
+/* Resets the buffer, without freeing the buffer space. */
+void
+nettle_buffer_reset(struct nettle_buffer *buffer);
+
+int
+nettle_buffer_grow(struct nettle_buffer *buffer,
+                  unsigned length);
+
+#define NETTLE_BUFFER_PUTC(buffer, c) \
+( (((buffer)->size < (buffer)->alloc) || nettle_buffer_grow((buffer), 1)) \
+  && ((buffer)->contents[(buffer)->size++] = (c), 1) )
+
+int
+nettle_buffer_write(struct nettle_buffer *buffer,
+                   unsigned length, const uint8_t *data);
+
+/* Like nettle_buffer_write, but instead of copying data to the
+ * buffer, it returns a pointer to the area where the caller can copy
+ * the data. The pointer is valid only until the next call that can
+ * reallocate the buffer. */
+uint8_t *
+nettle_buffer_space(struct nettle_buffer *buffer,
+                   unsigned length);
+
+/* Copy the contents of SRC to the end of DST. */
+int
+nettle_buffer_copy(struct nettle_buffer *dst,
+                  const struct nettle_buffer *src);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_BUFFER_H_INCLUDED */
diff --git a/camellia-crypt-internal.c b/camellia-crypt-internal.c
new file mode 100644 (file)
index 0000000..8a9296e
--- /dev/null
@@ -0,0 +1,170 @@
+/* camellia-crypt-internal.c
+ *
+ * Copyright (C) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation).
+ *
+ * Copyright (C) 2010 Niels Möller
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/*
+ * Algorithm Specification 
+ *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+ */
+
+/* Based on camellia.c ver 1.2.0, see
+   http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/camellia-LGPL-1.2.0.tar.gz.
+ */
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <limits.h>
+
+#include "camellia-internal.h"
+
+#include "macros.h"
+
+#define CAMELLIA_FL(x, k) do {                 \
+  uint32_t __xl, __xr, __kl, __kr, __t;                \
+  __xl = (x) >> 32;                            \
+  __xr = (x) & 0xffffffff;                     \
+  __kl = (k) >> 32;                            \
+  __kr = (k) & 0xffffffff;                     \
+  __t = __xl & __kl;                           \
+  __xr ^= ROL32(1, __t);                       \
+  __xl ^= (__xr | __kr);                       \
+  (x) = ((uint64_t) __xl << 32) | __xr;                \
+} while (0)
+
+#define CAMELLIA_FLINV(x, k) do {              \
+  uint32_t __xl, __xr, __kl, __kr, __t;                \
+  __xl = (x) >> 32;                            \
+  __xr = (x) & 0xffffffff;                     \
+  __kl = (k) >> 32;                            \
+  __kr = (k) & 0xffffffff;                     \
+  __xl ^= (__xr | __kr);                       \
+  __t = __xl & __kl;                           \
+  __xr ^= ROL32(1, __t);                       \
+  (x) = ((uint64_t) __xl << 32) | __xr;                \
+} while (0)
+
+#if HAVE_NATIVE_64_BIT
+#define CAMELLIA_ROUNDSM(T, x, k, y) do {                      \
+    uint32_t __il, __ir;                                       \
+    __ir                                                       \
+      = T->sp1110[(x) & 0xff]                                  \
+      ^ T->sp0222[((x) >> 24) & 0xff]                          \
+      ^ T->sp3033[((x) >> 16) & 0xff]                          \
+      ^ T->sp4404[((x) >> 8) & 0xff];                          \
+    /* ir == (t6^t7^t8),(t5^t7^t8),(t5^t6^t8),(t5^t6^t7) */    \
+    __il                                                       \
+      = T->sp1110[ (x) >> 56]                                  \
+      ^ T->sp0222[((x) >> 48) & 0xff]                          \
+      ^ T->sp3033[((x) >> 40) & 0xff]                          \
+      ^ T->sp4404[((x) >> 32) & 0xff];                         \
+    /* il == (t1^t3^t4),(t1^t2^t4),(t1^t2^t3),(t2^t3^t4) */    \
+    __ir ^= __il;                                              \
+    /* ir == (t1^t3^t4^t6^t7^t8),(t1^t2^t4^t5^t7^t8),          \
+       (t1^t2^t3^t5^t6^t8),(t2^t3^t4^t5^t6^t7)                 \
+       == y1,y2,y3,y4 */                                       \
+    __il = ROL32(24, __il);                                    \
+    /* il == (t2^t3^t4),(t1^t3^t4),(t1^t2^t4),(t1^t2^t3) */    \
+    __il ^= __ir;                                              \
+    /* il == (t1^t2^t6^t7^t8),(t2^t3^t5^t7^t8),                        \
+       (t3^t4^t5^t6^t8),(t1^t4^t5^t6^t7)                       \
+       == y5,y6,y7,y8 */                                       \
+    y ^= (k);                                                  \
+    y ^= ((uint64_t) __ir << 32) | __il;                       \
+  } while (0)
+#else /* !HAVE_NATIVE_64_BIT */
+#define CAMELLIA_ROUNDSM(T, x, k, y) do {                      \
+    uint32_t __il, __ir;                                       \
+    __ir                                                       \
+      = T->sp1110[(x) & 0xff]                                  \
+      ^ T->sp0222[((x) >> 24) & 0xff]                          \
+      ^ T->sp3033[((x) >> 16) & 0xff]                          \
+      ^ T->sp4404[((x) >> 8) & 0xff];                          \
+    /* ir == (t6^t7^t8),(t5^t7^t8),(t5^t6^t8),(t5^t6^t7) */    \
+    __il                                                       \
+      = T->sp1110[ (x) >> 56]                                  \
+      ^ T->sp0222[((x) >> 48) & 0xff]                          \
+      ^ T->sp3033[((x) >> 40) & 0xff]                          \
+      ^ T->sp4404[((x) >> 32) & 0xff];                         \
+    /* il == (t1^t3^t4),(t1^t2^t4),(t1^t2^t3),(t2^t3^t4) */    \
+    __il ^= (k) >> 32;                                         \
+    __ir ^= (k) & 0xffffffff;                                  \
+    __ir ^= __il;                                              \
+    /* ir == (t1^t3^t4^t6^t7^t8),(t1^t2^t4^t5^t7^t8),          \
+       (t1^t2^t3^t5^t6^t8),(t2^t3^t4^t5^t6^t7)                 \
+       == y1,y2,y3,y4 */                                       \
+    __il = ROL32(24, __il);                                    \
+    /* il == (t2^t3^t4),(t1^t3^t4),(t1^t2^t4),(t1^t2^t3) */    \
+    __il ^= __ir;                                              \
+    /* il == (t1^t2^t6^t7^t8),(t2^t3^t5^t7^t8),                        \
+       (t3^t4^t5^t6^t8),(t1^t4^t5^t6^t7)                       \
+       == y5,y6,y7,y8 */                                       \
+    y ^= ((uint64_t) __ir << 32) | __il;                       \
+  } while (0)
+#endif
+
+void
+_camellia_crypt(const struct camellia_ctx *ctx,
+               const struct camellia_table *T,
+               unsigned length, uint8_t *dst,
+               const uint8_t *src)
+{
+  FOR_BLOCKS(length, dst, src, CAMELLIA_BLOCK_SIZE)
+    {
+      uint64_t i0,i1;
+      unsigned i;
+
+      i0 = READ_UINT64(src);
+      i1 = READ_UINT64(src +  8);
+      
+      /* pre whitening but absorb kw2*/
+      i0 ^= ctx->keys[0];
+
+      /* main iteration */
+
+      CAMELLIA_ROUNDSM(T, i0,ctx->keys[1], i1);
+      CAMELLIA_ROUNDSM(T, i1,ctx->keys[2], i0);
+      CAMELLIA_ROUNDSM(T, i0,ctx->keys[3], i1);
+      CAMELLIA_ROUNDSM(T, i1,ctx->keys[4], i0);
+      CAMELLIA_ROUNDSM(T, i0,ctx->keys[5], i1);
+      CAMELLIA_ROUNDSM(T, i1,ctx->keys[6], i0);
+      
+      for (i = 0; i < ctx->nkeys - 8; i+= 8)
+       {
+         CAMELLIA_FL(i0, ctx->keys[i+7]);
+         CAMELLIA_FLINV(i1, ctx->keys[i+8]);
+         
+         CAMELLIA_ROUNDSM(T, i0,ctx->keys[i+9], i1);
+         CAMELLIA_ROUNDSM(T, i1,ctx->keys[i+10], i0);
+         CAMELLIA_ROUNDSM(T, i0,ctx->keys[i+11], i1);
+         CAMELLIA_ROUNDSM(T, i1,ctx->keys[i+12], i0);
+         CAMELLIA_ROUNDSM(T, i0,ctx->keys[i+13], i1);
+         CAMELLIA_ROUNDSM(T, i1,ctx->keys[i+14], i0);
+       }
+
+      /* post whitening but kw4 */
+      i1 ^= ctx->keys[i+7];
+
+      WRITE_UINT64(dst     , i1);
+      WRITE_UINT64(dst +  8, i0);
+    }
+}
diff --git a/camellia-crypt.c b/camellia-crypt.c
new file mode 100644 (file)
index 0000000..62c3435
--- /dev/null
@@ -0,0 +1,45 @@
+/* camellia-encrypt.c
+ *
+ * Crypt function for the camellia block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "camellia-internal.h"
+
+/* The main point on this function is to help the assembler
+   implementations of _nettle_camellia_crypt to get the table pointer.
+   For PIC code, the details can be complex and system dependent. */
+void
+camellia_crypt(const struct camellia_ctx *ctx,
+                unsigned length, uint8_t *dst,
+           const uint8_t *src)
+{
+  assert(!(length % CAMELLIA_BLOCK_SIZE) );
+  _camellia_crypt(ctx, &_camellia_table,
+                 length, dst, src);
+}
diff --git a/camellia-internal.h b/camellia-internal.h
new file mode 100644 (file)
index 0000000..f9d40fc
--- /dev/null
@@ -0,0 +1,74 @@
+/* camellia-internal.h
+ *
+ * The camellia block cipher.
+ */
+
+/* Copyright (C) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation).
+ *
+ * Copyright (C) 2010 Niels Möller
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/*
+ * Algorithm Specification 
+ *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+ */
+
+/* Based on camellia.c ver 1.2.0, see
+   http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/camellia-LGPL-1.2.0.tar.gz.
+ */
+
+#ifndef NETTLE_CAMELLIA_INTERNAL_H_INCLUDED
+#define NETTLE_CAMELLIA_INTERNAL_H_INCLUDED
+
+#include "camellia.h"
+
+/* Name mangling */
+#define _camellia_crypt _nettle_camellia_crypt
+#define _camellia_table _nettle_camellia_table
+
+/*
+ *  macros
+ */
+
+/* Rotation of 32-bit values. */
+#define ROL32(bits, x) (((x) << (bits)) | ((x) >> (32 - (bits))))
+
+/* Destructive rotation of 128 bit values. */
+#define ROL128(bits, xl, xr) do {              \
+    uint64_t __rol128_t = (xl);                             \
+    (xl) = ((xl) << (bits)) | ((xr) >> (64 - (bits)));    \
+    (xr) = ((xr) << (bits)) | (__rol128_t >> (64 - (bits)));   \
+  } while (0)
+
+struct camellia_table
+{
+  uint32_t sp1110[256];
+  uint32_t sp0222[256];
+  uint32_t sp3033[256];
+  uint32_t sp4404[256];
+};
+
+void
+_camellia_crypt(const struct camellia_ctx *ctx,
+               const struct camellia_table *T,
+               unsigned length, uint8_t *dst,
+               const uint8_t *src);
+
+extern const struct camellia_table _camellia_table;
+
+#endif /* NETTLE_CAMELLIA_INTERNAL_H_INCLUDED */
diff --git a/camellia-meta.c b/camellia-meta.c
new file mode 100644 (file)
index 0000000..68eef3d
--- /dev/null
@@ -0,0 +1,38 @@
+/* camellia-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "camellia.h"
+
+const struct nettle_cipher nettle_camellia128
+= _NETTLE_CIPHER_SEP_SET_KEY(camellia, CAMELLIA, 128);
+
+const struct nettle_cipher nettle_camellia192
+= _NETTLE_CIPHER_SEP_SET_KEY(camellia, CAMELLIA, 192);
+
+const struct nettle_cipher nettle_camellia256
+= _NETTLE_CIPHER_SEP_SET_KEY(camellia, CAMELLIA, 256);
diff --git a/camellia-set-decrypt-key.c b/camellia-set-decrypt-key.c
new file mode 100644 (file)
index 0000000..cd49c11
--- /dev/null
@@ -0,0 +1,61 @@
+/* camellia-set-decrypt-key.c
+ *
+ * Inverse key setup for the camellia block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "camellia.h"
+
+#define SWAP(a, b) \
+do { uint64_t t_swap = (a); (a) = (b); (b) = t_swap; } while(0)
+
+void
+camellia_invert_key(struct camellia_ctx *dst,
+                   const struct camellia_ctx *src)
+{
+  unsigned nkeys = src->nkeys;
+  unsigned i;
+  if (dst == src)
+    {
+      for (i = 0; i < nkeys - 1 - i; i++)
+       SWAP(dst->keys[i], dst->keys[nkeys - 1 - i]);
+    }
+  else
+    {
+      dst->nkeys = nkeys;
+
+      for (i = 0; i < nkeys; i++)
+       dst->keys[i] = src->keys[nkeys - 1 - i];
+    }
+}
+
+void
+camellia_set_decrypt_key(struct camellia_ctx *ctx,
+                        unsigned length, const uint8_t *key)
+{
+  camellia_set_encrypt_key(ctx, length, key);
+  camellia_invert_key(ctx, ctx);
+}
diff --git a/camellia-set-encrypt-key.c b/camellia-set-encrypt-key.c
new file mode 100644 (file)
index 0000000..989e3c7
--- /dev/null
@@ -0,0 +1,336 @@
+/* camellia-set-encrypt-key.c
+ *
+ * Key setup for the camellia block cipher.
+ */
+/*
+ * Copyright (C) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation).
+ *
+ * Copyright (C) 2010 Niels Möller
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/*
+ * Algorithm Specification 
+ *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+ */
+
+/* Based on camellia.c ver 1.2.0, see
+   http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/camellia-LGPL-1.2.0.tar.gz.
+ */
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <limits.h>
+
+#include "camellia-internal.h"
+
+#include "macros.h"
+
+/* key constants */
+
+#define SIGMA1 0xA09E667F3BCC908BULL
+#define SIGMA2 0xB67AE8584CAA73B2ULL
+#define SIGMA3 0xC6EF372FE94F82BEULL
+#define SIGMA4 0x54FF53A5F1D36F1CULL
+#define SIGMA5 0x10E527FADE682D1DULL
+#define SIGMA6 0xB05688C2B3E6C1FDULL
+
+#define CAMELLIA_SP1110(INDEX) (_nettle_camellia_table.sp1110[(int)(INDEX)])
+#define CAMELLIA_SP0222(INDEX) (_nettle_camellia_table.sp0222[(int)(INDEX)])
+#define CAMELLIA_SP3033(INDEX) (_nettle_camellia_table.sp3033[(int)(INDEX)])
+#define CAMELLIA_SP4404(INDEX) (_nettle_camellia_table.sp4404[(int)(INDEX)])
+
+#define CAMELLIA_F(x, k, y) do {               \
+    uint32_t __yl, __yr;                       \
+    uint64_t __i = (x) ^ (k);                  \
+    __yl                                       \
+      = CAMELLIA_SP1110( __i & 0xff)           \
+      ^ CAMELLIA_SP0222((__i >> 24) & 0xff)    \
+      ^ CAMELLIA_SP3033((__i >> 16) & 0xff)    \
+      ^ CAMELLIA_SP4404((__i >> 8) & 0xff);    \
+    __yr                                       \
+      = CAMELLIA_SP1110( __i >> 56)            \
+      ^ CAMELLIA_SP0222((__i >> 48) & 0xff)    \
+      ^ CAMELLIA_SP3033((__i >> 40) & 0xff)    \
+      ^ CAMELLIA_SP4404((__i >> 32) & 0xff);   \
+    __yl ^= __yr;                              \
+    __yr = ROL32(24, __yr);                    \
+    __yr ^= __yl;                              \
+    (y) = ((uint64_t) __yl << 32) | __yr;      \
+  } while (0)
+
+#if ! HAVE_NATIVE_64_BIT
+#define CAMELLIA_F_HALF_INV(x) do {            \
+    uint32_t __t, __w;                         \
+    __t = (x) >> 32;                           \
+    __w = __t ^(x);                            \
+    __w = ROL32(8, __w);                       \
+    (x) = ((uint64_t) __w << 32) | (__t ^ __w);        \
+  } while (0)
+#endif
+
+void
+camellia_set_encrypt_key(struct camellia_ctx *ctx,
+                        unsigned length, const uint8_t *key)
+{
+  uint64_t k0, k1;
+
+  uint64_t subkey[34];
+  uint64_t w, kw2, kw4;
+  
+  uint32_t dw, tl, tr;
+  unsigned i;
+
+  k0 = READ_UINT64(key);
+  k1 = READ_UINT64(key +  8);
+  
+  if (length == 16)
+    {
+      ctx->nkeys = 24;
+      /**
+       * generate KL dependent subkeys
+       */
+      subkey[0] = k0; subkey[1] = k1;
+      ROL128(15, k0, k1);
+      subkey[4] = k0; subkey[5] = k1;
+      ROL128(30, k0, k1);
+      subkey[10] = k0; subkey[11] = k1;
+      ROL128(15, k0, k1);
+      subkey[13] = k1;
+      ROL128(17, k0, k1);
+      subkey[16] = k0; subkey[17] = k1;
+      ROL128(17, k0, k1);
+      subkey[18] = k0; subkey[19] = k1;
+      ROL128(17, k0, k1);
+      subkey[22] = k0; subkey[23] = k1;
+
+      /* generate KA. D1 is k0, d2 is k1. */
+      /* FIXME: Make notation match the spec better. */
+      /* For the 128-bit case, KR = 0, the construction of KA reduces to:
+
+        D1 = KL >> 64;
+        W = KL & MASK64;
+        D2 = F(D1, Sigma1);
+        W = D2 ^ W
+        D1 = F(W, Sigma2)
+        D2 = D2 ^ F(D1, Sigma3);
+        D1 = D1 ^ F(D2, Sigma4);
+        KA = (D1 << 64) | D2;
+      */
+      k0 = subkey[0]; w = subkey[1];
+      CAMELLIA_F(k0, SIGMA1, k1);
+      w ^= k1;
+      CAMELLIA_F(w, SIGMA2, k0);
+      CAMELLIA_F(k0, SIGMA3, w);
+      k1 ^= w;
+      CAMELLIA_F(k1, SIGMA4, w);
+      k0 ^= w;
+
+      /* generate KA dependent subkeys */
+      subkey[2] = k0; subkey[3] = k1;
+      ROL128(15, k0, k1);
+      subkey[6] = k0; subkey[7] = k1;
+      ROL128(15, k0, k1);
+      subkey[8] = k0; subkey[9] = k1;
+      ROL128(15, k0, k1);
+      subkey[12] = k0;
+      ROL128(15, k0, k1);
+      subkey[14] = k0; subkey[15] = k1;
+      ROL128(34, k0, k1);
+      subkey[20] = k0; subkey[21] = k1;
+      ROL128(17, k0, k1);
+      subkey[24] = k0; subkey[25] = k1;
+    }
+  else
+    {
+      uint64_t k2, k3;
+
+      ctx->nkeys = 32;
+      k2 = READ_UINT64(key + 16);
+
+      if (length == 24)
+       k3 = ~k2;
+      else
+       {
+         assert (length == 32);
+         k3 = READ_UINT64(key + 24);
+       }
+      /* generate KL dependent subkeys */
+      subkey[0] = k0; subkey[1] = k1;
+      ROL128(45, k0, k1);
+      subkey[12] = k0; subkey[13] = k1;
+      ROL128(15, k0, k1);
+      subkey[16] = k0; subkey[17] = k1;
+      ROL128(17, k0, k1);
+      subkey[22] = k0; subkey[23] = k1;
+      ROL128(34, k0, k1);
+      subkey[30] = k0; subkey[31] = k1;
+
+      /* generate KR dependent subkeys */
+      ROL128(15, k2, k3);
+      subkey[4] = k2; subkey[5] = k3;
+      ROL128(15, k2, k3);
+      subkey[8] = k2; subkey[9] = k3;
+      ROL128(30, k2, k3);
+      subkey[18] = k2; subkey[19] = k3;
+      ROL128(34, k2, k3);
+      subkey[26] = k2; subkey[27] = k3;
+      ROL128(34, k2, k3);
+
+      /* generate KA */
+      /* The construction of KA is done as
+
+        D1 = (KL ^ KR) >> 64
+        D2 = (KL ^ KR) & MASK64
+        W = F(D1, SIGMA1)
+        D2 = D2 ^ W
+        D1 = F(D2, SIGMA2) ^ (KR >> 64)
+        D2 = F(D1, SIGMA3) ^ W ^ (KR & MASK64)
+        D1 = D1 ^ F(W, SIGMA2)
+        D2 = D2 ^ F(D1, SIGMA3)
+        D1 = D1 ^ F(D2, SIGMA4)
+      */
+
+      k0 = subkey[0] ^ k2;
+      k1 = subkey[1] ^ k3;
+
+      CAMELLIA_F(k0, SIGMA1, w);
+      k1 ^= w;
+
+      CAMELLIA_F(k1, SIGMA2, k0);
+      k0 ^= k2;
+
+      CAMELLIA_F(k0, SIGMA3, k1);
+      k1 ^= w ^ k3;
+
+      CAMELLIA_F(k1, SIGMA4, w);
+      k0 ^= w;
+
+      /* generate KB */
+      k2 ^= k0; k3 ^= k1;
+      CAMELLIA_F(k2, SIGMA5, w);
+      k3 ^= w;
+      CAMELLIA_F(k3, SIGMA6, w);
+      k2 ^= w;
+
+      /* generate KA dependent subkeys */
+      ROL128(15, k0, k1);
+      subkey[6] = k0; subkey[7] = k1;
+      ROL128(30, k0, k1);
+      subkey[14] = k0; subkey[15] = k1;
+      ROL128(32, k0, k1);
+      subkey[24] = k0; subkey[25] = k1;
+      ROL128(17, k0, k1);
+      subkey[28] = k0; subkey[29] = k1;
+
+      /* generate KB dependent subkeys */
+      subkey[2] = k2; subkey[3] = k3;
+      ROL128(30, k2, k3);
+      subkey[10] = k2; subkey[11] = k3;
+      ROL128(30, k2, k3);
+      subkey[20] = k2; subkey[21] = k3;
+      ROL128(51, k2, k3);
+      subkey[32] = k2; subkey[33] = k3;
+    }
+
+  /* At this point, the subkey array contains the subkeys as described
+     in the spec, 26 for short keys and 34 for large keys. */
+
+  /* absorb kw2 to other subkeys */
+  kw2 = subkey[1];
+
+  subkey[3] ^= kw2;
+  subkey[5] ^= kw2;
+  subkey[7] ^= kw2;
+  for (i = 8; i < ctx->nkeys; i += 8)
+    {
+      /* FIXME: gcc for x86_32 is smart enough to fetch the 32 low bits
+        and xor the result into the 32 high bits, but it still generates
+        worse code than for explicit 32-bit operations. */
+      kw2 ^= (kw2 & ~subkey[i+1]) << 32;
+      dw = (kw2 & subkey[i+1]) >> 32; kw2 ^= ROL32(1, dw); 
+
+      subkey[i+3] ^= kw2;
+      subkey[i+5] ^= kw2;
+      subkey[i+7] ^= kw2;
+    }
+  subkey[i] ^= kw2;
+  
+  /* absorb kw4 to other subkeys */  
+  kw4 = subkey[ctx->nkeys + 1];
+
+  for (i = ctx->nkeys - 8; i > 0; i -= 8)
+    {
+      subkey[i+6] ^= kw4;
+      subkey[i+4] ^= kw4;
+      subkey[i+2] ^= kw4;
+      kw4 ^= (kw4 & ~subkey[i]) << 32;
+      dw = (kw4 & subkey[i]) >> 32; kw4 ^= ROL32(1, dw);      
+    }
+
+  subkey[6] ^= kw4;
+  subkey[4] ^= kw4;
+  subkey[2] ^= kw4;
+  subkey[0] ^= kw4;
+
+  /* key XOR is end of F-function */
+  ctx->keys[0] = subkey[0] ^ subkey[2];
+  ctx->keys[1] = subkey[3];
+
+  ctx->keys[2] = subkey[2] ^ subkey[4];
+  ctx->keys[3] = subkey[3] ^ subkey[5];
+  ctx->keys[4] = subkey[4] ^ subkey[6];
+  ctx->keys[5] = subkey[5] ^ subkey[7];
+
+  for (i = 8; i < ctx->nkeys; i += 8)
+    {
+      tl = (subkey[i+2] >> 32) ^ (subkey[i+2] & ~subkey[i]);
+      dw = tl & (subkey[i] >> 32);
+      tr = subkey[i+2] ^ ROL32(1, dw);
+      ctx->keys[i-2] = subkey[i-2] ^ ( ((uint64_t) tl << 32) | tr);
+
+      ctx->keys[i-1] = subkey[i];
+      ctx->keys[i] = subkey[i+1];
+
+      tl = (subkey[i-1] >> 32) ^ (subkey[i-1] & ~subkey[i+1]);
+      dw = tl & (subkey[i+1] >> 32);
+      tr = subkey[i-1] ^ ROL32(1, dw);
+      ctx->keys[i+1] = subkey[i+3] ^ ( ((uint64_t) tl << 32) | tr);
+
+      ctx->keys[i+2] = subkey[i+2] ^ subkey[i+4];
+      ctx->keys[i+3] = subkey[i+3] ^ subkey[i+5];
+      ctx->keys[i+4] = subkey[i+4] ^ subkey[i+6];
+      ctx->keys[i+5] = subkey[i+5] ^ subkey[i+7];
+    }
+  ctx->keys[i-2] = subkey[i-2];
+  ctx->keys[i-1] = subkey[i] ^ subkey[i-1];
+
+#if !HAVE_NATIVE_64_BIT
+  for (i = 0; i < ctx->nkeys; i += 8)
+    {
+      /* apply the inverse of the last half of F-function */
+      CAMELLIA_F_HALF_INV(ctx->keys[i+1]);
+      CAMELLIA_F_HALF_INV(ctx->keys[i+2]);
+      CAMELLIA_F_HALF_INV(ctx->keys[i+3]);
+      CAMELLIA_F_HALF_INV(ctx->keys[i+4]);
+      CAMELLIA_F_HALF_INV(ctx->keys[i+5]);
+      CAMELLIA_F_HALF_INV(ctx->keys[i+6]);
+    }
+#endif
+}
diff --git a/camellia-table.c b/camellia-table.c
new file mode 100644 (file)
index 0000000..9245bc9
--- /dev/null
@@ -0,0 +1,310 @@
+/* camellia-table.c
+ *
+ * SBOX tables used by both encryption and key setup.
+ */
+
+/* Copyright (C) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation).
+ *
+ * Copyright (C) 2010 Niels Möller
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/*
+ * Algorithm Specification 
+ *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+ */
+
+/* Based on camellia.c ver 1.2.0, see
+   http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/camellia-LGPL-1.2.0.tar.gz.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "camellia-internal.h"
+
+const struct camellia_table _camellia_table = {
+  /* sp1110 */
+  {
+    0x70707000,0x82828200,0x2c2c2c00,0xececec00,
+    0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
+    0xe4e4e400,0x85858500,0x57575700,0x35353500,
+    0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
+    0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
+    0x45454500,0x19191900,0xa5a5a500,0x21212100,
+    0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
+    0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
+    0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
+    0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
+    0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
+    0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
+    0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
+    0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
+    0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
+    0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
+    0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
+    0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
+    0x74747400,0x12121200,0x2b2b2b00,0x20202000,
+    0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
+    0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
+    0x34343400,0x7e7e7e00,0x76767600,0x05050500,
+    0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
+    0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
+    0x14141400,0x58585800,0x3a3a3a00,0x61616100,
+    0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
+    0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
+    0x53535300,0x18181800,0xf2f2f200,0x22222200,
+    0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
+    0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
+    0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
+    0x60606000,0xfcfcfc00,0x69696900,0x50505000,
+    0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
+    0xa1a1a100,0x89898900,0x62626200,0x97979700,
+    0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
+    0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
+    0x10101000,0xc4c4c400,0x00000000,0x48484800,
+    0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
+    0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
+    0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
+    0x87878700,0x5c5c5c00,0x83838300,0x02020200,
+    0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
+    0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
+    0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
+    0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
+    0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
+    0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
+    0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
+    0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
+    0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
+    0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
+    0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
+    0x78787800,0x98989800,0x06060600,0x6a6a6a00,
+    0xe7e7e700,0x46464600,0x71717100,0xbababa00,
+    0xd4d4d400,0x25252500,0xababab00,0x42424200,
+    0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
+    0x72727200,0x07070700,0xb9b9b900,0x55555500,
+    0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
+    0x36363600,0x49494900,0x2a2a2a00,0x68686800,
+    0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
+    0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
+    0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
+    0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
+    0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
+  },
+  /* sp0222 */
+  {
+    0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
+    0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
+    0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
+    0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,
+    0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,
+    0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,
+    0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,
+    0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,
+    0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,
+    0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,
+    0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,
+    0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,
+    0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,
+    0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,
+    0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,
+    0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,
+    0x00171717,0x001a1a1a,0x00353535,0x00cccccc,
+    0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,
+    0x00e8e8e8,0x00242424,0x00565656,0x00404040,
+    0x00e1e1e1,0x00636363,0x00090909,0x00333333,
+    0x00bfbfbf,0x00989898,0x00979797,0x00858585,
+    0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,
+    0x00dadada,0x006f6f6f,0x00535353,0x00626262,
+    0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,
+    0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,
+    0x00bdbdbd,0x00363636,0x00222222,0x00383838,
+    0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,
+    0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,
+    0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,
+    0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,
+    0x00484848,0x00101010,0x00d1d1d1,0x00515151,
+    0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,
+    0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,
+    0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,
+    0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,
+    0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,
+    0x00202020,0x00898989,0x00000000,0x00909090,
+    0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,
+    0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,
+    0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,
+    0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,
+    0x009b9b9b,0x00949494,0x00212121,0x00666666,
+    0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,
+    0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,
+    0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,
+    0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,
+    0x00030303,0x002d2d2d,0x00dedede,0x00969696,
+    0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,
+    0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,
+    0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,
+    0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,
+    0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,
+    0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,
+    0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,
+    0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,
+    0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,
+    0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,
+    0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,
+    0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,
+    0x00787878,0x00707070,0x00e3e3e3,0x00494949,
+    0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,
+    0x00777777,0x00939393,0x00868686,0x00838383,
+    0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,
+    0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
+  },
+  /* sp3033 */
+  {
+    0x38003838,0x41004141,0x16001616,0x76007676,
+    0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
+    0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
+    0x75007575,0x06000606,0x57005757,0xa000a0a0,
+    0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,
+    0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,
+    0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,
+    0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,
+    0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,
+    0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,
+    0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,
+    0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,
+    0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,
+    0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,
+    0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,
+    0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,
+    0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,
+    0xfd00fdfd,0x66006666,0x58005858,0x96009696,
+    0x3a003a3a,0x09000909,0x95009595,0x10001010,
+    0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,
+    0xef00efef,0x26002626,0xe500e5e5,0x61006161,
+    0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,
+    0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,
+    0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,
+    0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,
+    0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,
+    0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,
+    0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,
+    0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,
+    0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,
+    0x12001212,0x04000404,0x74007474,0x54005454,
+    0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,
+    0x55005555,0x68006868,0x50005050,0xbe00bebe,
+    0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,
+    0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,
+    0x70007070,0xff00ffff,0x32003232,0x69006969,
+    0x08000808,0x62006262,0x00000000,0x24002424,
+    0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,
+    0x45004545,0x81008181,0x73007373,0x6d006d6d,
+    0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,
+    0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,
+    0xe600e6e6,0x25002525,0x48004848,0x99009999,
+    0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,
+    0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,
+    0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,
+    0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,
+    0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,
+    0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,
+    0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,
+    0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,
+    0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,
+    0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,
+    0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
+    0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
+    0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
+    0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
+    0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
+    0x7c007c7c,0x77007777,0x56005656,0x05000505,
+    0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
+    0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
+    0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
+    0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
+    0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
+    0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
+  },
+  /* sp4404 */
+  {
+    0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
+    0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
+    0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
+    0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
+    0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
+    0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
+    0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
+    0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
+    0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
+    0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
+    0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
+    0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
+    0x14140014,0x3a3a003a,0xdede00de,0x11110011,
+    0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
+    0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
+    0x24240024,0xe8e800e8,0x60600060,0x69690069,
+    0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
+    0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
+    0x10100010,0x00000000,0xa3a300a3,0x75750075,
+    0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
+    0x87870087,0x83830083,0xcdcd00cd,0x90900090,
+    0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
+    0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
+    0x81810081,0x6f6f006f,0x13130013,0x63630063,
+    0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
+    0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
+    0x78780078,0x06060006,0xe7e700e7,0x71710071,
+    0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
+    0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
+    0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
+    0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
+    0x15150015,0xadad00ad,0x77770077,0x80800080,
+    0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
+    0x85850085,0x35350035,0x0c0c000c,0x41410041,
+    0xefef00ef,0x93930093,0x19190019,0x21210021,
+    0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
+    0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
+    0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
+    0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
+    0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
+    0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
+    0x12120012,0x20200020,0xb1b100b1,0x99990099,
+    0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
+    0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
+    0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
+    0x0f0f000f,0x16160016,0x18180018,0x22220022,
+    0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
+    0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
+    0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
+    0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
+    0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
+    0x03030003,0xdada00da,0x3f3f003f,0x94940094,
+    0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
+    0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
+    0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
+    0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
+    0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
+    0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
+    0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
+    0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
+    0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
+    0x49490049,0x68680068,0x38380038,0xa4a400a4,
+    0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
+    0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
+  }
+};
diff --git a/camellia.h b/camellia.h
new file mode 100644 (file)
index 0000000..f4f3e1e
--- /dev/null
@@ -0,0 +1,82 @@
+/* camellia.h
+ *
+ * Copyright (C) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation).
+ *
+ * Copyright (C) 2010 Niels Möller
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef NETTLE_CAMELLIA_H_INCLUDED
+#define NETTLE_CAMELLIA_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define camellia_set_encrypt_key nettle_camellia_set_encrypt_key
+#define camellia_set_decrypt_key nettle_camellia_set_decrypt_key
+#define camellia_invert_key nettle_camellia_invert_key
+#define camellia_crypt nettle_camellia_crypt
+#define camellia_crypt nettle_camellia_crypt
+
+#define CAMELLIA_BLOCK_SIZE 16
+/* Valid key sizes are 128, 192 or 256 bits (16, 24 or 32 bytes) */
+#define CAMELLIA_MIN_KEY_SIZE 16
+#define CAMELLIA_MAX_KEY_SIZE 32
+#define CAMELLIA_KEY_SIZE 32
+
+struct camellia_ctx
+{
+  /* Number of subkeys. */
+  unsigned nkeys;
+  
+  /* For 128-bit keys, there are 18 regular rounds, pre- and
+     post-whitening, and two FL and FLINV rounds, using a total of 26
+     subkeys, each of 64 bit. For 192- and 256-bit keys, there are 6
+     additional regular rounds and one additional FL and FLINV, using
+     a total of 34 subkeys. */
+  /* The clever combination of subkeys imply one of the pre- and
+     post-whitening keys is folded with the round keys, so that subkey
+     #1 and the last one (#25 or #33) is not used. The result is that
+     we have only 24 or 32 subkeys at the end of key setup. */
+  uint64_t keys[32];
+};
+
+void
+camellia_set_encrypt_key(struct camellia_ctx *ctx,
+                        unsigned length, const uint8_t *key);
+
+void
+camellia_set_decrypt_key(struct camellia_ctx *ctx,
+                        unsigned length, const uint8_t *key);
+
+void
+camellia_invert_key(struct camellia_ctx *dst,
+                   const struct camellia_ctx *src);
+  
+void
+camellia_crypt(const struct camellia_ctx *ctx,
+              unsigned length, uint8_t *dst,
+              const uint8_t *src);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* NETTLE_CAMELLIA_H_INCLUDED */
diff --git a/cast128-meta.c b/cast128-meta.c
new file mode 100644 (file)
index 0000000..9c863d9
--- /dev/null
@@ -0,0 +1,32 @@
+/* cast128-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "cast128.h"
+
+const struct nettle_cipher nettle_cast128
+= _NETTLE_CIPHER_FIX(cast128, CAST128);
diff --git a/cast128.c b/cast128.c
new file mode 100644 (file)
index 0000000..884cfa7
--- /dev/null
+++ b/cast128.c
@@ -0,0 +1,276 @@
+/* cast128.c
+ *
+ * The CAST-128 block cipher, described in RFC 2144.
+ */
+
+/*     CAST-128 in C
+ *     Written by Steve Reid <sreid@sea-to-sky.net>
+ *     100% Public Domain - no warranty
+ *     Released 1997.10.11
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "cast128.h"
+#include "cast128_sboxes.h"
+
+#include "macros.h"
+
+#define CAST_SMALL_KEY 10
+#define CAST_SMALL_ROUNDS 12
+#define CAST_FULL_ROUNDS 16
+
+/* Macros to access 8-bit bytes out of a 32-bit word */
+#define U8a(x) ( (uint8_t) (x>>24) )
+#define U8b(x) ( (uint8_t) ((x>>16)&0xff) )
+#define U8c(x) ( (uint8_t) ((x>>8)&0xff) )
+#define U8d(x) ( (uint8_t) ((x)&0xff) )
+
+/* Circular left shift */
+#define ROL(x, n) ( ((x)<<(n)) | ((x)>>(32-(n))) )
+
+/* CAST-128 uses three different round functions */
+#define F1(l, r, i) \
+       t = ROL(ctx->keys[i] + r, ctx->keys[i+16]); \
+       l ^= ((cast_sbox1[U8a(t)] ^ cast_sbox2[U8b(t)]) \
+        - cast_sbox3[U8c(t)]) + cast_sbox4[U8d(t)];
+#define F2(l, r, i) \
+       t = ROL(ctx->keys[i] ^ r, ctx->keys[i+16]); \
+       l ^= ((cast_sbox1[U8a(t)] - cast_sbox2[U8b(t)]) \
+        + cast_sbox3[U8c(t)]) ^ cast_sbox4[U8d(t)];
+#define F3(l, r, i) \
+       t = ROL(ctx->keys[i] - r, ctx->keys[i+16]); \
+       l ^= ((cast_sbox1[U8a(t)] + cast_sbox2[U8b(t)]) \
+        ^ cast_sbox3[U8c(t)]) - cast_sbox4[U8d(t)];
+
+
+/***** Encryption Function *****/
+
+void
+cast128_encrypt(const struct cast128_ctx *ctx,
+               unsigned length, uint8_t *dst,
+               const uint8_t *src)
+{
+  FOR_BLOCKS(length, dst, src, CAST128_BLOCK_SIZE)
+    {
+      uint32_t t, l, r;
+
+      /* Get inblock into l,r */
+      l = READ_UINT32(src);
+      r = READ_UINT32(src+4);
+
+      /* Do the work */
+      F1(l, r,  0);
+      F2(r, l,  1);
+      F3(l, r,  2);
+      F1(r, l,  3);
+      F2(l, r,  4);
+      F3(r, l,  5);
+      F1(l, r,  6);
+      F2(r, l,  7);
+      F3(l, r,  8);
+      F1(r, l,  9);
+      F2(l, r, 10);
+      F3(r, l, 11);
+      /* Only do full 16 rounds if key length > 80 bits */
+      if (ctx->rounds > 12) {
+       F1(l, r, 12);
+       F2(r, l, 13);
+       F3(l, r, 14);
+       F1(r, l, 15);
+      }
+      /* Put l,r into outblock */
+      WRITE_UINT32(dst, r);
+      WRITE_UINT32(dst + 4, l);
+      /* Wipe clean */
+      t = l = r = 0;
+    }
+}
+
+
+/***** Decryption Function *****/
+
+void
+cast128_decrypt(const struct cast128_ctx *ctx,
+               unsigned length, uint8_t *dst,
+               const uint8_t *src)
+{
+  FOR_BLOCKS(length, dst, src, CAST128_BLOCK_SIZE)
+    {
+      uint32_t t, l, r;
+
+      /* Get inblock into l,r */
+      r = READ_UINT32(src);
+      l = READ_UINT32(src+4);
+
+      /* Do the work */
+      /* Only do full 16 rounds if key length > 80 bits */
+      if (ctx->rounds > 12) {
+       F1(r, l, 15);
+       F3(l, r, 14);
+       F2(r, l, 13);
+       F1(l, r, 12);
+      }
+      F3(r, l, 11);
+      F2(l, r, 10);
+      F1(r, l,  9);
+      F3(l, r,  8);
+      F2(r, l,  7);
+      F1(l, r,  6);
+      F3(r, l,  5);
+      F2(l, r,  4);
+      F1(r, l,  3);
+      F3(l, r,  2);
+      F2(r, l,  1);
+      F1(l, r,  0);
+
+      /* Put l,r into outblock */
+      WRITE_UINT32(dst, l);
+      WRITE_UINT32(dst + 4, r);
+
+      /* Wipe clean */
+      t = l = r = 0;
+    }
+}
+
+/***** Key Schedule *****/
+
+void
+cast128_set_key(struct cast128_ctx *ctx,
+               unsigned keybytes, const uint8_t *rawkey)
+{
+  uint32_t t[4], z[4], x[4];
+  unsigned i;
+
+  /* Set number of rounds to 12 or 16, depending on key length */
+  ctx->rounds = (keybytes <= CAST_SMALL_KEY)
+    ? CAST_SMALL_ROUNDS : CAST_FULL_ROUNDS;
+
+  /* Copy key to workspace x */
+  for (i = 0; i < 4; i++) {
+    x[i] = 0;
+    if ((i*4+0) < keybytes) x[i] = (uint32_t)rawkey[i*4+0] << 24;
+    if ((i*4+1) < keybytes) x[i] |= (uint32_t)rawkey[i*4+1] << 16;
+    if ((i*4+2) < keybytes) x[i] |= (uint32_t)rawkey[i*4+2] << 8;
+    if ((i*4+3) < keybytes) x[i] |= (uint32_t)rawkey[i*4+3];
+  }
+  /* FIXME: For the shorter key sizes, the last 4 subkeys are not
+     used, and need not be generatedd, nor stored. */
+  /* Generate 32 subkeys, four at a time */
+  for (i = 0; i < 32; i+=4) {
+    switch (i & 4) {
+    case 0:
+      t[0] = z[0] = x[0] ^ cast_sbox5[U8b(x[3])]
+       ^ cast_sbox6[U8d(x[3])] ^ cast_sbox7[U8a(x[3])]
+       ^ cast_sbox8[U8c(x[3])] ^ cast_sbox7[U8a(x[2])];
+      t[1] = z[1] = x[2] ^ cast_sbox5[U8a(z[0])]
+       ^ cast_sbox6[U8c(z[0])] ^ cast_sbox7[U8b(z[0])]
+       ^ cast_sbox8[U8d(z[0])] ^ cast_sbox8[U8c(x[2])];
+      t[2] = z[2] = x[3] ^ cast_sbox5[U8d(z[1])]
+       ^ cast_sbox6[U8c(z[1])] ^ cast_sbox7[U8b(z[1])]
+       ^ cast_sbox8[U8a(z[1])] ^ cast_sbox5[U8b(x[2])];
+      t[3] = z[3] = x[1] ^ cast_sbox5[U8c(z[2])] ^
+       cast_sbox6[U8b(z[2])] ^ cast_sbox7[U8d(z[2])]
+       ^ cast_sbox8[U8a(z[2])] ^ cast_sbox6[U8d(x[2])];
+      break;
+    case 4:
+      t[0] = x[0] = z[2] ^ cast_sbox5[U8b(z[1])]
+       ^ cast_sbox6[U8d(z[1])] ^ cast_sbox7[U8a(z[1])]
+       ^ cast_sbox8[U8c(z[1])] ^ cast_sbox7[U8a(z[0])];
+      t[1] = x[1] = z[0] ^ cast_sbox5[U8a(x[0])]
+       ^ cast_sbox6[U8c(x[0])] ^ cast_sbox7[U8b(x[0])]
+       ^ cast_sbox8[U8d(x[0])] ^ cast_sbox8[U8c(z[0])];
+      t[2] = x[2] = z[1] ^ cast_sbox5[U8d(x[1])]
+       ^ cast_sbox6[U8c(x[1])] ^ cast_sbox7[U8b(x[1])]
+       ^ cast_sbox8[U8a(x[1])] ^ cast_sbox5[U8b(z[0])];
+      t[3] = x[3] = z[3] ^ cast_sbox5[U8c(x[2])]
+       ^ cast_sbox6[U8b(x[2])] ^ cast_sbox7[U8d(x[2])]
+       ^ cast_sbox8[U8a(x[2])] ^ cast_sbox6[U8d(z[0])];
+      break;
+    }
+    switch (i & 12) {
+    case 0:
+    case 12:
+      ctx->keys[i+0] = cast_sbox5[U8a(t[2])] ^ cast_sbox6[U8b(t[2])]
+       ^ cast_sbox7[U8d(t[1])] ^ cast_sbox8[U8c(t[1])];
+      ctx->keys[i+1] = cast_sbox5[U8c(t[2])] ^ cast_sbox6[U8d(t[2])]
+       ^ cast_sbox7[U8b(t[1])] ^ cast_sbox8[U8a(t[1])];
+      ctx->keys[i+2] = cast_sbox5[U8a(t[3])] ^ cast_sbox6[U8b(t[3])]
+       ^ cast_sbox7[U8d(t[0])] ^ cast_sbox8[U8c(t[0])];
+      ctx->keys[i+3] = cast_sbox5[U8c(t[3])] ^ cast_sbox6[U8d(t[3])]
+       ^ cast_sbox7[U8b(t[0])] ^ cast_sbox8[U8a(t[0])];
+      break;
+    case 4:
+    case 8:
+      ctx->keys[i+0] = cast_sbox5[U8d(t[0])] ^ cast_sbox6[U8c(t[0])]
+       ^ cast_sbox7[U8a(t[3])] ^ cast_sbox8[U8b(t[3])];
+      ctx->keys[i+1] = cast_sbox5[U8b(t[0])] ^ cast_sbox6[U8a(t[0])]
+       ^ cast_sbox7[U8c(t[3])] ^ cast_sbox8[U8d(t[3])];
+      ctx->keys[i+2] = cast_sbox5[U8d(t[1])] ^ cast_sbox6[U8c(t[1])]
+       ^ cast_sbox7[U8a(t[2])] ^ cast_sbox8[U8b(t[2])];
+      ctx->keys[i+3] = cast_sbox5[U8b(t[1])] ^ cast_sbox6[U8a(t[1])]
+       ^ cast_sbox7[U8c(t[2])] ^ cast_sbox8[U8d(t[2])];
+      break;
+    }
+    switch (i & 12) {
+    case 0:
+      ctx->keys[i+0] ^= cast_sbox5[U8c(z[0])];
+      ctx->keys[i+1] ^= cast_sbox6[U8c(z[1])];
+      ctx->keys[i+2] ^= cast_sbox7[U8b(z[2])];
+      ctx->keys[i+3] ^= cast_sbox8[U8a(z[3])];
+      break;
+    case 4:
+      ctx->keys[i+0] ^= cast_sbox5[U8a(x[2])];
+      ctx->keys[i+1] ^= cast_sbox6[U8b(x[3])];
+      ctx->keys[i+2] ^= cast_sbox7[U8d(x[0])];
+      ctx->keys[i+3] ^= cast_sbox8[U8d(x[1])];
+      break;
+    case 8:
+      ctx->keys[i+0] ^= cast_sbox5[U8b(z[2])];
+      ctx->keys[i+1] ^= cast_sbox6[U8a(z[3])];
+      ctx->keys[i+2] ^= cast_sbox7[U8c(z[0])];
+      ctx->keys[i+3] ^= cast_sbox8[U8c(z[1])];
+      break;
+    case 12:
+      ctx->keys[i+0] ^= cast_sbox5[U8d(x[0])];
+      ctx->keys[i+1] ^= cast_sbox6[U8d(x[1])];
+      ctx->keys[i+2] ^= cast_sbox7[U8a(x[2])];
+      ctx->keys[i+3] ^= cast_sbox8[U8b(x[3])];
+      break;
+    }
+    if (i >= 16) {
+      ctx->keys[i+0] &= 31;
+      ctx->keys[i+1] &= 31;
+      ctx->keys[i+2] &= 31;
+      ctx->keys[i+3] &= 31;
+    }
+  }
+  /* Wipe clean */
+  for (i = 0; i < 4; i++) {
+    t[i] = x[i] = z[i] = 0;
+  }
+}
diff --git a/cast128.h b/cast128.h
new file mode 100644 (file)
index 0000000..a1af0b0
--- /dev/null
+++ b/cast128.h
@@ -0,0 +1,77 @@
+/* cast128.h
+ *
+ * The CAST-128 block cipher.
+ */
+
+/*     CAST-128 in C
+ *     Written by Steve Reid <sreid@sea-to-sky.net>
+ *     100% Public Domain - no warranty
+ *     Released 1997.10.11
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_CAST128_H_INCLUDED
+#define NETTLE_CAST128_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define cast128_set_key nettle_cast128_set_key
+#define cast128_encrypt nettle_cast128_encrypt
+#define cast128_decrypt nettle_cast128_decrypt
+
+#define CAST128_BLOCK_SIZE 8
+
+/* Variable key size between 40 and 128. */
+#define CAST128_MIN_KEY_SIZE 5
+#define CAST128_MAX_KEY_SIZE 16
+
+#define CAST128_KEY_SIZE 16
+
+struct cast128_ctx
+{
+  uint32_t keys[32];  /* Key, after expansion */
+  unsigned rounds;    /* Number of rounds to use, 12 or 16 */
+};
+
+void
+cast128_set_key(struct cast128_ctx *ctx,
+               unsigned length, const uint8_t *key);
+
+void
+cast128_encrypt(const struct cast128_ctx *ctx,
+               unsigned length, uint8_t *dst,
+               const uint8_t *src);
+void
+cast128_decrypt(const struct cast128_ctx *ctx,
+               unsigned length, uint8_t *dst,
+               const uint8_t *src);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_CAST128_H_INCLUDED */
diff --git a/cast128_sboxes.h b/cast128_sboxes.h
new file mode 100644 (file)
index 0000000..607564b
--- /dev/null
@@ -0,0 +1,545 @@
+/*
+ * $Id: cast128_sboxes.h,v 1.1 2007-04-05 14:20:35 nisse Exp $
+ *
+ *     CAST-128 in C
+ *     Written by Steve Reid <sreid@sea-to-sky.net>
+ *     100% Public Domain - no warranty
+ *     Released 1997.10.11
+ */
+
+static const uint32_t cast_sbox1[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,
+  0xA1C9E0D6, 0x346C4819, 0x61B76D87, 0x22540F2F,
+  0x2ABE32E1, 0xAA54166B, 0x22568E3A, 0xA2D341D0,
+  0x66DB40C8, 0xA784392F, 0x004DFF2F, 0x2DB9D2DE,
+  0x97943FAC, 0x4A97C1D8, 0x527644B7, 0xB5F437A7,
+  0xB82CBAEF, 0xD751D159, 0x6FF7F0ED, 0x5A097A1F,
+  0x827B68D0, 0x90ECF52E, 0x22B0C054, 0xBC8E5935,
+  0x4B6D2F7F, 0x50BB64A2, 0xD2664910, 0xBEE5812D,
+  0xB7332290, 0xE93B159F, 0xB48EE411, 0x4BFF345D,
+  0xFD45C240, 0xAD31973F, 0xC4F6D02E, 0x55FC8165,
+  0xD5B1CAAD, 0xA1AC2DAE, 0xA2D4B76D, 0xC19B0C50,
+  0x882240F2, 0x0C6E4F38, 0xA4E4BFD7, 0x4F5BA272,
+  0x564C1D2F, 0xC59C5319, 0xB949E354, 0xB04669FE,
+  0xB1B6AB8A, 0xC71358DD, 0x6385C545, 0x110F935D,
+  0x57538AD5, 0x6A390493, 0xE63D37E0, 0x2A54F6B3,
+  0x3A787D5F, 0x6276A0B5, 0x19A6FCDF, 0x7A42206A,
+  0x29F9D4D5, 0xF61B1891, 0xBB72275E, 0xAA508167,
+  0x38901091, 0xC6B505EB, 0x84C7CB8C, 0x2AD75A0F,
+  0x874A1427, 0xA2D1936B, 0x2AD286AF, 0xAA56D291,
+  0xD7894360, 0x425C750D, 0x93B39E26, 0x187184C9,
+  0x6C00B32D, 0x73E2BB14, 0xA0BEBC3C, 0x54623779,
+  0x64459EAB, 0x3F328B82, 0x7718CF82, 0x59A2CEA6,
+  0x04EE002E, 0x89FE78E6, 0x3FAB0950, 0x325FF6C2,
+  0x81383F05, 0x6963C5C8, 0x76CB5AD6, 0xD49974C9,
+  0xCA180DCF, 0x380782D5, 0xC7FA5CF6, 0x8AC31511,
+  0x35E79E13, 0x47DA91D0, 0xF40F9086, 0xA7E2419E,
+  0x31366241, 0x051EF495, 0xAA573B04, 0x4A805D8D,
+  0x548300D0, 0x00322A3C, 0xBF64CDDF, 0xBA57A68E,
+  0x75C6372B, 0x50AFD341, 0xA7C13275, 0x915A0BF5,
+  0x6B54BFAB, 0x2B0B1426, 0xAB4CC9D7, 0x449CCD82,
+  0xF7FBF265, 0xAB85C5F3, 0x1B55DB94, 0xAAD4E324,
+  0xCFA4BD3F, 0x2DEAA3E2, 0x9E204D02, 0xC8BD25AC,
+  0xEADF55B3, 0xD5BD9E98, 0xE31231B2, 0x2AD5AD6C,
+  0x954329DE, 0xADBE4528, 0xD8710F69, 0xAA51C90F,
+  0xAA786BF6, 0x22513F1E, 0xAA51A79B, 0x2AD344CC,
+  0x7B5A41F0, 0xD37CFBAD, 0x1B069505, 0x41ECE491,
+  0xB4C332E6, 0x032268D4, 0xC9600ACC, 0xCE387E6D,
+  0xBF6BB16C, 0x6A70FB78, 0x0D03D9C9, 0xD4DF39DE,
+  0xE01063DA, 0x4736F464, 0x5AD328D8, 0xB347CC96,
+  0x75BB0FC3, 0x98511BFB, 0x4FFBCC35, 0xB58BCF6A,
+  0xE11F0ABC, 0xBFC5FE4A, 0xA70AEC10, 0xAC39570A,
+  0x3F04442F, 0x6188B153, 0xE0397A2E, 0x5727CB79,
+  0x9CEB418F, 0x1CACD68D, 0x2AD37C96, 0x0175CB9D,
+  0xC69DFF09, 0xC75B65F0, 0xD9DB40D8, 0xEC0E7779,
+  0x4744EAD4, 0xB11C3274, 0xDD24CB9E, 0x7E1C54BD,
+  0xF01144F9, 0xD2240EB1, 0x9675B3FD, 0xA3AC3755,
+  0xD47C27AF, 0x51C85F4D, 0x56907596, 0xA5BB15E6,
+  0x580304F0, 0xCA042CF1, 0x011A37EA, 0x8DBFAADB,
+  0x35BA3E4A, 0x3526FFA0, 0xC37B4D09, 0xBC306ED9,
+  0x98A52666, 0x5648F725, 0xFF5E569D, 0x0CED63D0,
+  0x7C63B2CF, 0x700B45E1, 0xD5EA50F1, 0x85A92872,
+  0xAF1FBDA7, 0xD4234870, 0xA7870BF3, 0x2D3B4D79,
+  0x42E04198, 0x0CD0EDE7, 0x26470DB8, 0xF881814C,
+  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 uint32_t cast_sbox2[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,
+  0xD1DA4181, 0x3B092AB1, 0xF997F1C1, 0xA5E6CF7B,
+  0x01420DDB, 0xE4E7EF5B, 0x25A1FF41, 0xE180F806,
+  0x1FC41080, 0x179BEE7A, 0xD37AC6A9, 0xFE5830A4,
+  0x98DE8B7F, 0x77E83F4E, 0x79929269, 0x24FA9F7B,
+  0xE113C85B, 0xACC40083, 0xD7503525, 0xF7EA615F,
+  0x62143154, 0x0D554B63, 0x5D681121, 0xC866C359,
+  0x3D63CF73, 0xCEE234C0, 0xD4D87E87, 0x5C672B21,
+  0x071F6181, 0x39F7627F, 0x361E3084, 0xE4EB573B,
+  0x602F64A4, 0xD63ACD9C, 0x1BBC4635, 0x9E81032D,
+  0x2701F50C, 0x99847AB4, 0xA0E3DF79, 0xBA6CF38C,
+  0x10843094, 0x2537A95E, 0xF46F6FFE, 0xA1FF3B1F,
+  0x208CFB6A, 0x8F458C74, 0xD9E0A227, 0x4EC73A34,
+  0xFC884F69, 0x3E4DE8DF, 0xEF0E0088, 0x3559648D,
+  0x8A45388C, 0x1D804366, 0x721D9BFD, 0xA58684BB,
+  0xE8256333, 0x844E8212, 0x128D8098, 0xFED33FB4,
+  0xCE280AE1, 0x27E19BA5, 0xD5A6C252, 0xE49754BD,
+  0xC5D655DD, 0xEB667064, 0x77840B4D, 0xA1B6A801,
+  0x84DB26A9, 0xE0B56714, 0x21F043B7, 0xE5D05860,
+  0x54F03084, 0x066FF472, 0xA31AA153, 0xDADC4755,
+  0xB5625DBF, 0x68561BE6, 0x83CA6B94, 0x2D6ED23B,
+  0xECCF01DB, 0xA6D3D0BA, 0xB6803D5C, 0xAF77A709,
+  0x33B4A34C, 0x397BC8D6, 0x5EE22B95, 0x5F0E5304,
+  0x81ED6F61, 0x20E74364, 0xB45E1378, 0xDE18639B,
+  0x881CA122, 0xB96726D1, 0x8049A7E8, 0x22B7DA7B,
+  0x5E552D25, 0x5272D237, 0x79D2951C, 0xC60D894C,
+  0x488CB402, 0x1BA4FE5B, 0xA4B09F6B, 0x1CA815CF,
+  0xA20C3005, 0x8871DF63, 0xB9DE2FCB, 0x0CC6C9E9,
+  0x0BEEFF53, 0xE3214517, 0xB4542835, 0x9F63293C,
+  0xEE41E729, 0x6E1D2D7C, 0x50045286, 0x1E6685F3,
+  0xF33401C6, 0x30A22C95, 0x31A70850, 0x60930F13,
+  0x73F98417, 0xA1269859, 0xEC645C44, 0x52C877A9,
+  0xCDFF33A6, 0xA02B1741, 0x7CBAD9A2, 0x2180036F,
+  0x50D99C08, 0xCB3F4861, 0xC26BD765, 0x64A3F6AB,
+  0x80342676, 0x25A75E7B, 0xE4E6D1FC, 0x20C710E6,
+  0xCDF0B680, 0x17844D3B, 0x31EEF84D, 0x7E0824E4,
+  0x2CCB49EB, 0x846A3BAE, 0x8FF77888, 0xEE5D60F6,
+  0x7AF75673, 0x2FDD5CDB, 0xA11631C1, 0x30F66F43,
+  0xB3FAEC54, 0x157FD7FA, 0xEF8579CC, 0xD152DE58,
+  0xDB2FFD5E, 0x8F32CE19, 0x306AF97A, 0x02F03EF8,
+  0x99319AD5, 0xC242FA0F, 0xA7E3EBB0, 0xC68E4906,
+  0xB8DA230C, 0x80823028, 0xDCDEF3C8, 0xD35FB171,
+  0x088A1BC8, 0xBEC0C560, 0x61A3C9E8, 0xBCA8F54D,
+  0xC72FEFFA, 0x22822E99, 0x82C570B4, 0xD8D94E89,
+  0x8B1C34BC, 0x301E16E6, 0x273BE979, 0xB0FFEAA6,
+  0x61D9B8C6, 0x00B24869, 0xB7FFCE3F, 0x08DC283B,
+  0x43DAF65A, 0xF7E19798, 0x7619B72F, 0x8F1C9BA4,
+  0xDC8637A0, 0x16A7D3B1, 0x9FC393B7, 0xA7136EEB,
+  0xC6BCC63E, 0x1A513742, 0xEF6828BC, 0x520365D6,
+  0x2D6A77AB, 0x3527ED4B, 0x821FD216, 0x095C6E2E,
+  0xDB92F2FB, 0x5EEA29CB, 0x145892F5, 0x91584F7F,
+  0x5483697B, 0x2667A8CC, 0x85196048, 0x8C4BACEA,
+  0x833860D4, 0x0D23E0F9, 0x6C387E8A, 0x0AE6D249,
+  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 uint32_t cast_sbox3[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,
+  0x553FB2C0, 0x489AE22B, 0xD4EF9794, 0x125E3FBC,
+  0x21FFFCEE, 0x825B1BFD, 0x9255C5ED, 0x1257A240,
+  0x4E1A8302, 0xBAE07FFF, 0x528246E7, 0x8E57140E,
+  0x3373F7BF, 0x8C9F8188, 0xA6FC4EE8, 0xC982B5A5,
+  0xA8C01DB7, 0x579FC264, 0x67094F31, 0xF2BD3F5F,
+  0x40FFF7C1, 0x1FB78DFC, 0x8E6BD2C1, 0x437BE59B,
+  0x99B03DBF, 0xB5DBC64B, 0x638DC0E6, 0x55819D99,
+  0xA197C81C, 0x4A012D6E, 0xC5884A28, 0xCCC36F71,
+  0xB843C213, 0x6C0743F1, 0x8309893C, 0x0FEDDD5F,
+  0x2F7FE850, 0xD7C07F7E, 0x02507FBF, 0x5AFB9A04,
+  0xA747D2D0, 0x1651192E, 0xAF70BF3E, 0x58C31380,
+  0x5F98302E, 0x727CC3C4, 0x0A0FB402, 0x0F7FEF82,
+  0x8C96FDAD, 0x5D2C2AAE, 0x8EE99A49, 0x50DA88B8,
+  0x8427F4A0, 0x1EAC5790, 0x796FB449, 0x8252DC15,
+  0xEFBD7D9B, 0xA672597D, 0xADA840D8, 0x45F54504,
+  0xFA5D7403, 0xE83EC305, 0x4F91751A, 0x925669C2,
+  0x23EFE941, 0xA903F12E, 0x60270DF2, 0x0276E4B6,
+  0x94FD6574, 0x927985B2, 0x8276DBCB, 0x02778176,
+  0xF8AF918D, 0x4E48F79E, 0x8F616DDF, 0xE29D840E,
+  0x842F7D83, 0x340CE5C8, 0x96BBB682, 0x93B4B148,
+  0xEF303CAB, 0x984FAF28, 0x779FAF9B, 0x92DC560D,
+  0x224D1E20, 0x8437AA88, 0x7D29DC96, 0x2756D3DC,
+  0x8B907CEE, 0xB51FD240, 0xE7C07CE3, 0xE566B4A1,
+  0xC3E9615E, 0x3CF8209D, 0x6094D1E3, 0xCD9CA341,
+  0x5C76460E, 0x00EA983B, 0xD4D67881, 0xFD47572C,
+  0xF76CEDD9, 0xBDA8229C, 0x127DADAA, 0x438A074E,
+  0x1F97C090, 0x081BDB8A, 0x93A07EBE, 0xB938CA15,
+  0x97B03CFF, 0x3DC2C0F8, 0x8D1AB2EC, 0x64380E51,
+  0x68CC7BFB, 0xD90F2788, 0x12490181, 0x5DE5FFD4,
+  0xDD7EF86A, 0x76A2E214, 0xB9A40368, 0x925D958F,
+  0x4B39FFFA, 0xBA39AEE9, 0xA4FFD30B, 0xFAF7933B,
+  0x6D498623, 0x193CBCFA, 0x27627545, 0x825CF47A,
+  0x61BD8BA0, 0xD11E42D1, 0xCEAD04F4, 0x127EA392,
+  0x10428DB7, 0x8272A972, 0x9270C4A8, 0x127DE50B,
+  0x285BA1C8, 0x3C62F44F, 0x35C0EAA5, 0xE805D231,
+  0x428929FB, 0xB4FCDF82, 0x4FB66A53, 0x0E7DC15B,
+  0x1F081FAB, 0x108618AE, 0xFCFD086D, 0xF9FF2889,
+  0x694BCC11, 0x236A5CAE, 0x12DECA4D, 0x2C3F8CC5,
+  0xD2D02DFE, 0xF8EF5896, 0xE4CF52DA, 0x95155B67,
+  0x494A488C, 0xB9B6A80C, 0x5C8F82BC, 0x89D36B45,
+  0x3A609437, 0xEC00C9A9, 0x44715253, 0x0A874B49,
+  0xD773BC40, 0x7C34671C, 0x02717EF6, 0x4FEB5536,
+  0xA2D02FFF, 0xD2BF60C4, 0xD43F03C0, 0x50B4EF6D,
+  0x07478CD1, 0x006E1888, 0xA2E53F55, 0xB9E6D4BC,
+  0xA2048016, 0x97573833, 0xD7207D67, 0xDE0F8F3D,
+  0x72F87B33, 0xABCC4F33, 0x7688C55D, 0x7B00A6B0,
+  0x947B0001, 0x570075D2, 0xF9BB88F8, 0x8942019E,
+  0x4264A5FF, 0x856302E0, 0x72DBD92B, 0xEE971B69,
+  0x6EA22FDE, 0x5F08AE2B, 0xAF7A616D, 0xE5C98767,
+  0xCF1FEBD2, 0x61EFC8C2, 0xF1AC2571, 0xCC8239C2,
+  0x67214CB8, 0xB1E583D1, 0xB7DC3E62, 0x7F10BDCE,
+  0xF90A5C38, 0x0FF0443D, 0x606E6DC6, 0x60543A49,
+  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 uint32_t cast_sbox4[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,
+  0xEE4D111A, 0x0FCA5167, 0x71FF904C, 0x2D195FFE,
+  0x1A05645F, 0x0C13FEFE, 0x081B08CA, 0x05170121,
+  0x80530100, 0xE83E5EFE, 0xAC9AF4F8, 0x7FE72701,
+  0xD2B8EE5F, 0x06DF4261, 0xBB9E9B8A, 0x7293EA25,
+  0xCE84FFDF, 0xF5718801, 0x3DD64B04, 0xA26F263B,
+  0x7ED48400, 0x547EEBE6, 0x446D4CA0, 0x6CF3D6F5,
+  0x2649ABDF, 0xAEA0C7F5, 0x36338CC1, 0x503F7E93,
+  0xD3772061, 0x11B638E1, 0x72500E03, 0xF80EB2BB,
+  0xABE0502E, 0xEC8D77DE, 0x57971E81, 0xE14F6746,
+  0xC9335400, 0x6920318F, 0x081DBB99, 0xFFC304A5,
+  0x4D351805, 0x7F3D5CE3, 0xA6C866C6, 0x5D5BCCA9,
+  0xDAEC6FEA, 0x9F926F91, 0x9F46222F, 0x3991467D,
+  0xA5BF6D8E, 0x1143C44F, 0x43958302, 0xD0214EEB,
+  0x022083B8, 0x3FB6180C, 0x18F8931E, 0x281658E6,
+  0x26486E3E, 0x8BD78A70, 0x7477E4C1, 0xB506E07C,
+  0xF32D0A25, 0x79098B02, 0xE4EABB81, 0x28123B23,
+  0x69DEAD38, 0x1574CA16, 0xDF871B62, 0x211C40B7,
+  0xA51A9EF9, 0x0014377B, 0x041E8AC8, 0x09114003,
+  0xBD59E4D2, 0xE3D156D5, 0x4FE876D5, 0x2F91A340,
+  0x557BE8DE, 0x00EAE4A7, 0x0CE5C2EC, 0x4DB4BBA6,
+  0xE756BDFF, 0xDD3369AC, 0xEC17B035, 0x06572327,
+  0x99AFC8B0, 0x56C8C391, 0x6B65811C, 0x5E146119,
+  0x6E85CB75, 0xBE07C002, 0xC2325577, 0x893FF4EC,
+  0x5BBFC92D, 0xD0EC3B25, 0xB7801AB7, 0x8D6D3B24,
+  0x20C763EF, 0xC366A5FC, 0x9C382880, 0x0ACE3205,
+  0xAAC9548A, 0xECA1D7C7, 0x041AFA32, 0x1D16625A,
+  0x6701902C, 0x9B757A54, 0x31D477F7, 0x9126B031,
+  0x36CC6FDB, 0xC70B8B46, 0xD9E66A48, 0x56E55A79,
+  0x026A4CEB, 0x52437EFF, 0x2F8F76B4, 0x0DF980A5,
+  0x8674CDE3, 0xEDDA04EB, 0x17A9BE04, 0x2C18F4DF,
+  0xB7747F9D, 0xAB2AF7B4, 0xEFC34D20, 0x2E096B7C,
+  0x1741A254, 0xE5B6A035, 0x213D42F6, 0x2C1C7C26,
+  0x61C2F50F, 0x6552DAF9, 0xD2C231F8, 0x25130F69,
+  0xD8167FA2, 0x0418F2C8, 0x001A96A6, 0x0D1526AB,
+  0x63315C21, 0x5E0A72EC, 0x49BAFEFD, 0x187908D9,
+  0x8D0DBD86, 0x311170A7, 0x3E9B640C, 0xCC3E10D7,
+  0xD5CAD3B6, 0x0CAEC388, 0xF73001E1, 0x6C728AFF,
+  0x71EAE2A1, 0x1F9AF36E, 0xCFCBD12F, 0xC1DE8417,
+  0xAC07BE6B, 0xCB44A1D8, 0x8B9B0F56, 0x013988C3,
+  0xB1C52FCA, 0xB4BE31CD, 0xD8782806, 0x12A3A4E2,
+  0x6F7DE532, 0x58FD7EB6, 0xD01EE900, 0x24ADFFC2,
+  0xF4990FC5, 0x9711AAC5, 0x001D7B95, 0x82E5E7D2,
+  0x109873F6, 0x00613096, 0xC32D9521, 0xADA121FF,
+  0x29908415, 0x7FBB977F, 0xAF9EB3DB, 0x29C9ED2A,
+  0x5CE2A465, 0xA730F32C, 0xD0AA3FE8, 0x8A5CC091,
+  0xD49E2CE7, 0x0CE454A9, 0xD60ACD86, 0x015F1919,
+  0x77079103, 0xDEA03AF6, 0x78A8565E, 0xDEE356DF,
+  0x21F05CBE, 0x8B75E387, 0xB3C50651, 0xB8A5C3EF,
+  0xD8EEB6D2, 0xE523BE77, 0xC2154529, 0x2F69EFDF,
+  0xAFE67AFB, 0xF470C4B2, 0xF3E0EB5B, 0xD6CC9876,
+  0x39E4460C, 0x1FDA8538, 0x1987832F, 0xCA007367,
+  0xA99144F8, 0x296B299E, 0x492FC295, 0x9266BEAB,
+  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 uint32_t cast_sbox5[256] = {
+  0x7EC90C04, 0x2C6E74B9, 0x9B0E66DF, 0xA6337911,
+  0xB86A7FFF, 0x1DD358F5, 0x44DD9D44, 0x1731167F,
+  0x08FBF1FA, 0xE7F511CC, 0xD2051B00, 0x735ABA00,
+  0x2AB722D8, 0x386381CB, 0xACF6243A, 0x69BEFD7A,
+  0xE6A2E77F, 0xF0C720CD, 0xC4494816, 0xCCF5C180,
+  0x38851640, 0x15B0A848, 0xE68B18CB, 0x4CAADEFF,
+  0x5F480A01, 0x0412B2AA, 0x259814FC, 0x41D0EFE2,
+  0x4E40B48D, 0x248EB6FB, 0x8DBA1CFE, 0x41A99B02,
+  0x1A550A04, 0xBA8F65CB, 0x7251F4E7, 0x95A51725,
+  0xC106ECD7, 0x97A5980A, 0xC539B9AA, 0x4D79FE6A,
+  0xF2F3F763, 0x68AF8040, 0xED0C9E56, 0x11B4958B,
+  0xE1EB5A88, 0x8709E6B0, 0xD7E07156, 0x4E29FEA7,
+  0x6366E52D, 0x02D1C000, 0xC4AC8E05, 0x9377F571,
+  0x0C05372A, 0x578535F2, 0x2261BE02, 0xD642A0C9,
+  0xDF13A280, 0x74B55BD2, 0x682199C0, 0xD421E5EC,
+  0x53FB3CE8, 0xC8ADEDB3, 0x28A87FC9, 0x3D959981,
+  0x5C1FF900, 0xFE38D399, 0x0C4EFF0B, 0x062407EA,
+  0xAA2F4FB1, 0x4FB96976, 0x90C79505, 0xB0A8A774,
+  0xEF55A1FF, 0xE59CA2C2, 0xA6B62D27, 0xE66A4263,
+  0xDF65001F, 0x0EC50966, 0xDFDD55BC, 0x29DE0655,
+  0x911E739A, 0x17AF8975, 0x32C7911C, 0x89F89468,
+  0x0D01E980, 0x524755F4, 0x03B63CC9, 0x0CC844B2,
+  0xBCF3F0AA, 0x87AC36E9, 0xE53A7426, 0x01B3D82B,
+  0x1A9E7449, 0x64EE2D7E, 0xCDDBB1DA, 0x01C94910,
+  0xB868BF80, 0x0D26F3FD, 0x9342EDE7, 0x04A5C284,
+  0x636737B6, 0x50F5B616, 0xF24766E3, 0x8ECA36C1,
+  0x136E05DB, 0xFEF18391, 0xFB887A37, 0xD6E7F7D4,
+  0xC7FB7DC9, 0x3063FCDF, 0xB6F589DE, 0xEC2941DA,
+  0x26E46695, 0xB7566419, 0xF654EFC5, 0xD08D58B7,
+  0x48925401, 0xC1BACB7F, 0xE5FF550F, 0xB6083049,
+  0x5BB5D0E8, 0x87D72E5A, 0xAB6A6EE1, 0x223A66CE,
+  0xC62BF3CD, 0x9E0885F9, 0x68CB3E47, 0x086C010F,
+  0xA21DE820, 0xD18B69DE, 0xF3F65777, 0xFA02C3F6,
+  0x407EDAC3, 0xCBB3D550, 0x1793084D, 0xB0D70EBA,
+  0x0AB378D5, 0xD951FB0C, 0xDED7DA56, 0x4124BBE4,
+  0x94CA0B56, 0x0F5755D1, 0xE0E1E56E, 0x6184B5BE,
+  0x580A249F, 0x94F74BC0, 0xE327888E, 0x9F7B5561,
+  0xC3DC0280, 0x05687715, 0x646C6BD7, 0x44904DB3,
+  0x66B4F0A3, 0xC0F1648A, 0x697ED5AF, 0x49E92FF6,
+  0x309E374F, 0x2CB6356A, 0x85808573, 0x4991F840,
+  0x76F0AE02, 0x083BE84D, 0x28421C9A, 0x44489406,
+  0x736E4CB8, 0xC1092910, 0x8BC95FC6, 0x7D869CF4,
+  0x134F616F, 0x2E77118D, 0xB31B2BE1, 0xAA90B472,
+  0x3CA5D717, 0x7D161BBA, 0x9CAD9010, 0xAF462BA2,
+  0x9FE459D2, 0x45D34559, 0xD9F2DA13, 0xDBC65487,
+  0xF3E4F94E, 0x176D486F, 0x097C13EA, 0x631DA5C7,
+  0x445F7382, 0x175683F4, 0xCDC66A97, 0x70BE0288,
+  0xB3CDCF72, 0x6E5DD2F3, 0x20936079, 0x459B80A5,
+  0xBE60E2DB, 0xA9C23101, 0xEBA5315C, 0x224E42F2,
+  0x1C5C1572, 0xF6721B2C, 0x1AD2FFF3, 0x8C25404E,
+  0x324ED72F, 0x4067B7FD, 0x0523138E, 0x5CA3BC78,
+  0xDC0FD66E, 0x75922283, 0x784D6B17, 0x58EBB16E,
+  0x44094F85, 0x3F481D87, 0xFCFEAE7B, 0x77B5FF76,
+  0x8C2302BF, 0xAAF47556, 0x5F46B02A, 0x2B092801,
+  0x3D38F5F7, 0x0CA81F36, 0x52AF4A8A, 0x66D5E7C0,
+  0xDF3B0874, 0x95055110, 0x1B5AD7A8, 0xF61ED5AD,
+  0x6CF6E479, 0x20758184, 0xD0CEFA65, 0x88F7BE58,
+  0x4A046826, 0x0FF6F8F3, 0xA09C7F70, 0x5346ABA0,
+  0x5CE96C28, 0xE176EDA3, 0x6BAC307F, 0x376829D2,
+  0x85360FA9, 0x17E3FE2A, 0x24B79767, 0xF5A96B20,
+  0xD6CD2595, 0x68FF1EBF, 0x7555442C, 0xF19F06BE,
+  0xF9E0659A, 0xEEB9491D, 0x34010718, 0xBB30CAB8,
+  0xE822FE15, 0x88570983, 0x750E6249, 0xDA627E55,
+  0x5E76FFA8, 0xB1534546, 0x6D47DE08, 0xEFE9E7D4
+};
+
+static const uint32_t cast_sbox6[256] = {
+  0xF6FA8F9D, 0x2CAC6CE1, 0x4CA34867, 0xE2337F7C,
+  0x95DB08E7, 0x016843B4, 0xECED5CBC, 0x325553AC,
+  0xBF9F0960, 0xDFA1E2ED, 0x83F0579D, 0x63ED86B9,
+  0x1AB6A6B8, 0xDE5EBE39, 0xF38FF732, 0x8989B138,
+  0x33F14961, 0xC01937BD, 0xF506C6DA, 0xE4625E7E,
+  0xA308EA99, 0x4E23E33C, 0x79CBD7CC, 0x48A14367,
+  0xA3149619, 0xFEC94BD5, 0xA114174A, 0xEAA01866,
+  0xA084DB2D, 0x09A8486F, 0xA888614A, 0x2900AF98,
+  0x01665991, 0xE1992863, 0xC8F30C60, 0x2E78EF3C,
+  0xD0D51932, 0xCF0FEC14, 0xF7CA07D2, 0xD0A82072,
+  0xFD41197E, 0x9305A6B0, 0xE86BE3DA, 0x74BED3CD,
+  0x372DA53C, 0x4C7F4448, 0xDAB5D440, 0x6DBA0EC3,
+  0x083919A7, 0x9FBAEED9, 0x49DBCFB0, 0x4E670C53,
+  0x5C3D9C01, 0x64BDB941, 0x2C0E636A, 0xBA7DD9CD,
+  0xEA6F7388, 0xE70BC762, 0x35F29ADB, 0x5C4CDD8D,
+  0xF0D48D8C, 0xB88153E2, 0x08A19866, 0x1AE2EAC8,
+  0x284CAF89, 0xAA928223, 0x9334BE53, 0x3B3A21BF,
+  0x16434BE3, 0x9AEA3906, 0xEFE8C36E, 0xF890CDD9,
+  0x80226DAE, 0xC340A4A3, 0xDF7E9C09, 0xA694A807,
+  0x5B7C5ECC, 0x221DB3A6, 0x9A69A02F, 0x68818A54,
+  0xCEB2296F, 0x53C0843A, 0xFE893655, 0x25BFE68A,
+  0xB4628ABC, 0xCF222EBF, 0x25AC6F48, 0xA9A99387,
+  0x53BDDB65, 0xE76FFBE7, 0xE967FD78, 0x0BA93563,
+  0x8E342BC1, 0xE8A11BE9, 0x4980740D, 0xC8087DFC,
+  0x8DE4BF99, 0xA11101A0, 0x7FD37975, 0xDA5A26C0,
+  0xE81F994F, 0x9528CD89, 0xFD339FED, 0xB87834BF,
+  0x5F04456D, 0x22258698, 0xC9C4C83B, 0x2DC156BE,
+  0x4F628DAA, 0x57F55EC5, 0xE2220ABE, 0xD2916EBF,
+  0x4EC75B95, 0x24F2C3C0, 0x42D15D99, 0xCD0D7FA0,
+  0x7B6E27FF, 0xA8DC8AF0, 0x7345C106, 0xF41E232F,
+  0x35162386, 0xE6EA8926, 0x3333B094, 0x157EC6F2,
+  0x372B74AF, 0x692573E4, 0xE9A9D848, 0xF3160289,
+  0x3A62EF1D, 0xA787E238, 0xF3A5F676, 0x74364853,
+  0x20951063, 0x4576698D, 0xB6FAD407, 0x592AF950,
+  0x36F73523, 0x4CFB6E87, 0x7DA4CEC0, 0x6C152DAA,
+  0xCB0396A8, 0xC50DFE5D, 0xFCD707AB, 0x0921C42F,
+  0x89DFF0BB, 0x5FE2BE78, 0x448F4F33, 0x754613C9,
+  0x2B05D08D, 0x48B9D585, 0xDC049441, 0xC8098F9B,
+  0x7DEDE786, 0xC39A3373, 0x42410005, 0x6A091751,
+  0x0EF3C8A6, 0x890072D6, 0x28207682, 0xA9A9F7BE,
+  0xBF32679D, 0xD45B5B75, 0xB353FD00, 0xCBB0E358,
+  0x830F220A, 0x1F8FB214, 0xD372CF08, 0xCC3C4A13,
+  0x8CF63166, 0x061C87BE, 0x88C98F88, 0x6062E397,
+  0x47CF8E7A, 0xB6C85283, 0x3CC2ACFB, 0x3FC06976,
+  0x4E8F0252, 0x64D8314D, 0xDA3870E3, 0x1E665459,
+  0xC10908F0, 0x513021A5, 0x6C5B68B7, 0x822F8AA0,
+  0x3007CD3E, 0x74719EEF, 0xDC872681, 0x073340D4,
+  0x7E432FD9, 0x0C5EC241, 0x8809286C, 0xF592D891,
+  0x08A930F6, 0x957EF305, 0xB7FBFFBD, 0xC266E96F,
+  0x6FE4AC98, 0xB173ECC0, 0xBC60B42A, 0x953498DA,
+  0xFBA1AE12, 0x2D4BD736, 0x0F25FAAB, 0xA4F3FCEB,
+  0xE2969123, 0x257F0C3D, 0x9348AF49, 0x361400BC,
+  0xE8816F4A, 0x3814F200, 0xA3F94043, 0x9C7A54C2,
+  0xBC704F57, 0xDA41E7F9, 0xC25AD33A, 0x54F4A084,
+  0xB17F5505, 0x59357CBE, 0xEDBD15C8, 0x7F97C5AB,
+  0xBA5AC7B5, 0xB6F6DEAF, 0x3A479C3A, 0x5302DA25,
+  0x653D7E6A, 0x54268D49, 0x51A477EA, 0x5017D55B,
+  0xD7D25D88, 0x44136C76, 0x0404A8C8, 0xB8E5A121,
+  0xB81A928A, 0x60ED5869, 0x97C55B96, 0xEAEC991B,
+  0x29935913, 0x01FDB7F1, 0x088E8DFA, 0x9AB6F6F5,
+  0x3B4CBF9F, 0x4A5DE3AB, 0xE6051D35, 0xA0E1D855,
+  0xD36B4CF1, 0xF544EDEB, 0xB0E93524, 0xBEBB8FBD,
+  0xA2D762CF, 0x49C92F54, 0x38B5F331, 0x7128A454,
+  0x48392905, 0xA65B1DB8, 0x851C97BD, 0xD675CF2F
+};
+
+static const uint32_t cast_sbox7[256] = {
+  0x85E04019, 0x332BF567, 0x662DBFFF, 0xCFC65693,
+  0x2A8D7F6F, 0xAB9BC912, 0xDE6008A1, 0x2028DA1F,
+  0x0227BCE7, 0x4D642916, 0x18FAC300, 0x50F18B82,
+  0x2CB2CB11, 0xB232E75C, 0x4B3695F2, 0xB28707DE,
+  0xA05FBCF6, 0xCD4181E9, 0xE150210C, 0xE24EF1BD,
+  0xB168C381, 0xFDE4E789, 0x5C79B0D8, 0x1E8BFD43,
+  0x4D495001, 0x38BE4341, 0x913CEE1D, 0x92A79C3F,
+  0x089766BE, 0xBAEEADF4, 0x1286BECF, 0xB6EACB19,
+  0x2660C200, 0x7565BDE4, 0x64241F7A, 0x8248DCA9,
+  0xC3B3AD66, 0x28136086, 0x0BD8DFA8, 0x356D1CF2,
+  0x107789BE, 0xB3B2E9CE, 0x0502AA8F, 0x0BC0351E,
+  0x166BF52A, 0xEB12FF82, 0xE3486911, 0xD34D7516,
+  0x4E7B3AFF, 0x5F43671B, 0x9CF6E037, 0x4981AC83,
+  0x334266CE, 0x8C9341B7, 0xD0D854C0, 0xCB3A6C88,
+  0x47BC2829, 0x4725BA37, 0xA66AD22B, 0x7AD61F1E,
+  0x0C5CBAFA, 0x4437F107, 0xB6E79962, 0x42D2D816,
+  0x0A961288, 0xE1A5C06E, 0x13749E67, 0x72FC081A,
+  0xB1D139F7, 0xF9583745, 0xCF19DF58, 0xBEC3F756,
+  0xC06EBA30, 0x07211B24, 0x45C28829, 0xC95E317F,
+  0xBC8EC511, 0x38BC46E9, 0xC6E6FA14, 0xBAE8584A,
+  0xAD4EBC46, 0x468F508B, 0x7829435F, 0xF124183B,
+  0x821DBA9F, 0xAFF60FF4, 0xEA2C4E6D, 0x16E39264,
+  0x92544A8B, 0x009B4FC3, 0xABA68CED, 0x9AC96F78,
+  0x06A5B79A, 0xB2856E6E, 0x1AEC3CA9, 0xBE838688,
+  0x0E0804E9, 0x55F1BE56, 0xE7E5363B, 0xB3A1F25D,
+  0xF7DEBB85, 0x61FE033C, 0x16746233, 0x3C034C28,
+  0xDA6D0C74, 0x79AAC56C, 0x3CE4E1AD, 0x51F0C802,
+  0x98F8F35A, 0x1626A49F, 0xEED82B29, 0x1D382FE3,
+  0x0C4FB99A, 0xBB325778, 0x3EC6D97B, 0x6E77A6A9,
+  0xCB658B5C, 0xD45230C7, 0x2BD1408B, 0x60C03EB7,
+  0xB9068D78, 0xA33754F4, 0xF430C87D, 0xC8A71302,
+  0xB96D8C32, 0xEBD4E7BE, 0xBE8B9D2D, 0x7979FB06,
+  0xE7225308, 0x8B75CF77, 0x11EF8DA4, 0xE083C858,
+  0x8D6B786F, 0x5A6317A6, 0xFA5CF7A0, 0x5DDA0033,
+  0xF28EBFB0, 0xF5B9C310, 0xA0EAC280, 0x08B9767A,
+  0xA3D9D2B0, 0x79D34217, 0x021A718D, 0x9AC6336A,
+  0x2711FD60, 0x438050E3, 0x069908A8, 0x3D7FEDC4,
+  0x826D2BEF, 0x4EEB8476, 0x488DCF25, 0x36C9D566,
+  0x28E74E41, 0xC2610ACA, 0x3D49A9CF, 0xBAE3B9DF,
+  0xB65F8DE6, 0x92AEAF64, 0x3AC7D5E6, 0x9EA80509,
+  0xF22B017D, 0xA4173F70, 0xDD1E16C3, 0x15E0D7F9,
+  0x50B1B887, 0x2B9F4FD5, 0x625ABA82, 0x6A017962,
+  0x2EC01B9C, 0x15488AA9, 0xD716E740, 0x40055A2C,
+  0x93D29A22, 0xE32DBF9A, 0x058745B9, 0x3453DC1E,
+  0xD699296E, 0x496CFF6F, 0x1C9F4986, 0xDFE2ED07,
+  0xB87242D1, 0x19DE7EAE, 0x053E561A, 0x15AD6F8C,
+  0x66626C1C, 0x7154C24C, 0xEA082B2A, 0x93EB2939,
+  0x17DCB0F0, 0x58D4F2AE, 0x9EA294FB, 0x52CF564C,
+  0x9883FE66, 0x2EC40581, 0x763953C3, 0x01D6692E,
+  0xD3A0C108, 0xA1E7160E, 0xE4F2DFA6, 0x693ED285,
+  0x74904698, 0x4C2B0EDD, 0x4F757656, 0x5D393378,
+  0xA132234F, 0x3D321C5D, 0xC3F5E194, 0x4B269301,
+  0xC79F022F, 0x3C997E7E, 0x5E4F9504, 0x3FFAFBBD,
+  0x76F7AD0E, 0x296693F4, 0x3D1FCE6F, 0xC61E45BE,
+  0xD3B5AB34, 0xF72BF9B7, 0x1B0434C0, 0x4E72B567,
+  0x5592A33D, 0xB5229301, 0xCFD2A87F, 0x60AEB767,
+  0x1814386B, 0x30BCC33D, 0x38A0C07D, 0xFD1606F2,
+  0xC363519B, 0x589DD390, 0x5479F8E6, 0x1CB8D647,
+  0x97FD61A9, 0xEA7759F4, 0x2D57539D, 0x569A58CF,
+  0xE84E63AD, 0x462E1B78, 0x6580F87E, 0xF3817914,
+  0x91DA55F4, 0x40A230F3, 0xD1988F35, 0xB6E318D2,
+  0x3FFA50BC, 0x3D40F021, 0xC3C0BDAE, 0x4958C24C,
+  0x518F36B2, 0x84B1D370, 0x0FEDCE83, 0x878DDADA,
+  0xF2A279C7, 0x94E01BE8, 0x90716F4B, 0x954B8AA3
+};
+
+static const uint32_t cast_sbox8[256] = {
+  0xE216300D, 0xBBDDFFFC, 0xA7EBDABD, 0x35648095,
+  0x7789F8B7, 0xE6C1121B, 0x0E241600, 0x052CE8B5,
+  0x11A9CFB0, 0xE5952F11, 0xECE7990A, 0x9386D174,
+  0x2A42931C, 0x76E38111, 0xB12DEF3A, 0x37DDDDFC,
+  0xDE9ADEB1, 0x0A0CC32C, 0xBE197029, 0x84A00940,
+  0xBB243A0F, 0xB4D137CF, 0xB44E79F0, 0x049EEDFD,
+  0x0B15A15D, 0x480D3168, 0x8BBBDE5A, 0x669DED42,
+  0xC7ECE831, 0x3F8F95E7, 0x72DF191B, 0x7580330D,
+  0x94074251, 0x5C7DCDFA, 0xABBE6D63, 0xAA402164,
+  0xB301D40A, 0x02E7D1CA, 0x53571DAE, 0x7A3182A2,
+  0x12A8DDEC, 0xFDAA335D, 0x176F43E8, 0x71FB46D4,
+  0x38129022, 0xCE949AD4, 0xB84769AD, 0x965BD862,
+  0x82F3D055, 0x66FB9767, 0x15B80B4E, 0x1D5B47A0,
+  0x4CFDE06F, 0xC28EC4B8, 0x57E8726E, 0x647A78FC,
+  0x99865D44, 0x608BD593, 0x6C200E03, 0x39DC5FF6,
+  0x5D0B00A3, 0xAE63AFF2, 0x7E8BD632, 0x70108C0C,
+  0xBBD35049, 0x2998DF04, 0x980CF42A, 0x9B6DF491,
+  0x9E7EDD53, 0x06918548, 0x58CB7E07, 0x3B74EF2E,
+  0x522FFFB1, 0xD24708CC, 0x1C7E27CD, 0xA4EB215B,
+  0x3CF1D2E2, 0x19B47A38, 0x424F7618, 0x35856039,
+  0x9D17DEE7, 0x27EB35E6, 0xC9AFF67B, 0x36BAF5B8,
+  0x09C467CD, 0xC18910B1, 0xE11DBF7B, 0x06CD1AF8,
+  0x7170C608, 0x2D5E3354, 0xD4DE495A, 0x64C6D006,
+  0xBCC0C62C, 0x3DD00DB3, 0x708F8F34, 0x77D51B42,
+  0x264F620F, 0x24B8D2BF, 0x15C1B79E, 0x46A52564,
+  0xF8D7E54E, 0x3E378160, 0x7895CDA5, 0x859C15A5,
+  0xE6459788, 0xC37BC75F, 0xDB07BA0C, 0x0676A3AB,
+  0x7F229B1E, 0x31842E7B, 0x24259FD7, 0xF8BEF472,
+  0x835FFCB8, 0x6DF4C1F2, 0x96F5B195, 0xFD0AF0FC,
+  0xB0FE134C, 0xE2506D3D, 0x4F9B12EA, 0xF215F225,
+  0xA223736F, 0x9FB4C428, 0x25D04979, 0x34C713F8,
+  0xC4618187, 0xEA7A6E98, 0x7CD16EFC, 0x1436876C,
+  0xF1544107, 0xBEDEEE14, 0x56E9AF27, 0xA04AA441,
+  0x3CF7C899, 0x92ECBAE6, 0xDD67016D, 0x151682EB,
+  0xA842EEDF, 0xFDBA60B4, 0xF1907B75, 0x20E3030F,
+  0x24D8C29E, 0xE139673B, 0xEFA63FB8, 0x71873054,
+  0xB6F2CF3B, 0x9F326442, 0xCB15A4CC, 0xB01A4504,
+  0xF1E47D8D, 0x844A1BE5, 0xBAE7DFDC, 0x42CBDA70,
+  0xCD7DAE0A, 0x57E85B7A, 0xD53F5AF6, 0x20CF4D8C,
+  0xCEA4D428, 0x79D130A4, 0x3486EBFB, 0x33D3CDDC,
+  0x77853B53, 0x37EFFCB5, 0xC5068778, 0xE580B3E6,
+  0x4E68B8F4, 0xC5C8B37E, 0x0D809EA2, 0x398FEB7C,
+  0x132A4F94, 0x43B7950E, 0x2FEE7D1C, 0x223613BD,
+  0xDD06CAA2, 0x37DF932B, 0xC4248289, 0xACF3EBC3,
+  0x5715F6B7, 0xEF3478DD, 0xF267616F, 0xC148CBE4,
+  0x9052815E, 0x5E410FAB, 0xB48A2465, 0x2EDA7FA4,
+  0xE87B40E4, 0xE98EA084, 0x5889E9E1, 0xEFD390FC,
+  0xDD07D35B, 0xDB485694, 0x38D7E5B2, 0x57720101,
+  0x730EDEBC, 0x5B643113, 0x94917E4F, 0x503C2FBA,
+  0x646F1282, 0x7523D24A, 0xE0779695, 0xF9C17A8F,
+  0x7A5B2121, 0xD187B896, 0x29263A4D, 0xBA510CDF,
+  0x81F47C9F, 0xAD1163ED, 0xEA7B5965, 0x1A00726E,
+  0x11403092, 0x00DA6D77, 0x4A0CDD61, 0xAD1F4603,
+  0x605BDFB0, 0x9EEDC364, 0x22EBE6A8, 0xCEE7D28A,
+  0xA0E736A0, 0x5564A6B9, 0x10853209, 0xC7EB8F37,
+  0x2DE705CA, 0x8951570F, 0xDF09822B, 0xBD691A6C,
+  0xAA12E4F2, 0x87451C0F, 0xE0F6A27A, 0x3ADA4819,
+  0x4CF1764F, 0x0D771C2B, 0x67CDB156, 0x350D8384,
+  0x5938FA0F, 0x42399EF3, 0x36997B07, 0x0E84093D,
+  0x4AA93E61, 0x8360D87B, 0x1FA98B0C, 0x1149382C,
+  0xE97625A5, 0x0614D1B7, 0x0E25244B, 0x0C768347,
+  0x589E8D82, 0x0D2059D1, 0xA466BB1E, 0xF8DA0A82,
+  0x04F19130, 0xBA6E4EC0, 0x99265164, 0x1EE7230D,
+  0x50B2AD80, 0xEAEE6801, 0x8DB2A283, 0xEA8BF59E
+};
+
diff --git a/cbc.c b/cbc.c
new file mode 100644 (file)
index 0000000..8a0a3ba
--- /dev/null
+++ b/cbc.c
@@ -0,0 +1,156 @@
+/* cbc.c
+ *
+ * Cipher block chaining mode.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "cbc.h"
+
+#include "memxor.h"
+#include "nettle-internal.h"
+
+void
+cbc_encrypt(void *ctx, nettle_crypt_func f,
+           unsigned block_size, uint8_t *iv,
+           unsigned length, uint8_t *dst,
+           const uint8_t *src)
+{
+  assert(!(length % block_size));
+
+  for ( ; length; length -= block_size, src += block_size, dst += block_size)
+    {
+      memxor(iv, src, block_size);
+      f(ctx, block_size, dst, iv);
+      memcpy(iv, dst, block_size);
+    }
+}
+
+/* Don't allocate any more space than this on the stack */
+#define CBC_BUFFER_LIMIT 512
+
+void
+cbc_decrypt(void *ctx, nettle_crypt_func f,
+           unsigned block_size, uint8_t *iv,
+           unsigned length, uint8_t *dst,
+           const uint8_t *src)
+{
+  assert(!(length % block_size));
+
+  if (!length)
+    return;
+
+  if (src != dst)
+    {
+      /* Decrypt in ECB mode */
+      f(ctx, length, dst, src);
+
+      /* XOR the cryptotext, shifted one block */
+      memxor(dst, iv, block_size);
+      memxor(dst + block_size, src, length - block_size);
+      memcpy(iv, src + length - block_size, block_size);
+    }
+
+  else
+    {
+      /* For in-place CBC, we decrypt into a temporary buffer of size
+       * at most CBC_BUFFER_LIMIT, and process that amount of data at
+       * a time. */
+      
+      /* NOTE: We assume that block_size <= CBC_BUFFER_LIMIT, and we
+        depend on memxor3 working from the end of the area, allowing
+        certain overlapping operands. */ 
+
+      TMP_DECL(buffer, uint8_t, CBC_BUFFER_LIMIT);
+      TMP_DECL(initial_iv, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
+
+      unsigned buffer_size;
+
+      if (length <= CBC_BUFFER_LIMIT)
+       buffer_size = length;
+      else
+       buffer_size
+         = CBC_BUFFER_LIMIT - (CBC_BUFFER_LIMIT % block_size);
+
+      TMP_ALLOC(buffer, buffer_size);
+      TMP_ALLOC(initial_iv, block_size);
+
+      for ( ; length > buffer_size;
+           length -= buffer_size, src += buffer_size, dst += buffer_size)
+       {
+         f(ctx, buffer_size, buffer, src);
+         memcpy(initial_iv, iv, block_size);
+         memcpy(iv, src + buffer_size - block_size, block_size);
+         memxor3(dst + block_size, buffer + block_size, src,
+                 buffer_size - block_size);
+         memxor3(dst, buffer, initial_iv, block_size);
+       }
+
+      f(ctx, length, buffer, src);
+      memcpy(initial_iv, iv, block_size);
+      /* Copies last block */
+      memcpy(iv, src + length - block_size, block_size);
+      /* Writes all but first block, reads all but last block. */
+      memxor3(dst + block_size, buffer + block_size, src,
+             length - block_size);
+      /* Writes first block. */
+      memxor3(dst, buffer, initial_iv, block_size);
+    }
+}
+
+#if 0
+#include "twofish.h"
+#include "aes.h"
+
+static void foo(void)
+{
+  struct CBC_CTX(struct twofish_ctx, TWOFISH_BLOCK_SIZE) ctx;
+  uint8_t src[TWOFISH_BLOCK_SIZE];
+  uint8_t dst[TWOFISH_BLOCK_SIZE];
+  
+  CBC_ENCRYPT(&ctx, twofish_encrypt, TWOFISH_BLOCK_SIZE, dst, src);
+
+  /* Should result in a warning */
+  CBC_ENCRYPT(&ctx, aes_encrypt, TWOFISH_BLOCK_SIZE, dst, src);
+  
+}
+
+static void foo2(void)
+{
+  struct twofish_ctx ctx;
+  uint8_t iv[TWOFISH_BLOCK_SIZE];
+  uint8_t src[TWOFISH_BLOCK_SIZE];
+  uint8_t dst[TWOFISH_BLOCK_SIZE];
+  
+  CBC_ENCRYPT2(&ctx, twofish_encrypt, TWOFISH_BLOCK_SIZE, iv, TWOFISH_BLOCK_SIZE, dst, src);
+  /* Should result in a warning */
+  CBC_ENCRYPT2(&ctx, aes_encrypt, TWOFISH_BLOCK_SIZE, iv, TWOFISH_BLOCK_SIZE, dst, src);
+}
+
+#endif
diff --git a/cbc.h b/cbc.h
new file mode 100644 (file)
index 0000000..8c56699
--- /dev/null
+++ b/cbc.h
@@ -0,0 +1,76 @@
+/* cbc.h
+ *
+ * Cipher block chaining mode.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_CBC_H_INCLUDED
+#define NETTLE_CBC_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define cbc_encrypt nettle_cbc_encrypt
+#define cbc_decrypt nettle_cbc_decrypt
+
+void
+cbc_encrypt(void *ctx, nettle_crypt_func f,
+           unsigned block_size, uint8_t *iv,
+           unsigned length, uint8_t *dst,
+           const uint8_t *src);
+
+void
+cbc_decrypt(void *ctx, nettle_crypt_func f,
+           unsigned block_size, uint8_t *iv,
+           unsigned length, uint8_t *dst,
+           const uint8_t *src);
+
+#define CBC_CTX(type, size) \
+{ type ctx; uint8_t iv[size]; }
+
+#define CBC_SET_IV(ctx, data) \
+memcpy((ctx)->iv, (data), sizeof((ctx)->iv))
+
+/* NOTE: Avoid using NULL, as we don't include anything defining it. */
+#define CBC_ENCRYPT(self, f, length, dst, src)         \
+(0 ? ((f)(&(self)->ctx, 0, (void *)0, (void *)0))                      \
+   : cbc_encrypt((void *) &(self)->ctx,                        \
+                 (nettle_crypt_func *) (f),            \
+                sizeof((self)->iv), (self)->iv,        \
+                 (length), (dst), (src)))
+
+#define CBC_DECRYPT(self, f, length, dst, src)         \
+(0 ? ((f)(&(self)->ctx, 0, (void *)0, (void *)0))                      \
+   : cbc_decrypt((void *) &(self)->ctx,                        \
+                 (nettle_crypt_func *) (f),            \
+                sizeof((self)->iv), (self)->iv,        \
+                 (length), (dst), (src)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_CBC_H_INCLUDED */
diff --git a/config.guess b/config.guess
new file mode 100755 (executable)
index 0000000..c3bae20
--- /dev/null
@@ -0,0 +1,1439 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2005-03-17'
+
+# 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
+# (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.
+#
+# 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 <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# 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.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+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."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+       for c in cc gcc c89 c99 ; do
+         if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+            CC_FOR_BUILD="$c"; break ;
+         fi ;
+       done ;
+       if test x"$CC_FOR_BUILD" = x ; then
+         CC_FOR_BUILD=no_compiler_found ;
+       fi
+       ;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+       PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+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
+
+# 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*,
+       # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+       # switched to ELF, *-*-netbsd* would select the old
+       # object file format.  This provides both forward
+       # compatibility and a consistent mechanism for selecting the
+       # object file format.
+       #
+       # Note: NetBSD doesn't particularly care about the vendor
+       # portion of the name.  We always set it to "unknown".
+       sysctl="sysctl -n hw.machine_arch"
+       UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+           /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+       case "${UNAME_MACHINE_ARCH}" in
+           armeb) machine=armeb-unknown ;;
+           arm*) machine=arm-unknown ;;
+           sh3el) machine=shl-unknown ;;
+           sh3eb) machine=sh-unknown ;;
+           *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+       esac
+       # The Operating System including object format, if it has switched
+       # to ELF recently, or will in the future.
+       case "${UNAME_MACHINE_ARCH}" in
+           arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+               eval $set_cc_for_build
+               if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+                       | grep __ELF__ >/dev/null
+               then
+                   # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+                   # Return netbsd for either.  FIX?
+                   os=netbsd
+               else
+                   os=netbsdelf
+               fi
+               ;;
+           *)
+               os=netbsd
+               ;;
+       esac
+       # The OS release
+       # Debian GNU/NetBSD machines have a different userland, and
+       # thus, need a distinct triplet. However, they do not need
+       # kernel version information, so it can be replaced with a
+       # suitable tag, in the style of linux-gnu.
+       case "${UNAME_VERSION}" in
+           Debian*)
+               release='-gnu'
+               ;;
+           *)
+               release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+               ;;
+       esac
+       # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+       # contains redundant information, the shorter form:
+       # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+       echo "${machine}-${os}${release}"
+       exit 0 ;;
+    amiga:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hp300:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    macppc:OpenBSD:*:*)
+       echo powerpc-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+       echo m88k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+       echo powerpc-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pegasos:OpenBSD:*:*)
+       echo powerpc-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pmax:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sgi:OpenBSD:*:*)
+       echo mipseb-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sun3:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:OpenBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    alpha:OSF1:*:*)
+       if test $UNAME_RELEASE = "V4.0"; then
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+       fi
+       # According to Compaq, /usr/sbin/psrinfo has been available on
+       # OSF/1 and Tru64 systems produced since 1995.  I hope that
+       # covers most systems running today.  This code pipes the CPU
+       # types through head -n 1, so we only detect the type of CPU 0.
+       ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+       case "$ALPHA_CPU_TYPE" in
+           "EV4 (21064)")
+               UNAME_MACHINE="alpha" ;;
+           "EV4.5 (21064)")
+               UNAME_MACHINE="alpha" ;;
+           "LCA4 (21066/21068)")
+               UNAME_MACHINE="alpha" ;;
+           "EV5 (21164)")
+               UNAME_MACHINE="alphaev5" ;;
+           "EV5.6 (21164A)")
+               UNAME_MACHINE="alphaev56" ;;
+           "EV5.6 (21164PC)")
+               UNAME_MACHINE="alphapca56" ;;
+           "EV5.7 (21164PC)")
+               UNAME_MACHINE="alphapca57" ;;
+           "EV6 (21264)")
+               UNAME_MACHINE="alphaev6" ;;
+           "EV6.7 (21264A)")
+               UNAME_MACHINE="alphaev67" ;;
+           "EV6.8CB (21264C)")
+               UNAME_MACHINE="alphaev68" ;;
+           "EV6.8AL (21264B)")
+               UNAME_MACHINE="alphaev68" ;;
+           "EV6.8CX (21264D)")
+               UNAME_MACHINE="alphaev68" ;;
+           "EV6.9A (21264/EV69A)")
+               UNAME_MACHINE="alphaev69" ;;
+           "EV7 (21364)")
+               UNAME_MACHINE="alphaev7" ;;
+           "EV7.9 (21364A)")
+               UNAME_MACHINE="alphaev79" ;;
+       esac
+       # A Vn.n version is a released version.
+       # A Tn.n version is a released field test version.
+       # A Xn.n version is an unreleased experimental baselevel.
+       # 1.2 uses "1.2" for uname -r.
+       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+       exit 0 ;;
+    Alpha*:OpenVMS:*:*)
+       echo alpha-hp-vms
+       exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # Should we change UNAME_MACHINE based on the output of uname instead
+       # of the specific Alpha model?
+       echo alpha-pc-interix
+       exit 0 ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-unknown-sysv4
+       exit 0;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-amigaos
+       exit 0 ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-morphos
+       exit 0 ;;
+    *:OS/390:*:*)
+       echo i370-ibm-openedition
+       exit 0 ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+       exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+       echo arm-acorn-riscix${UNAME_RELEASE}
+       exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+       echo hppa1.1-hitachi-hiuxmpp
+       exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+       if test "`(/bin/universe) 2>/dev/null`" = att ; then
+               echo pyramid-pyramid-sysv3
+       else
+               echo pyramid-pyramid-bsd
+       fi
+       exit 0 ;;
+    NILE*:*:*:dcosx)
+       echo pyramid-pyramid-svr4
+       exit 0 ;;
+    DRS?6000:unix:4.0:6*)
+       echo sparc-icl-nx6
+       exit 0 ;;
+    DRS?6000:UNIX_SV:4.2*:7*)
+       case `/usr/bin/uname -p` in
+           sparc) echo sparc-icl-nx7 && exit 0 ;;
+       esac ;;
+    sun4H:SunOS:5.*:*)
+       echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    i86pc:SunOS:5.*:*)
+       case "`optisa \`isainfo\``" in
+           amd64)
+               echo x86_64-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+               ;;
+           *)
+               echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+               ;;
+       esac
+       exit 0 ;;
+    sun4*:SunOS:6*:*)
+       # According to config.sub, this is the proper way to canonicalize
+       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+       # it's likely to be more like Solaris than SunOS4.
+       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:*:*)
+       case "`/usr/bin/arch -k`" in
+           Series*|S4*)
+               UNAME_RELEASE=`uname -v`
+               ;;
+       esac
+       # Japanese Language versions have a version number like `4.1.3-JL'.
+       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       exit 0 ;;
+    sun3*:SunOS:*:*)
+       echo m68k-sun-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    sun*:*:4.2BSD:*)
+       UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       case "`/bin/arch`" in
+           sun3)
+               echo m68k-sun-sunos${UNAME_RELEASE}
+               ;;
+           sun4)
+               echo sparc-sun-sunos${UNAME_RELEASE}
+               ;;
+       esac
+       exit 0 ;;
+    aushp:SunOS:*:*)
+       echo sparc-auspex-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+       echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    powerpc:machten:*:*)
+       echo powerpc-apple-machten${UNAME_RELEASE}
+       exit 0 ;;
+    RISC*:Mach:*:*)
+       echo mips-dec-mach_bsd4.3
+       exit 0 ;;
+    RISC*:ULTRIX:*:*)
+       echo mips-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+       echo vax-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+       echo clipper-intergraph-clix${UNAME_RELEASE}
+       exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+       #if defined (host_mips) && defined (MIPSEB)
+       #if defined (SYSTYPE_SYSV)
+         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_SVR4)
+         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+       #endif
+       #endif
+         exit (-1);
+       }
+EOF
+       $CC_FOR_BUILD -o $dummy $dummy.c \
+         && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+         && exit 0
+       echo mips-mips-riscos${UNAME_RELEASE}
+       exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+       echo powerpc-motorola-powermax
+       exit 0 ;;
+    Motorola:*:4.3:PL8-*)
+       echo powerpc-harris-powermax
+       exit 0 ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+       echo powerpc-harris-powermax
+       exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit 0 ;;
+    m88k:CX/UX:7*:*)
+       echo m88k-harris-cxux7
+       exit 0 ;;
+    m88k:*:4*:R4*)
+       echo m88k-motorola-sysv4
+       exit 0 ;;
+    m88k:*:3*:R3*)
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+       if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+       then
+           if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+              [ ${TARGET_BINARY_INTERFACE}x = x ]
+           then
+               echo m88k-dg-dgux${UNAME_RELEASE}
+           else
+               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+           fi
+       else
+           echo i586-dg-dgux${UNAME_RELEASE}
+       fi
+       exit 0 ;;
+    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
+       echo m88k-dolphin-sysv3
+       exit 0 ;;
+    M88*:*:R3*:*)
+       # Delta 88k system running SVR3
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+       echo m88k-tektronix-sysv3
+       exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+       echo m68k-tektronix-bsd
+       exit 0 ;;
+    *:IRIX*:*:*)
+       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+       echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+       exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+       echo i386-ibm-aix
+       exit 0 ;;
+    ia64:AIX:*:*)
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:2:3)
+       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+               eval $set_cc_for_build
+               sed 's/^                //' << EOF >$dummy.c
+               #include <sys/systemcfg.h>
+
+               main()
+                       {
+                       if (!__power_pc())
+                               exit(1);
+                       puts("powerpc-ibm-aix3.2.5");
+                       exit(0);
+                       }
+EOF
+               $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+               echo rs6000-ibm-aix3.2.5
+       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+               echo rs6000-ibm-aix3.2.4
+       else
+               echo rs6000-ibm-aix3.2
+       fi
+       exit 0 ;;
+    *:AIX:*:[45])
+       IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+       if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+               IBM_ARCH=rs6000
+       else
+               IBM_ARCH=powerpc
+       fi
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:*:*)
+       echo rs6000-ibm-aix
+       exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+       echo romp-ibm-bsd4.4
+       exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+       echo rs6000-bull-bosx
+       exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+       echo m68k-bull-sysv3
+       exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+       echo m68k-hp-bsd
+       exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+       echo m68k-hp-bsd4.4
+       exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       case "${UNAME_MACHINE}" in
+           9000/31? )            HP_ARCH=m68000 ;;
+           9000/[34]?? )         HP_ARCH=m68k ;;
+           9000/[678][0-9][0-9])
+               if [ -x /usr/bin/getconf ]; then
+                   sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+                         '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+               fi
+               if [ "${HP_ARCH}" = "" ]; then
+                   eval $set_cc_for_build
+                   sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+               {
+               case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+               case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+               case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+                   switch (bits)
+                       {
+                       case 64: puts ("hppa2.0w"); break;
+                       case 32: puts ("hppa2.0n"); break;
+                       default: puts ("hppa2.0"); break;
+                       } break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+                   puts ("hppa2.0"); break;
+              #endif
+               default: puts ("hppa1.0"); break;
+               }
+                  exit (0);
+              }
+EOF
+                   (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+                   test -z "$HP_ARCH" && HP_ARCH=hppa
+               fi ;;
+       esac
+       if [ ${HP_ARCH} = "hppa2.0w" ]
+       then
+           # avoid double evaluation of $set_cc_for_build
+           test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+           if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+           then
+               HP_ARCH="hppa2.0w"
+           else
+               HP_ARCH="hppa64"
+           fi
+       fi
+       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    ia64:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       echo ia64-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    3050*:HI-UX:*:*)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <unistd.h>
+       int
+       main ()
+       {
+         long cpu = sysconf (_SC_CPU_VERSION);
+         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+            results, however.  */
+         if (CPU_IS_PA_RISC (cpu))
+           {
+             switch (cpu)
+               {
+                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+                 default: puts ("hppa-hitachi-hiuxwe2"); break;
+               }
+           }
+         else if (CPU_IS_HP_MC68K (cpu))
+           puts ("m68k-hitachi-hiuxwe2");
+         else puts ("unknown-hitachi-hiuxwe2");
+         exit (0);
+       }
+EOF
+       $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+       echo unknown-hitachi-hiuxwe2
+       exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+       echo hppa1.1-hp-bsd
+       exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+       echo hppa1.0-hp-bsd
+       exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+       echo hppa1.0-hp-mpeix
+       exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+       echo hppa1.1-hp-osf
+       exit 0 ;;
+    hp8??:OSF1:*:*)
+       echo hppa1.0-hp-osf
+       exit 0 ;;
+    i*86:OSF1:*:*)
+       if [ -x /usr/sbin/sysversion ] ; then
+           echo ${UNAME_MACHINE}-unknown-osf1mk
+       else
+           echo ${UNAME_MACHINE}-unknown-osf1
+       fi
+       exit 0 ;;
+    parisc*:Lites*:*:*)
+       echo hppa1.1-hp-lites
+       exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+       echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+       echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+       echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+       echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+       echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+             -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*TS:*:*:*)
+       echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*T3E:*:*:*)
+       echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*SV1:*:*:*)
+       echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    *:UNICOS/mp:*:*)
+       echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+       FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+       exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    sparc*:BSD/OS:*:*)
+       echo sparc-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:FreeBSD:*:*)
+       # Determine whether the default compiler uses glibc.
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <features.h>
+       #if __GLIBC__ >= 2
+       LIBC=gnu
+       #else
+       LIBC=
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+       # GNU/KFreeBSD systems have a "k" prefix to indicate we are using
+       # FreeBSD's kernel, but not the complete OS.
+       case ${LIBC} in gnu) kernel_only='k' ;; esac
+       echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
+       exit 0 ;;
+    i*:CYGWIN*:*)
+       echo ${UNAME_MACHINE}-pc-cygwin
+       exit 0 ;;
+    i*:MINGW*:*)
+       echo ${UNAME_MACHINE}-pc-mingw32
+       exit 0 ;;
+    i*:PW*:*)
+       echo ${UNAME_MACHINE}-pc-pw32
+       exit 0 ;;
+    x86:Interix*:[34]*)
+       echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+       exit 0 ;;
+    [x3456]86:Windows_95:* | [x3456]86:Windows_98:* | [x3456]86:Windows_NT:*)
+       echo i${UNAME_MACHINE}-pc-mks
+       exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+       # UNAME_MACHINE based on the output of uname instead of i386?
+       echo i586-pc-interix
+       exit 0 ;;
+    i*:UWIN*:*)
+       echo ${UNAME_MACHINE}-pc-uwin
+       exit 0 ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin
+       exit 0 ;;
+    prep*:SunOS:5.*:*)
+       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    *:GNU:*:*)
+       # the GNU system
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       exit 0 ;;
+    *: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
+       exit 0 ;;
+    i*86:Minix:*:*)
+       echo ${UNAME_MACHINE}-pc-minix
+       exit 0 ;;
+    arm*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    cris:Linux:*:*)
+       echo cris-axis-linux-gnu
+       exit 0 ;;
+    ia64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    m68*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    mips:Linux:*:*)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #undef CPU
+       #undef mips
+       #undef mipsel
+       #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+       CPU=mipsel
+       #else
+       #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+       CPU=mips
+       #else
+       CPU=
+       #endif
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+       test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+       ;;
+    mips64:Linux:*:*)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #undef CPU
+       #undef mips64
+       #undef mips64el
+       #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+       CPU=mips64el
+       #else
+       #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+       CPU=mips64
+       #else
+       CPU=
+       #endif
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+       test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+       ;;
+    ppc:Linux:*:*)
+       echo powerpc-unknown-linux-gnu
+       exit 0 ;;
+    ppc64:Linux:*:*)
+       echo powerpc64-unknown-linux-gnu
+       exit 0 ;;
+    alpha:Linux:*:*)
+       case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+         EV5)   UNAME_MACHINE=alphaev5 ;;
+         EV56)  UNAME_MACHINE=alphaev56 ;;
+         PCA56) UNAME_MACHINE=alphapca56 ;;
+         PCA57) UNAME_MACHINE=alphapca56 ;;
+         EV6)   UNAME_MACHINE=alphaev6 ;;
+         EV67)  UNAME_MACHINE=alphaev67 ;;
+         EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+       objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+       if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+       echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+       exit 0 ;;
+    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 ;;
+       esac
+       exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+       echo hppa64-unknown-linux-gnu
+       exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+       echo ${UNAME_MACHINE}-ibm-linux
+       exit 0 ;;
+    sh64*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    sh*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    x86_64:Linux:*:*)
+       echo x86_64-unknown-linux-gnu
+       exit 0 ;;
+    i*86:Linux:*:*)
+       # The BFD linker knows what the default object file format is, so
+       # first see if it will tell us. cd to the root directory to prevent
+       # problems with other programs or directories called `ld' in the path.
+       # Set LC_ALL=C to ensure ld outputs messages in English.
+       ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+                        | sed -ne '/supported targets:/!d
+                                   s/[         ][      ]*/ /g
+                                   s/.*supported targets: *//
+                                   s/ .*//
+                                   p'`
+        case "$ld_supported_targets" in
+         elf32-i386)
+               TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+               ;;
+         a.out-i386-linux)
+               echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+               exit 0 ;;
+         coff-i386)
+               echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+               exit 0 ;;
+         "")
+               # Either a pre-BFD a.out linker (linux-gnuoldld) or
+               # one that does not give us useful --help.
+               echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+               exit 0 ;;
+       esac
+       # Determine whether the default compiler is a.out or elf
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <features.h>
+       #ifdef __ELF__
+       # ifdef __GLIBC__
+       #  if __GLIBC__ >= 2
+       LIBC=gnu
+       #  else
+       LIBC=gnulibc1
+       #  endif
+       # else
+       LIBC=gnulibc1
+       # endif
+       #else
+       #ifdef __INTEL_COMPILER
+       LIBC=gnu
+       #else
+       LIBC=gnuaout
+       #endif
+       #endif
+       #ifdef __dietlibc__
+       LIBC=dietlibc
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+       test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+       test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+       ;;
+    i*86:DYNIX/ptx:4*:*)
+       # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+       # earlier versions are messed up and put the nodename in both
+       # sysname and nodename.
+       echo i386-sequent-sysv4
+       exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+       # I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       exit 0 ;;
+    i*86:OS/2:*:*)
+       # If we were able to find `uname', then EMX Unix compatibility
+       # is probably installed.
+       echo ${UNAME_MACHINE}-pc-os2-emx
+       exit 0 ;;
+    i*86:XTS-300:*:STOP)
+       echo ${UNAME_MACHINE}-unknown-stop
+       exit 0 ;;
+    i*86:atheos:*:*)
+       echo ${UNAME_MACHINE}-unknown-atheos
+       exit 0 ;;
+       i*86:syllable:*:*)
+       echo ${UNAME_MACHINE}-pc-syllable
+       exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+       echo i386-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    i*86:*DOS:*:*)
+       echo ${UNAME_MACHINE}-pc-msdosdjgpp
+       exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+       UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+               echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+       else
+               echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+       fi
+       exit 0 ;;
+    i*86:*:5:[78]*)
+       case `/bin/uname -X | grep "^Machine"` in
+           *486*)           UNAME_MACHINE=i486 ;;
+           *Pentium)        UNAME_MACHINE=i586 ;;
+           *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+       esac
+       echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+       exit 0 ;;
+    i*86:*:3.2:*)
+       if test -f /usr/options/cb.name; then
+               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+       elif /bin/uname -X 2>/dev/null >/dev/null ; then
+               UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+               (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+               (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+                       && UNAME_MACHINE=i586
+               (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+       else
+               echo ${UNAME_MACHINE}-pc-sysv32
+       fi
+       exit 0 ;;
+    pc:*:*:*)
+       # Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+       echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+       echo i386-pc-mach3
+       exit 0 ;;
+    paragon:*:*:*)
+       echo i860-intel-osf1
+       exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+       else # Add other i860-SVR4 vendors below as they are discovered.
+         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+       fi
+       exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+       # "miniframe"
+       echo m68010-convergent-sysv
+       exit 0 ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+       echo m68k-convergent-sysv
+       exit 0 ;;
+    M680?0:D-NIX:5.3:*)
+       echo m68k-diab-dnix
+       exit 0 ;;
+    M68*:*:R3V[567]*:*)
+       test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
+       OS_REL=''
+       test -r /etc/.relid \
+       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+         && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+       echo m68k-atari-sysv4
+       exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+       echo powerpc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+       echo mips-dde-sysv${UNAME_RELEASE}
+       exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    RM*:SINIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    *:SINIX-*:*:*)
+       if uname -p 2>/dev/null >/dev/null ; then
+               UNAME_MACHINE=`(uname -p) 2>/dev/null`
+               echo ${UNAME_MACHINE}-sni-sysv4
+       else
+               echo ns32k-sni-sysv
+       fi
+       exit 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+       # From Gerald Hewes <hewes@openmarket.com>.
+       # How about differentiating between stratus architectures? -djm
+       echo hppa1.1-stratus-sysv4
+       exit 0 ;;
+    *:*:*:FTX*)
+       # From seanf@swdc.stratus.com.
+       echo i860-stratus-sysv4
+       exit 0 ;;
+    *:VOS:*:*)
+       # From Paul.Green@stratus.com.
+       echo hppa1.1-stratus-vos
+       exit 0 ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit 0 ;;
+    news*:NEWS-OS:6*:*)
+       echo mips-sony-newsos6
+       exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+       if [ -d /usr/nec ]; then
+               echo mips-nec-sysv${UNAME_RELEASE}
+       else
+               echo mips-unknown-sysv${UNAME_RELEASE}
+       fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
+       echo powerpc-be-beos
+       exit 0 ;;
+    BeMac:BeOS:*:*)    # BeOS running on Mac or Mac clone, PPC only.
+       echo powerpc-apple-beos
+       exit 0 ;;
+    BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
+       echo i586-pc-beos
+       exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+       echo sx4-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+       echo sx5-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    SX-6:SUPER-UX:*:*)
+       echo sx6-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    Power*:Rhapsody:*:*)
+       echo powerpc-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Rhapsody:*:*)
+       echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Darwin:*:*)
+       case `uname -p` in
+           *86) UNAME_PROCESSOR=i686 ;;
+           powerpc) UNAME_PROCESSOR=powerpc ;;
+       esac
+       echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+       exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+       UNAME_PROCESSOR=`uname -p`
+       if test "$UNAME_PROCESSOR" = "x86"; then
+               UNAME_PROCESSOR=i386
+               UNAME_MACHINE=pc
+       fi
+       echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+       exit 0 ;;
+    *:QNX:*:4*)
+       echo i386-pc-qnx
+       exit 0 ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+       echo nsr-tandem-nsk${UNAME_RELEASE}
+       exit 0 ;;
+    *:NonStop-UX:*:*)
+       echo mips-compaq-nonstopux
+       exit 0 ;;
+    BS2000:POSIX*:*:*)
+       echo bs2000-siemens-sysv
+       exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+       echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+       exit 0 ;;
+    *:Plan9:*:*)
+       # "uname -m" is not consistent, so use $cputype instead. 386
+       # is converted to i386 for consistency with other x86
+       # operating systems.
+       if test "$cputype" = "386"; then
+           UNAME_MACHINE=i386
+       else
+           UNAME_MACHINE="$cputype"
+       fi
+       echo ${UNAME_MACHINE}-unknown-plan9
+       exit 0 ;;
+    *:TOPS-10:*:*)
+       echo pdp10-unknown-tops10
+       exit 0 ;;
+    *:TENEX:*:*)
+       echo pdp10-unknown-tenex
+       exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+       echo pdp10-dec-tops20
+       exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+       echo pdp10-xkl-tops20
+       exit 0 ;;
+    *:TOPS-20:*:*)
+       echo pdp10-unknown-tops20
+       exit 0 ;;
+    *:ITS:*:*)
+       echo pdp10-unknown-its
+       exit 0 ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+       exit 0 ;;
+    *:DRAGONFLY:*:*)
+       echo ${UNAME_MACHINE}-unknown-dragonfly${UNAME_RELEASE}
+       exit 0 ;;
+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_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+         ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+       echo c1-convex-bsd
+       exit 0 ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit 0 ;;
+    c34*)
+       echo c34-convex-bsd
+       exit 0 ;;
+    c38*)
+       echo c38-convex-bsd
+       exit 0 ;;
+    c4*)
+       echo c4-convex-bsd
+       exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config.h.in b/config.h.in
new file mode 100644 (file)
index 0000000..b800cc0
--- /dev/null
@@ -0,0 +1,211 @@
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+   systems. This function is required for `alloca.c' support on those systems.
+   */
+#undef CRAY_STACKSEG_END
+
+/* Define to 1 if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+   */
+#undef HAVE_ALLOCA_H
+
+/* Define to 1 if you have the `clock_gettime' function */
+#undef HAVE_CLOCK_GETTIME
+
+/* Define if fcntl file locking is available */
+#undef HAVE_FCNTL_LOCKING
+
+/* Define if the compiler understands __attribute__ */
+#undef HAVE_GCC_ATTRIBUTE
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `gmp' library (-lgmp). */
+#undef HAVE_LIBGMP
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memxor' function. */
+#undef HAVE_MEMXOR
+
+/* Define if mpz_powm_sec is available (appeared in GMP-5) */
+#undef HAVE_MPZ_POWM_SEC
+
+/* Define to 1 if you have the <openssl/aes.h> header file. */
+#undef HAVE_OPENSSL_AES_H
+
+/* Define to 1 if you have the <openssl/blowfish.h> header file. */
+#undef HAVE_OPENSSL_BLOWFISH_H
+
+/* Define to 1 if you have the <openssl/cast.h> header file. */
+#undef HAVE_OPENSSL_CAST_H
+
+/* Define to 1 if you have the <openssl/des.h> header file. */
+#undef HAVE_OPENSSL_DES_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* The size of `char', as computed by sizeof. */
+#undef SIZEOF_CHAR
+
+/* The size of `int', as computed by sizeof. */
+#undef SIZEOF_INT
+
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of `short', as computed by sizeof. */
+#undef SIZEOF_SHORT
+
+/* The size of `void*', as computed by sizeof. */
+#undef SIZEOF_VOIDP
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at runtime.
+       STACK_DIRECTION > 0 => grows toward higher addresses
+       STACK_DIRECTION < 0 => grows toward lower addresses
+       STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Defined if public key features are enabled */
+#undef WITH_HOGWEED
+
+/* Define if you have openssl's libcrypto (used for benchmarking) */
+#undef WITH_OPENSSL
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+#  undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
+
+/* AIX requires this to be the first thing in the file.  */
+#ifndef __GNUC__
+# if HAVE_ALLOCA_H
+#  include <alloca.h>
+# else
+#  ifdef _AIX
+ #pragma alloca
+#  else
+#   ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+#   endif
+#  endif
+/* Needed for alloca on windows */
+#  if HAVE_MALLOC_H
+#   include <malloc.h>
+#  endif
+# endif
+#else /* defined __GNUC__ */
+# if HAVE_ALLOCA_H
+#  include <alloca.h>
+# endif
+#endif
+
+
+#if HAVE_STRERROR
+#define STRERROR strerror
+#else
+#define STRERROR(x) (sys_errlist[x])
+#endif
+
+
+#if __GNUC__ && HAVE_GCC_ATTRIBUTE
+# define NORETURN __attribute__ ((__noreturn__))
+# define PRINTF_STYLE(f, a) __attribute__ ((__format__ (__printf__, f, a)))
+# define UNUSED __attribute__ ((__unused__))
+#else
+# define NORETURN
+# define PRINTF_STYLE(f, a)
+# define UNUSED
+#endif
+
+
+/* Needs include of <limits.h> before use. */
+#define HAVE_NATIVE_64_BIT (SIZEOF_LONG * CHAR_BIT >= 64)
+
diff --git a/config.m4.in b/config.m4.in
new file mode 100644 (file)
index 0000000..ec62573
--- /dev/null
@@ -0,0 +1,8 @@
+define(<srcdir>, <<@srcdir@>>)dnl
+define(<C_NAME>, <@ASM_SYMBOL_PREFIX@><$1>)dnl
+define(<ELF_STYLE>, <@ASM_ELF_STYLE@>)dnl
+define(<TYPE_FUNCTION>, <@ASM_TYPE_FUNCTION@>)dnl
+define(<ALIGN_LOG>, <@ASM_ALIGN_LOG@>)dnl
+divert(1)
+@ASM_MARK_NOEXEC_STACK@
+divert
diff --git a/config.make.in b/config.make.in
new file mode 100644 (file)
index 0000000..152b42e
--- /dev/null
@@ -0,0 +1,93 @@
+# Makefile settings shared between Makefiles.
+
+CC = @CC@
+CXX = @CXX@
+CFLAGS = @CFLAGS@
+CXXFLAGS = @CXXFLAGS@
+CCPIC = @CCPIC@
+CCPIC_MAYBE = @CCPIC_MAYBE@
+CPPFLAGS = @CPPFLAGS@
+DEFS = @DEFS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+LIBOBJS = @LIBOBJS@
+
+OBJEXT = @OBJEXT@
+EXEEXT = @EXEEXT@
+
+DEP_FLAGS = @DEP_FLAGS@
+DEP_PROCESS = @DEP_PROCESS@
+
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+
+SHLIBCFLAGS = @SHLIBCFLAGS@
+
+LIBNETTLE_MAJOR = @LIBNETTLE_MAJOR@
+LIBNETTLE_MINOR = @LIBNETTLE_MINOR@
+LIBNETTLE_SONAME = @LIBNETTLE_SONAME@
+LIBNETTLE_FILE = @LIBNETTLE_FILE@
+LIBNETTLE_FORLINK = @LIBNETTLE_FORLINK@
+LIBNETTLE_LIBS = @LIBNETTLE_LIBS@
+LIBNETTLE_LINK = @LIBNETTLE_LINK@
+
+LIBHOGWEED_MAJOR = @LIBHOGWEED_MAJOR@
+LIBHOGWEED_MINOR = @LIBHOGWEED_MINOR@
+LIBHOGWEED_SONAME = @LIBHOGWEED_SONAME@
+LIBHOGWEED_FILE = @LIBHOGWEED_FILE@
+LIBHOGWEED_FORLINK = @LIBHOGWEED_FORLINK@
+LIBHOGWEED_LIBS = @LIBHOGWEED_LIBS@
+LIBHOGWEED_LINK = @LIBHOGWEED_LINK@
+
+AR = ar
+ARFLAGS = cru
+AUTOCONF = autoconf
+AUTOHEADER = autoheader
+M4 = @M4@
+MAKEINFO = makeinfo
+RANLIB = @RANLIB@
+
+prefix =       @prefix@
+exec_prefix =  @exec_prefix@
+datarootdir =  @datarootdir@
+bindir =       @bindir@
+libdir =       @libdir@
+includedir =   @includedir@
+infodir =      @infodir@
+
+# PRE_CPPFLAGS and PRE_LDFLAGS lets each Makefile.in prepend its own
+# flags before CPPFLAGS and LDFLAGS.
+
+COMPILE = $(CC) $(PRE_CPPFLAGS) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(CCPIC) $(DEP_FLAGS)
+COMPILE_CXX = $(CXX) $(PRE_CPPFLAGS) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) $(CCPIC) $(DEP_FLAGS)
+LINK = $(CC) $(CFLAGS) $(PRE_LDFLAGS) $(LDFLAGS)
+LINK_CXX = $(CXX) $(CXXFLAGS) $(PRE_LDFLAGS) $(LDFLAGS)
+
+# Default rule. Must be here, since config.make is included before the
+# usual targets.
+default: all
+
+# For some reason the suffixes list must be set before the rules.
+# Otherwise BSD make won't build binaries e.g. aesdata. On the other
+# hand, AIX make has the opposite idiosyncrasies to BSD, and the AIX
+# compile was broken when .SUFFIXES was moved here from Makefile.in.
+
+.SUFFIXES:
+.SUFFIXES: .asm .c .$(OBJEXT) .p$(OBJEXT) .html .dvi .info .exe .pdf .ps .texinfo
+
+# Disable builtin rule
+%$(EXEEXT) : %.c
+.c:
+
+# Keep object files
+.PRECIOUS: %.o
+
+.PHONY: all check install uninstall clean distclean mostlyclean maintainer-clean distdir \
+       all-here check-here install-here clean-here distclean-here mostlyclean-here \
+       maintainer-clean-here distdir-here \
+       install-shared install-info install-headers \
+       uninstall-shared uninstall-info uninstall-headers \
+       dist distcleancheck
diff --git a/config.sub b/config.sub
new file mode 100755 (executable)
index 0000000..ba33103
--- /dev/null
@@ -0,0 +1,1549 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2004-03-12'
+
+# 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
+# (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.
+
+# 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.
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+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
+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."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
+  kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+       -sun*os*)
+               # Prevent following clause from handling this invalid input.
+               ;;
+       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+       -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)
+               os=
+               basic_machine=$1
+               ;;
+       -sim | -cisco | -oki | -wec | -winbond)
+               os=
+               basic_machine=$1
+               ;;
+       -scout)
+               ;;
+       -wrs)
+               os=-vxworks
+               basic_machine=$1
+               ;;
+       -chorusos*)
+               os=-chorusos
+               basic_machine=$1
+               ;;
+       -chorusrdb)
+               os=-chorusrdb
+               basic_machine=$1
+               ;;
+       -hiux*)
+               os=-hiuxwe2
+               ;;
+       -sco5)
+               os=-sco3.2v5
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco4)
+               os=-sco3.2v4
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2.[4-9]*)
+               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2v[4-9]*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco*)
+               os=-sco3.2v2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -udk*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -isc)
+               os=-isc2.2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -clix*)
+               basic_machine=clipper-intergraph
+               ;;
+       -isc*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -lynx*)
+               os=-lynxos
+               ;;
+       -ptx*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+               ;;
+       -windowsnt*)
+               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               ;;
+       -psos*)
+               os=-psos
+               ;;
+       -mint | -mint[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+       # Recognize the basic CPU types without company name.
+       # Some are omitted here because they have special meanings below.
+       1750a | 580 \
+       | a29k \
+       | 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 \
+       | c4x | clipper \
+       | d10v | d30v | dlx | dsp16xx \
+       | fr30 | frv \
+       | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+       | i370 | i860 | i960 | ia64 \
+       | ip2k | iq2000 \
+       | m32r | m32rle | m68000 | m68k | m88k | mcore \
+       | mips | mipsbe | mipseb | mipsel | mipsle \
+       | mips16 \
+       | mips64 | mips64el \
+       | mips64vr | mips64vrel \
+       | mips64orion | mips64orionel \
+       | mips64vr4100 | mips64vr4100el \
+       | mips64vr4300 | mips64vr4300el \
+       | mips64vr5000 | mips64vr5000el \
+       | mipsisa32 | mipsisa32el \
+       | mipsisa32r2 | mipsisa32r2el \
+       | mipsisa64 | mipsisa64el \
+       | mipsisa64r2 | mipsisa64r2el \
+       | mipsisa64sb1 | mipsisa64sb1el \
+       | mipsisa64sr71k | mipsisa64sr71kel \
+       | mipstx39 | mipstx39el \
+       | mn10200 | mn10300 \
+       | msp430 \
+       | ns16k | ns32k \
+       | openrisc | or32 \
+       | pdp10 | pdp11 | pj | pjl \
+       | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+       | pyramid \
+       | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+       | sh64 | sh64le \
+       | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \
+       | strongarm \
+       | tahoe | thumb | tic4x | tic80 | tron \
+       | v850 | v850e \
+       | we32k \
+       | x86 | xscale | xstormy16 | xtensa \
+       | z8k)
+               basic_machine=$basic_machine-unknown
+               ;;
+       m6811 | m68hc11 | m6812 | m68hc12)
+               # Motorola 68HC11/12.
+               basic_machine=$basic_machine-unknown
+               os=-none
+               ;;
+       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+               ;;
+
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i*86 | x86_64)
+         basic_machine=$basic_machine-pc
+         ;;
+       # Object if more than one company name word.
+       *-*-*)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+       # Recognize the basic CPU types with company name.
+       580-* \
+       | a29k-* \
+       | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+       | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+       | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+       | avr-* \
+       | bs2000-* \
+       | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+       | clipper-* | cydra-* \
+       | d10v-* | d30v-* | dlx-* \
+       | elxsi-* \
+       | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+       | h8300-* | h8500-* \
+       | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+       | i*86-* | i860-* | i960-* | ia64-* \
+       | ip2k-* | iq2000-* \
+       | m32r-* | m32rle-* \
+       | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+       | m88110-* | m88k-* | mcore-* \
+       | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+       | mips16-* \
+       | mips64-* | mips64el-* \
+       | mips64vr-* | mips64vrel-* \
+       | mips64orion-* | mips64orionel-* \
+       | mips64vr4100-* | mips64vr4100el-* \
+       | mips64vr4300-* | mips64vr4300el-* \
+       | mips64vr5000-* | mips64vr5000el-* \
+       | mipsisa32-* | mipsisa32el-* \
+       | mipsisa32r2-* | mipsisa32r2el-* \
+       | mipsisa64-* | mipsisa64el-* \
+       | mipsisa64r2-* | mipsisa64r2el-* \
+       | mipsisa64sb1-* | mipsisa64sb1el-* \
+       | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+       | mipstx39-* | mipstx39el-* \
+       | msp430-* \
+       | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
+       | orion-* \
+       | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+       | pyramid-* \
+       | romp-* | rs6000-* \
+       | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+       | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+       | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+       | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+       | tahoe-* | thumb-* \
+       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+       | tron-* \
+       | v850-* | v850e-* | vax-* \
+       | we32k-* \
+       | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+       | xtensa-* \
+       | ymp-* \
+       | z8k-*)
+               ;;
+       # Recognize the various machine names and aliases which stand
+       # for a CPU type and a company and sometimes even an OS.
+       386bsd)
+               basic_machine=i386-unknown
+               os=-bsd
+               ;;
+       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+               basic_machine=m68000-att
+               ;;
+       3b*)
+               basic_machine=we32k-att
+               ;;
+       a29khif)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       abacus)
+               basic_machine=abacus-unknown
+               ;;
+       adobe68k)
+               basic_machine=m68010-adobe
+               os=-scout
+               ;;
+       alliant | fx80)
+               basic_machine=fx80-alliant
+               ;;
+       altos | altos3068)
+               basic_machine=m68k-altos
+               ;;
+       am29k)
+               basic_machine=a29k-none
+               os=-bsd
+               ;;
+       amd64)
+               basic_machine=x86_64-pc
+               ;;
+       amd64-*)
+               basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       amdahl)
+               basic_machine=580-amdahl
+               os=-sysv
+               ;;
+       amiga | amiga-*)
+               basic_machine=m68k-unknown
+               ;;
+       amigaos | amigados)
+               basic_machine=m68k-unknown
+               os=-amigaos
+               ;;
+       amigaunix | amix)
+               basic_machine=m68k-unknown
+               os=-sysv4
+               ;;
+       apollo68)
+               basic_machine=m68k-apollo
+               os=-sysv
+               ;;
+       apollo68bsd)
+               basic_machine=m68k-apollo
+               os=-bsd
+               ;;
+       aux)
+               basic_machine=m68k-apple
+               os=-aux
+               ;;
+       balance)
+               basic_machine=ns32k-sequent
+               os=-dynix
+               ;;
+       c90)
+               basic_machine=c90-cray
+               os=-unicos
+               ;;
+       convex-c1)
+               basic_machine=c1-convex
+               os=-bsd
+               ;;
+       convex-c2)
+               basic_machine=c2-convex
+               os=-bsd
+               ;;
+       convex-c32)
+               basic_machine=c32-convex
+               os=-bsd
+               ;;
+       convex-c34)
+               basic_machine=c34-convex
+               os=-bsd
+               ;;
+       convex-c38)
+               basic_machine=c38-convex
+               os=-bsd
+               ;;
+       cray | j90)
+               basic_machine=j90-cray
+               os=-unicos
+               ;;
+       cr16c)
+               basic_machine=cr16c-unknown
+               os=-elf
+               ;;
+       crds | unos)
+               basic_machine=m68k-crds
+               ;;
+       cris | cris-* | etrax*)
+               basic_machine=cris-axis
+               ;;
+       crx)
+               basic_machine=crx-unknown
+               os=-elf
+               ;;
+       da30 | da30-*)
+               basic_machine=m68k-da30
+               ;;
+       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+               basic_machine=mips-dec
+               ;;
+       decsystem10* | dec10*)
+               basic_machine=pdp10-dec
+               os=-tops10
+               ;;
+       decsystem20* | dec20*)
+               basic_machine=pdp10-dec
+               os=-tops20
+               ;;
+       delta | 3300 | motorola-3300 | motorola-delta \
+             | 3300-motorola | delta-motorola)
+               basic_machine=m68k-motorola
+               ;;
+       delta88)
+               basic_machine=m88k-motorola
+               os=-sysv3
+               ;;
+       dpx20 | dpx20-*)
+               basic_machine=rs6000-bull
+               os=-bosx
+               ;;
+       dpx2* | dpx2*-bull)
+               basic_machine=m68k-bull
+               os=-sysv3
+               ;;
+       ebmon29k)
+               basic_machine=a29k-amd
+               os=-ebmon
+               ;;
+       elxsi)
+               basic_machine=elxsi-elxsi
+               os=-bsd
+               ;;
+       encore | umax | mmax)
+               basic_machine=ns32k-encore
+               ;;
+       es1800 | OSE68k | ose68k | ose | OSE)
+               basic_machine=m68k-ericsson
+               os=-ose
+               ;;
+       fx2800)
+               basic_machine=i860-alliant
+               ;;
+       genix)
+               basic_machine=ns32k-ns
+               ;;
+       gmicro)
+               basic_machine=tron-gmicro
+               os=-sysv
+               ;;
+       go32)
+               basic_machine=i386-pc
+               os=-go32
+               ;;
+       h3050r* | hiux*)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       h8300hms)
+               basic_machine=h8300-hitachi
+               os=-hms
+               ;;
+       h8300xray)
+               basic_machine=h8300-hitachi
+               os=-xray
+               ;;
+       h8500hms)
+               basic_machine=h8500-hitachi
+               os=-hms
+               ;;
+       harris)
+               basic_machine=m88k-harris
+               os=-sysv3
+               ;;
+       hp300-*)
+               basic_machine=m68k-hp
+               ;;
+       hp300bsd)
+               basic_machine=m68k-hp
+               os=-bsd
+               ;;
+       hp300hpux)
+               basic_machine=m68k-hp
+               os=-hpux
+               ;;
+       hp3k9[0-9][0-9] | hp9[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k2[0-9][0-9] | hp9k31[0-9])
+               basic_machine=m68000-hp
+               ;;
+       hp9k3[2-9][0-9])
+               basic_machine=m68k-hp
+               ;;
+       hp9k6[0-9][0-9] | hp6[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k7[0-79][0-9] | hp7[0-79][0-9])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k78[0-9] | hp78[0-9])
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][13679] | hp8[0-9][13679])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][0-9] | hp8[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hppa-next)
+               os=-nextstep3
+               ;;
+       hppaosf)
+               basic_machine=hppa1.1-hp
+               os=-osf
+               ;;
+       hppro)
+               basic_machine=hppa1.1-hp
+               os=-proelf
+               ;;
+       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
+               ;;
+       i*86v4*)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv4
+               ;;
+       i*86v)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv
+               ;;
+       i*86sol2)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-solaris2
+               ;;
+       i386mach)
+               basic_machine=i386-mach
+               os=-mach
+               ;;
+       i386-vsta | vsta)
+               basic_machine=i386-unknown
+               os=-vsta
+               ;;
+       iris | iris4d)
+               basic_machine=mips-sgi
+               case $os in
+                   -irix*)
+                       ;;
+                   *)
+                       os=-irix4
+                       ;;
+               esac
+               ;;
+       isi68 | isi)
+               basic_machine=m68k-isi
+               os=-sysv
+               ;;
+       m88k-omron*)
+               basic_machine=m88k-omron
+               ;;
+       magnum | m3230)
+               basic_machine=mips-mips
+               os=-sysv
+               ;;
+       merlin)
+               basic_machine=ns32k-utek
+               os=-sysv
+               ;;
+       mingw32)
+               basic_machine=i386-pc
+               os=-mingw32
+               ;;
+       miniframe)
+               basic_machine=m68000-convergent
+               ;;
+       *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+       mips3*-*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               ;;
+       mips3*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               ;;
+       mmix*)
+               basic_machine=mmix-knuth
+               os=-mmixware
+               ;;
+       monitor)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       morphos)
+               basic_machine=powerpc-unknown
+               os=-morphos
+               ;;
+       msdos)
+               basic_machine=i386-pc
+               os=-msdos
+               ;;
+       mvs)
+               basic_machine=i370-ibm
+               os=-mvs
+               ;;
+       ncr3000)
+               basic_machine=i486-ncr
+               os=-sysv4
+               ;;
+       netbsd386)
+               basic_machine=i386-unknown
+               os=-netbsd
+               ;;
+       netwinder)
+               basic_machine=armv4l-rebel
+               os=-linux
+               ;;
+       news | news700 | news800 | news900)
+               basic_machine=m68k-sony
+               os=-newsos
+               ;;
+       news1000)
+               basic_machine=m68030-sony
+               os=-newsos
+               ;;
+       news-3600 | risc-news)
+               basic_machine=mips-sony
+               os=-newsos
+               ;;
+       necv70)
+               basic_machine=v70-nec
+               os=-sysv
+               ;;
+       next | m*-next )
+               basic_machine=m68k-next
+               case $os in
+                   -nextstep* )
+                       ;;
+                   -ns2*)
+                     os=-nextstep2
+                       ;;
+                   *)
+                     os=-nextstep3
+                       ;;
+               esac
+               ;;
+       nh3000)
+               basic_machine=m68k-harris
+               os=-cxux
+               ;;
+       nh[45]000)
+               basic_machine=m88k-harris
+               os=-cxux
+               ;;
+       nindy960)
+               basic_machine=i960-intel
+               os=-nindy
+               ;;
+       mon960)
+               basic_machine=i960-intel
+               os=-mon960
+               ;;
+       nonstopux)
+               basic_machine=mips-compaq
+               os=-nonstopux
+               ;;
+       np1)
+               basic_machine=np1-gould
+               ;;
+       nv1)
+               basic_machine=nv1-cray
+               os=-unicosmp
+               ;;
+       nsr-tandem)
+               basic_machine=nsr-tandem
+               ;;
+       op50n-* | op60c-*)
+               basic_machine=hppa1.1-oki
+               os=-proelf
+               ;;
+       or32 | or32-*)
+               basic_machine=or32-unknown
+               os=-coff
+               ;;
+       os400)
+               basic_machine=powerpc-ibm
+               os=-os400
+               ;;
+       OSE68000 | ose68000)
+               basic_machine=m68000-ericsson
+               os=-ose
+               ;;
+       os68k)
+               basic_machine=m68k-none
+               os=-os68k
+               ;;
+       pa-hitachi)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       paragon)
+               basic_machine=i860-intel
+               os=-osf
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+       pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       pentium | p5 | k5 | k6 | nexgen | viac3)
+               basic_machine=i586-pc
+               ;;
+       pentiumpro | p6 | 6x86 | athlon | athlon_*)
+               basic_machine=i686-pc
+               ;;
+       pentiumii | pentium2 | pentiumiii | pentium3)
+               basic_machine=i686-pc
+               ;;
+       pentium4)
+               basic_machine=i786-pc
+               ;;
+       pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumpro-* | p6-* | 6x86-* | athlon-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentium4-*)
+               basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pn)
+               basic_machine=pn-gould
+               ;;
+       power)  basic_machine=power-ibm
+               ;;
+       ppc)    basic_machine=powerpc-unknown
+               ;;
+       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppcle | powerpclittle | ppc-le | powerpc-little)
+               basic_machine=powerpcle-unknown
+               ;;
+       ppcle-* | powerpclittle-*)
+               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppc64)  basic_machine=powerpc64-unknown
+               ;;
+       ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+               basic_machine=powerpc64le-unknown
+               ;;
+       ppc64le-* | powerpc64little-*)
+               basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ps2)
+               basic_machine=i386-ibm
+               ;;
+       pw32)
+               basic_machine=i586-unknown
+               os=-pw32
+               ;;
+       rom68k)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       rm[46]00)
+               basic_machine=mips-siemens
+               ;;
+       rtpc | rtpc-*)
+               basic_machine=romp-ibm
+               ;;
+       s390 | s390-*)
+               basic_machine=s390-ibm
+               ;;
+       s390x | s390x-*)
+               basic_machine=s390x-ibm
+               ;;
+       sa29200)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       sb1)
+               basic_machine=mipsisa64sb1-unknown
+               ;;
+       sb1el)
+               basic_machine=mipsisa64sb1el-unknown
+               ;;
+       sei)
+               basic_machine=mips-sei
+               os=-seiux
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       sh64)
+               basic_machine=sh64-unknown
+               ;;
+       sparclite-wrs | simso-wrs)
+               basic_machine=sparclite-wrs
+               os=-vxworks
+               ;;
+       sps7)
+               basic_machine=m68k-bull
+               os=-sysv2
+               ;;
+       spur)
+               basic_machine=spur-unknown
+               ;;
+       st2000)
+               basic_machine=m68k-tandem
+               ;;
+       stratus)
+               basic_machine=i860-stratus
+               os=-sysv4
+               ;;
+       sun2)
+               basic_machine=m68000-sun
+               ;;
+       sun2os3)
+               basic_machine=m68000-sun
+               os=-sunos3
+               ;;
+       sun2os4)
+               basic_machine=m68000-sun
+               os=-sunos4
+               ;;
+       sun3os3)
+               basic_machine=m68k-sun
+               os=-sunos3
+               ;;
+       sun3os4)
+               basic_machine=m68k-sun
+               os=-sunos4
+               ;;
+       sun4os3)
+               basic_machine=sparc-sun
+               os=-sunos3
+               ;;
+       sun4os4)
+               basic_machine=sparc-sun
+               os=-sunos4
+               ;;
+       sun4sol2)
+               basic_machine=sparc-sun
+               os=-solaris2
+               ;;
+       sun3 | sun3-*)
+               basic_machine=m68k-sun
+               ;;
+       sun4)
+               basic_machine=sparc-sun
+               ;;
+       sun386 | sun386i | roadrunner)
+               basic_machine=i386-sun
+               ;;
+       sv1)
+               basic_machine=sv1-cray
+               os=-unicos
+               ;;
+       symmetry)
+               basic_machine=i386-sequent
+               os=-dynix
+               ;;
+       t3e)
+               basic_machine=alphaev5-cray
+               os=-unicos
+               ;;
+       t90)
+               basic_machine=t90-cray
+               os=-unicos
+               ;;
+       tic54x | c54x*)
+               basic_machine=tic54x-unknown
+               os=-coff
+               ;;
+       tic55x | c55x*)
+               basic_machine=tic55x-unknown
+               os=-coff
+               ;;
+       tic6x | c6x*)
+               basic_machine=tic6x-unknown
+               os=-coff
+               ;;
+       tx39)
+               basic_machine=mipstx39-unknown
+               ;;
+       tx39el)
+               basic_machine=mipstx39el-unknown
+               ;;
+       toad1)
+               basic_machine=pdp10-xkl
+               os=-tops20
+               ;;
+       tower | tower-32)
+               basic_machine=m68k-ncr
+               ;;
+       tpf)
+               basic_machine=s390x-ibm
+               os=-tpf
+               ;;
+       udi29k)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       ultra3)
+               basic_machine=a29k-nyu
+               os=-sym1
+               ;;
+       v810 | necv810)
+               basic_machine=v810-nec
+               os=-none
+               ;;
+       vaxv)
+               basic_machine=vax-dec
+               os=-sysv
+               ;;
+       vms)
+               basic_machine=vax-dec
+               os=-vms
+               ;;
+       vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+       vxworks960)
+               basic_machine=i960-wrs
+               os=-vxworks
+               ;;
+       vxworks68)
+               basic_machine=m68k-wrs
+               os=-vxworks
+               ;;
+       vxworks29k)
+               basic_machine=a29k-wrs
+               os=-vxworks
+               ;;
+       w65*)
+               basic_machine=w65-wdc
+               os=-none
+               ;;
+       w89k-*)
+               basic_machine=hppa1.1-winbond
+               os=-proelf
+               ;;
+       xps | xps100)
+               basic_machine=xps100-honeywell
+               ;;
+       ymp)
+               basic_machine=ymp-cray
+               os=-unicos
+               ;;
+       z8k-*-coff)
+               basic_machine=z8k-unknown
+               os=-sim
+               ;;
+       none)
+               basic_machine=none-none
+               os=-none
+               ;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+       w89k)
+               basic_machine=hppa1.1-winbond
+               ;;
+       op50n)
+               basic_machine=hppa1.1-oki
+               ;;
+       op60c)
+               basic_machine=hppa1.1-oki
+               ;;
+       romp)
+               basic_machine=romp-ibm
+               ;;
+       rs6000)
+               basic_machine=rs6000-ibm
+               ;;
+       vax)
+               basic_machine=vax-dec
+               ;;
+       pdp10)
+               # there are many clones, so DEC is not a safe bet
+               basic_machine=pdp10-unknown
+               ;;
+       pdp11)
+               basic_machine=pdp11-dec
+               ;;
+       we32k)
+               basic_machine=we32k-att
+               ;;
+       sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+               basic_machine=sh-unknown
+               ;;
+       sh64)
+               basic_machine=sh64-unknown
+               ;;
+       sparc | sparcv8 | sparcv9 | sparcv9b)
+               basic_machine=sparc-sun
+               ;;
+       cydra)
+               basic_machine=cydra-cydrome
+               ;;
+       orion)
+               basic_machine=orion-highlevel
+               ;;
+       orion105)
+               basic_machine=clipper-highlevel
+               ;;
+       mac | mpw | mac-mpw)
+               basic_machine=m68k-apple
+               ;;
+       pmac | pmac-mpw)
+               basic_machine=powerpc-apple
+               ;;
+       *-unknown)
+               # Make sure to match an already-canonicalized machine name.
+               ;;
+       *)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+       *-digital*)
+               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               ;;
+       *-commodore*)
+               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               ;;
+       *)
+               ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+       # -solaris* is a basic system type, with this one exception.
+       -solaris1 | -solaris1.*)
+               os=`echo $os | sed -e 's|solaris1|sunos4|'`
+               ;;
+       -solaris)
+               os=-solaris2
+               ;;
+       -svr4*)
+               os=-sysv4
+               ;;
+       -unixware*)
+               os=-sysv4.2uw
+               ;;
+       -gnu/linux*)
+               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+               ;;
+       # First accept the basic system types.
+       # The portable systems comes first.
+       # Each alternative MUST END IN A *, to match a version number.
+       # -sysv* is not here because it comes later, after sysvr4.
+       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+             | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+             | -aos* \
+             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+             | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+             | -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* \
+             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+             | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+             | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+             | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+             | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+             | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+             | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*)
+       # Remember, each alternative MUST END IN *, to match a version number.
+               ;;
+       -qnx*)
+               case $basic_machine in
+                   x86-* | i*86-*)
+                       ;;
+                   *)
+                       os=-nto$os
+                       ;;
+               esac
+               ;;
+       -nto-qnx*)
+               ;;
+       -nto*)
+               os=`echo $os | sed -e 's|nto|nto-qnx|'`
+               ;;
+       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+             | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+             | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+               ;;
+       -mac*)
+               os=`echo $os | sed -e 's|mac|macos|'`
+               ;;
+       -linux-dietlibc)
+               os=-linux-dietlibc
+               ;;
+       -linux*)
+               os=`echo $os | sed -e 's|linux|linux-gnu|'`
+               ;;
+       -sunos5*)
+               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               ;;
+       -sunos6*)
+               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               ;;
+       -opened*)
+               os=-openedition
+               ;;
+        -os400*)
+               os=-os400
+               ;;
+       -wince*)
+               os=-wince
+               ;;
+       -osfrose*)
+               os=-osfrose
+               ;;
+       -osf*)
+               os=-osf
+               ;;
+       -utek*)
+               os=-bsd
+               ;;
+       -dynix*)
+               os=-bsd
+               ;;
+       -acis*)
+               os=-aos
+               ;;
+       -atheos*)
+               os=-atheos
+               ;;
+       -syllable*)
+               os=-syllable
+               ;;
+       -386bsd)
+               os=-bsd
+               ;;
+       -ctix* | -uts*)
+               os=-sysv
+               ;;
+       -nova*)
+               os=-rtmk-nova
+               ;;
+       -ns2 )
+               os=-nextstep2
+               ;;
+       -nsk*)
+               os=-nsk
+               ;;
+       # Preserve the version number of sinix5.
+       -sinix5.*)
+               os=`echo $os | sed -e 's|sinix|sysv|'`
+               ;;
+       -sinix*)
+               os=-sysv4
+               ;;
+        -tpf*)
+               os=-tpf
+               ;;
+       -triton*)
+               os=-sysv3
+               ;;
+       -oss*)
+               os=-sysv3
+               ;;
+       -svr4)
+               os=-sysv4
+               ;;
+       -svr3)
+               os=-sysv3
+               ;;
+       -sysvr4)
+               os=-sysv4
+               ;;
+       # This must come after -sysvr4.
+       -sysv*)
+               ;;
+       -ose*)
+               os=-ose
+               ;;
+       -es1800*)
+               os=-ose
+               ;;
+       -xenix)
+               os=-xenix
+               ;;
+       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+               os=-mint
+               ;;
+       -aros*)
+               os=-aros
+               ;;
+       -kaos*)
+               os=-kaos
+               ;;
+       -none)
+               ;;
+       *)
+               # Get rid of the `-' at the beginning of $os.
+               os=`echo $os | sed 's/[^-]*-//'`
+               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+       *-acorn)
+               os=-riscix1.2
+               ;;
+       arm*-rebel)
+               os=-linux
+               ;;
+       arm*-semi)
+               os=-aout
+               ;;
+    c4x-* | tic4x-*)
+        os=-coff
+        ;;
+       # This must come before the *-dec entry.
+       pdp10-*)
+               os=-tops20
+               ;;
+       pdp11-*)
+               os=-none
+               ;;
+       *-dec | vax-*)
+               os=-ultrix4.2
+               ;;
+       m68*-apollo)
+               os=-domain
+               ;;
+       i386-sun)
+               os=-sunos4.0.2
+               ;;
+       m68000-sun)
+               os=-sunos3
+               # This also exists in the configure program, but was not the
+               # default.
+               # os=-sunos4
+               ;;
+       m68*-cisco)
+               os=-aout
+               ;;
+       mips*-cisco)
+               os=-elf
+               ;;
+       mips*-*)
+               os=-elf
+               ;;
+       or32-*)
+               os=-coff
+               ;;
+       *-tti)  # must be before sparc entry or we get the wrong os.
+               os=-sysv3
+               ;;
+       sparc-* | *-sun)
+               os=-sunos4.1.1
+               ;;
+       *-be)
+               os=-beos
+               ;;
+       *-ibm)
+               os=-aix
+               ;;
+       *-wec)
+               os=-proelf
+               ;;
+       *-winbond)
+               os=-proelf
+               ;;
+       *-oki)
+               os=-proelf
+               ;;
+       *-hp)
+               os=-hpux
+               ;;
+       *-hitachi)
+               os=-hiux
+               ;;
+       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+               os=-sysv
+               ;;
+       *-cbm)
+               os=-amigaos
+               ;;
+       *-dg)
+               os=-dgux
+               ;;
+       *-dolphin)
+               os=-sysv3
+               ;;
+       m68k-ccur)
+               os=-rtu
+               ;;
+       m88k-omron*)
+               os=-luna
+               ;;
+       *-next )
+               os=-nextstep
+               ;;
+       *-sequent)
+               os=-ptx
+               ;;
+       *-crds)
+               os=-unos
+               ;;
+       *-ns)
+               os=-genix
+               ;;
+       i370-*)
+               os=-mvs
+               ;;
+       *-next)
+               os=-nextstep3
+               ;;
+       *-gould)
+               os=-sysv
+               ;;
+       *-highlevel)
+               os=-bsd
+               ;;
+       *-encore)
+               os=-bsd
+               ;;
+       *-sgi)
+               os=-irix
+               ;;
+       *-siemens)
+               os=-sysv4
+               ;;
+       *-masscomp)
+               os=-rtu
+               ;;
+       f30[01]-fujitsu | f700-fujitsu)
+               os=-uxpv
+               ;;
+       *-rom68k)
+               os=-coff
+               ;;
+       *-*bug)
+               os=-coff
+               ;;
+       *-apple)
+               os=-macos
+               ;;
+       *-atari*)
+               os=-mint
+               ;;
+       *)
+               os=-none
+               ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+       *-unknown)
+               case $os in
+                       -riscix*)
+                               vendor=acorn
+                               ;;
+                       -sunos*)
+                               vendor=sun
+                               ;;
+                       -aix*)
+                               vendor=ibm
+                               ;;
+                       -beos*)
+                               vendor=be
+                               ;;
+                       -hpux*)
+                               vendor=hp
+                               ;;
+                       -mpeix*)
+                               vendor=hp
+                               ;;
+                       -hiux*)
+                               vendor=hitachi
+                               ;;
+                       -unos*)
+                               vendor=crds
+                               ;;
+                       -dgux*)
+                               vendor=dg
+                               ;;
+                       -luna*)
+                               vendor=omron
+                               ;;
+                       -genix*)
+                               vendor=ns
+                               ;;
+                       -mvs* | -opened*)
+                               vendor=ibm
+                               ;;
+                       -os400*)
+                               vendor=ibm
+                               ;;
+                       -ptx*)
+                               vendor=sequent
+                               ;;
+                       -tpf*)
+                               vendor=ibm
+                               ;;
+                       -vxsim* | -vxworks* | -windiss*)
+                               vendor=wrs
+                               ;;
+                       -aux*)
+                               vendor=apple
+                               ;;
+                       -hms*)
+                               vendor=hitachi
+                               ;;
+                       -mpw* | -macos*)
+                               vendor=apple
+                               ;;
+                       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+                               vendor=atari
+                               ;;
+                       -vos*)
+                               vendor=stratus
+                               ;;
+               esac
+               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               ;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/configure b/configure
new file mode 100755 (executable)
index 0000000..e2f2914
--- /dev/null
+++ b/configure
@@ -0,0 +1,8542 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.67 for nettle 2.4.
+#
+# Report bugs to <nettle-bugs@lists.lysator.liu.se>.
+#
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+# Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+       expr "X$arg" : "X\\(.*\\)$as_nl";
+       arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""       $as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+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
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+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"
+  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"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+        /*)
+          for as_base in sh bash ksh sh5; do
+            # Try only shells that exist, to save several forks.
+            as_shell=$as_dir/$as_base
+            if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+                   { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+                  if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+          done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+             { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+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+"$@"}
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf@gnu.org and
+$0: nettle-bugs@lists.lysator.liu.se about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)[^/].*/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+      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"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# 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.
+as_fn_error ()
+{
+  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: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+           s//\1/
+           q
+         }
+         /^X\/\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\/\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO 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'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  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; }
+
+  # 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).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='        ';;     # ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='        ';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... 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'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  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
+
+# 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'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# 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`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='nettle'
+PACKAGE_TARNAME='nettle'
+PACKAGE_VERSION='2.4'
+PACKAGE_STRING='nettle 2.4'
+PACKAGE_BUGREPORT='nettle-bugs@lists.lysator.liu.se'
+PACKAGE_URL=''
+
+ac_unique_file="arcfour.c"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='LTLIBOBJS
+BENCH_LIBS
+OPENSSL_LIBFLAGS
+IF_SHARED
+IF_HOGWEED
+LIBOBJS
+ALLOCA
+EGREP
+GREP
+CPP
+M4
+LIBHOGWEED_LIBS
+LIBHOGWEED_LINK
+LIBHOGWEED_FILE
+LIBHOGWEED_SONAME
+LIBHOGWEED_FORLINK
+LIBHOGWEED_MINOR
+LIBHOGWEED_MAJOR
+LIBNETTLE_LIBS
+LIBNETTLE_LINK
+LIBNETTLE_FILE
+LIBNETTLE_SONAME
+LIBNETTLE_FORLINK
+LIBNETTLE_MINOR
+LIBNETTLE_MAJOR
+SHLIBCFLAGS
+ASM_ALIGN_LOG
+ASM_MARK_NOEXEC_STACK
+ASM_TYPE_FUNCTION
+ASM_ELF_STYLE
+ASM_SYMBOL_PREFIX
+CCPIC_MAYBE
+CCPIC
+DEP_PROCESS
+DEP_FLAGS
+DEP_INCLUDE
+MKDIR_P
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+OBJDUMP
+NM
+RANLIB
+SET_MAKE
+CXX_TESTS
+ac_ct_CXX
+CXXFLAGS
+CXX
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+with_include_path
+with_lib_path
+enable_public_key
+enable_assembler
+enable_shared
+enable_pic
+enable_openssl
+enable_gcov
+enable_dependency_tracking
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CXX
+CXXFLAGS
+CCC
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    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"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+        ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    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"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+        ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    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"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+        ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    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"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+        ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --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"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # 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'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $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}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  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" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in  exec_prefix prefix bindir sbindir libexecdir datarootdir \
+               datadir sysconfdir sharedstatedir localstatedir includedir \
+               oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+               libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  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'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+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
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+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"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_myself" : 'X\(//\)[^/]' \| \
+        X"$as_myself" : 'X\(//\)$' \| \
+        X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)[^/].*/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+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"
+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"
+       pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+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 nettle 2.4 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --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
+      --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
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/nettle]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of nettle 2.4:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --disable-public-key    Disable public key algorithms
+  --disable-assembler     Disable assembler code
+  --enable-shared         Build a shared library
+  --disable-pic           Do not try to compile library files as position
+                          independent code
+  --disable-openssl       Do not include openssl glue in the benchmark program
+  --enable-gcov           Instrument for gcov (requires a modern gcc)
+  --disable-dependency-tracking
+                          Disable dependency tracking. Dependency tracking
+                          doesn't work with BSD make
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-include-path     A colon-separated list of directories to search for
+                          include files
+  --with-lib-path         A colon-separated list of directories to search for
+                          libraries
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  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    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CPP         C preprocessor
+
+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 <nettle-bugs@lists.lysator.liu.se>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+nettle configure 2.4
+generated by GNU Autoconf 2.67
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+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_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+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;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+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_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+        test -z "$ac_cxx_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+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;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+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_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+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;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+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 eval "test \"\${$3+set}\"" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+        return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+           return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+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;}
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { 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; } && { ac_try='./conftest$ac_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 :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+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;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+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 eval "test \"\${$3+set}\"" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+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;}
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if test "$cross_compiling" = yes; then
+    # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid; break
+else
+  as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+                       if test $ac_lo -le $ac_mid; then
+                         ac_lo= ac_hi=
+                         break
+                       fi
+                       as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=$ac_mid; break
+else
+  as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+                       if test $ac_mid -le $ac_hi; then
+                         ac_lo= ac_hi=
+                         break
+                       fi
+                       as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid
+else
+  as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+  else
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    return 1;
+  if (($2) < 0)
+    {
+      long int i = longval ();
+      if (i != ($2))
+       return 1;
+      fprintf (f, "%ld", i);
+    }
+  else
+    {
+      unsigned long int i = ulongval ();
+      if (i != ($2))
+       return 1;
+      fprintf (f, "%lu", i);
+    }
+  /* Do not output a trailing newline, as this causes \r\n confusion
+     on some platforms.  */
+  return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+  ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+  fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval "test \"\${$3+set}\"" = set; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval "test \"\${$3+set}\"" = set; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+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; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&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;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$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;}
+( $as_echo "## ----------------------------------------------- ##
+## Report this to nettle-bugs@lists.lysator.liu.se ##
+## ----------------------------------------------- ##"
+     ) | 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 eval "test \"\${$3+set}\"" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+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;}
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { 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>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+        test "$cross_compiling" = yes ||
+        $as_test_x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # 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;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+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 eval "test \"\${$3+set}\"" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* 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 $2 ();
+/* The GNU C library 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_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+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;}
+
+} # ac_fn_c_check_func
+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 nettle $as_me 2.4, which was
+generated by GNU Autoconf 2.67.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+       ac_must_keep_next=false # Got value, back to normal.
+      else
+       case $ac_arg in
+         *=* | --config-cache | -C | -disable-* | --disable-* \
+         | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+         | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+         | -with-* | --with-* | -without-* | --without-* | --x)
+           case "$ac_configure_args0 " in
+             "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+           esac
+           ;;
+         -* ) ac_must_keep_next=true ;;
+       esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+       "s/'\''/'\''\\\\'\'''\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+       eval ac_val=\$$ac_var
+       case $ac_val in
+       *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+       esac
+       $as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # 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
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  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" \
+      || { { $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.  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
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+       # differences in whitespace do not lead to failure.
+       ac_old_val_w=`echo x $ac_old_val`
+       ac_new_val_w=`echo x $ac_new_val`
+       if test "$ac_old_val_w" != "$ac_new_val_w"; then
+         { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+         ac_cache_corrupted=:
+       else
+         { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+         eval $ac_var=\$ac_old_val
+       fi
+       { $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+       { $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$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
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+# Needed to stop autoconf from looking for files in parent directories.
+ac_aux_dir=
+for ac_dir in . "$srcdir"/.; 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\"/." "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+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.
+
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+
+LIBNETTLE_MAJOR=4
+LIBNETTLE_MINOR=3
+
+LIBHOGWEED_MAJOR=2
+LIBHOGWEED_MINOR=1
+
+# 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_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 :
+  $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
+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
+
+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 ;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+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 :
+  $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
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+# Command line options
+
+# Check whether --with-include-path was given.
+if test "${with_include_path+set}" = set; then :
+  withval=$with_include_path;
+else
+  with_include_path=''
+fi
+
+
+if test x$with_include_path != x ; then
+  CPPFLAGS="$CPPFLAGS -I`echo $with_include_path | sed 's/:/ -I/g'`"
+fi
+
+
+# Check whether --with-lib-path was given.
+if test "${with_lib_path+set}" = set; then :
+  withval=$with_lib_path;
+else
+  with_lib_path=''
+fi
+
+
+if test x$with_lib_path != x ; then
+  LDFLAGS="$LDFLAGS -L`echo $with_lib_path | sed 's/:/ -L/g'`"
+fi
+
+# Check whether --enable-public-key was given.
+if test "${enable_public_key+set}" = set; then :
+  enableval=$enable_public_key;
+else
+  enable_public_key=yes
+fi
+
+
+# Check whether --enable-assembler was given.
+if test "${enable_assembler+set}" = set; then :
+  enableval=$enable_assembler;
+else
+  enable_assembler=yes
+fi
+
+
+# Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+  enableval=$enable_shared;
+else
+  enable_shared=no
+fi
+
+
+# Check whether --enable-pic was given.
+if test "${enable_pic+set}" = set; then :
+  enableval=$enable_pic;
+else
+  enable_pic=yes
+fi
+
+
+# Check whether --enable-openssl was given.
+if test "${enable_openssl+set}" = set; then :
+  enableval=$enable_openssl;
+else
+  enable_openssl=yes
+fi
+
+
+# Check whether --enable-gcov was given.
+if test "${enable_gcov+set}" = set; then :
+  enableval=$enable_gcov;
+else
+  enable_gcov=no
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -R flag" >&5
+$as_echo_n "checking for -R flag... " >&6; }
+RPATHFLAG=''
+case "$host_os" in
+  osf1*)               RPATHFLAG="-rpath " ;;
+  irix6.*|irix5.*)     RPATHFLAG="-rpath " ;;
+  solaris*)
+    if test "$TCC" = "yes"; then
+      # tcc doesn't know about -R
+      RPATHFLAG="-Wl,-R,"
+    else
+      RPATHFLAG=-R
+    fi
+    ;;
+  linux*)              RPATHFLAG="-Wl,-rpath," ;;
+  *)                   RPATHFLAG="" ;;
+esac
+
+if test x$RPATHFLAG = x ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: using $RPATHFLAG" >&5
+$as_echo "using $RPATHFLAG" >&6; }
+fi
+
+RPATH_CANDIDATE_REAL_DIRS=''
+RPATH_CANDIDATE_DIRS=''
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Searching for libraries" >&5
+$as_echo "Searching for libraries" >&6; }
+
+for d in `echo $with_lib_path | sed 's/:/ /g'` \
+    `echo $exec_prefix | sed "s@^NONE@$prefix/lib@g" | sed "s@^NONE@$ac_default_prefix/lib@g"` \
+    /usr/local/lib /sw/local/lib /sw/lib \
+    /usr/gnu/lib /opt/gnu/lib /sw/gnu/lib /usr/freeware/lib /usr/pkg/lib ; do
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking $d" >&5
+$as_echo_n "checking $d... " >&6; }
+ac_exists=no
+if test -d "$d/." ; then
+  ac_real_dir=`cd $d && pwd`
+  if test -n "$ac_real_dir" ; then
+    ac_exists=yes
+    for old in RPATH_CANDIDATE_REAL_DIRS ; do
+      ac_found=no
+      if test x$ac_real_dir = x$old ; then
+        ac_found=yes;
+       break;
+      fi
+    done
+    if test $ac_found = yes ; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: already added" >&5
+$as_echo "already added" >&6; }
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: added" >&5
+$as_echo "added" >&6; }
+      # LDFLAGS="$LDFLAGS -L $d"
+      RPATH_CANDIDATE_REAL_DIRS="$ac_real_dir $RPATH_CANDIDATE_REAL_DIRS"
+      RPATH_CANDIDATE_DIRS="$d $RPATH_CANDIDATE_DIRS"
+    fi
+  fi
+fi
+if test $ac_exists = no ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+fi
+
+done
+
+
+# Checks for programs.
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+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 :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # 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
+    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
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+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 :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # 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
+    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
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  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
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+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 :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # 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
+    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
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+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 :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+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 test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $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
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  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_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # 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
+    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
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+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_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # 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
+    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
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  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
+    CC=$ac_ct_CC
+  fi
+fi
+
+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 ; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  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.  */
+
+int
+main ()
+{
+
+  ;
+  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"
+# 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 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:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+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_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+       ;;
+    [ab].out )
+       # We found the default executable, but exeext='' is most
+       # certainly right.
+       break;;
+    *.* )
+       if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+       then :; else
+          ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+       fi
+       # We set ac_cv_exeext here because the later test for it is not
+       # safe: cross compilers may not add the suffix if given an `-o'
+       # argument, so we may need to know it at that point already.
+       # Even if this section looks crufty: it has the advantage of
+       # actually working.
+       break;;
+    * )
+       break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+if test -z "$ac_file"; then :
+  { $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_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
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $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"
+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; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+         break;;
+    * ) break;;
+  esac
+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 ; }
+fi
+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 :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+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_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $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_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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+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 :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+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 :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+        CFLAGS="-g"
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+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 :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* 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);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+       -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# When $CC foo.c -o foo creates both foo and foo.exe, autoconf picks
+# up the foo.exe and sets exeext to .exe. That is correct for cygwin,
+# which has some kind of magic link from foo to foo.exe, but not for
+# rntcl. A better check for the cygwin case would check if the
+# contents of foo and foo.exe are equal; in the rntcl case, foo is a
+# sh script, and foo.exe is a windows executable.
+
+if test "x$CC" = xrntcl ; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: Compiling with rntcl; clearing EXEEXT and disabling assembler" >&5
+$as_echo "$as_me: Compiling with rntcl; clearing EXEEXT and disabling assembler" >&6;}
+    ac_exeext=''
+    ac_cv_exeext=''
+    EXEEXT=''
+    enable_assembler=no
+fi
+
+# Used by the testsuite only
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  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_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # 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
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    $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
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+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_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    $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_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  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
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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_cxx_compiler_gnu+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+        CXXFLAGS="-g"
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  CXX_TESTS='cxx-test$(EXEEXT)'
+else
+  CXX_TESTS=''
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$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 eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+       @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# 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;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+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_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
+    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
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+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 :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_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
+    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
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  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
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}nm", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nm; 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_NM+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NM"; then
+  ac_cv_prog_NM="$NM" # 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
+    ac_cv_prog_NM="${ac_tool_prefix}nm"
+    $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
+NM=$ac_cv_prog_NM
+if test -n "$NM"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NM" >&5
+$as_echo "$NM" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NM"; then
+  ac_ct_NM=$NM
+  # Extract the first word of "nm", so it can be a program name with args.
+set dummy nm; 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_NM+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_NM"; then
+  ac_cv_prog_ac_ct_NM="$ac_ct_NM" # 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
+    ac_cv_prog_ac_ct_NM="nm"
+    $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_NM=$ac_cv_prog_ac_ct_NM
+if test -n "$ac_ct_NM"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NM" >&5
+$as_echo "$ac_ct_NM" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_NM" = x; then
+    NM="strings"
+  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
+    NM=$ac_ct_NM
+  fi
+else
+  NM="$ac_cv_prog_NM"
+fi
+
+# Used only for the GNU-stack configure test.
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+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 :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OBJDUMP"; then
+  ac_cv_prog_OBJDUMP="$OBJDUMP" # 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
+    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
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+  ac_ct_OBJDUMP=$OBJDUMP
+  # Extract the first word of "objdump", so it can be a program name with args.
+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 :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OBJDUMP"; then
+  ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # 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
+    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
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OBJDUMP" = x; then
+    OBJDUMP="false"
+  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
+    OBJDUMP=$ac_ct_OBJDUMP
+  fi
+else
+  OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+
+if test "x$ac_cv_prog_cc_stdc" = xno ; then
+  as_fn_error $? "the C compiler doesn't handle ANSI-C" "$LINENO" 5  #'
+fi
+
+# 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:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $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 :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # 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 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.
+           :
+         elif test $ac_prog = install &&
+           grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # program-specific install script used by HP pwplus--don't use.
+           :
+         else
+           rm -rf conftest.one conftest.two conftest.dir
+           echo one > conftest.one
+           echo two > conftest.two
+           mkdir conftest.dir
+           if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+             test -s conftest.one && test -s conftest.two &&
+             test -s conftest.dir/conftest.one &&
+             test -s conftest.dir/conftest.two
+           then
+             ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+             break 3
+           fi
+         fi
+       fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL 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.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+# According to the autoconf manual, needs install-sh from
+# autoconf-2.60 or automake-1.10 to avoid races.
+{ $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 :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+  IFS=$as_save_IFS
+  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
+          case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+            'mkdir (GNU coreutils) '* | \
+            'mkdir (coreutils) '* | \
+            'mkdir (fileutils) '4.1*)
+              ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+              break 3;;
+          esac
+        done
+       done
+  done
+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
+    # As a last resort, use the slow shell script.  Don't cache a
+    # 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.
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+
+# Check whether --enable-dependency_tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+  enableval=$enable_dependency_tracking;
+else
+  enable_dependency_tracking=yes
+fi
+
+
+DEP_FLAGS=''
+DEP_PROCESS='true'
+if test x$enable_dependency_tracking = xyes ; then
+  if test x$GCC = xyes ; then
+    gcc_version=`gcc --version | head -1`
+    case "$gcc_version" in
+      2.*|*[!0-9.]2.*)
+        enable_dependency_tracking=no
+        { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Dependency tracking disabled, gcc-3.x is needed" >&5
+$as_echo "$as_me: WARNING: Dependency tracking disabled, gcc-3.x is needed" >&2;}
+      ;;
+      *)
+        DEP_FLAGS='-MT $@ -MD -MP -MF $@.d'
+        DEP_PROCESS='true'
+      ;;
+    esac
+  else
+    enable_dependency_tracking=no
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Dependency tracking disabled" >&5
+$as_echo "$as_me: WARNING: Dependency tracking disabled" >&2;}
+  fi
+fi
+
+if test x$enable_dependency_tracking = xyes ; then
+  DEP_INCLUDE='include '
+else
+  DEP_INCLUDE='# '
+fi
+
+
+
+
+
+if test x$enable_dependency_tracking = xyes ; then
+  # Since the makefiles use include to get the dependency files, we must
+  # make sure that the files exist. We generate some more files than are
+  # actually needed.
+
+  ac_config_commands="$ac_config_commands dummy-dep-files"
+
+fi
+
+# Figure out ABI. Currently, configurable only by setting CFLAGS.
+ABI=standard
+
+case "$host_cpu" in
+  x86_64 | amd64)
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#if defined(__x86_64__) || defined(__arch64__)
+#error 64-bit x86
+#endif
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+      ABI=32
+
+else
+
+      ABI=64
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    ;;
+  *sparc*)
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#if defined(__sparcv9) || defined(__arch64__)
+#error 64-bit sparc
+#endif
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+      ABI=32
+
+else
+
+      ABI=64
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    ;;
+esac
+
+if test "x$ABI" != xstandard ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: Compiler uses $ABI-bit ABI. To change, set CC." >&5
+$as_echo "$as_me: Compiler uses $ABI-bit ABI. To change, set CC." >&6;}
+  if test "$libdir" = '${exec_prefix}/lib' ; then
+    # Try setting a better default
+    case "$host_cpu:$host_os:$ABI" in
+      *:solaris*:32|*:sunos*:32)
+       libdir='${exec_prefix}/lib'
+       ;;
+      *:solaris*:64|*:sunos*:64)
+       libdir='${exec_prefix}/lib/64'
+       ;;
+      # Linux conventions are a mess... According to the Linux File
+      # Hierarchy Standard, all architectures except IA64 puts 32-bit
+      # libraries in lib, and 64-bit in lib64. Some distributions,
+      # e.g., Fedora and Gentoo, adhere to this standard, while at
+      # least Debian has decided to put 64-bit libraries in lib and
+      # 32-bit libraries in lib32.
+
+      # We try to figure out the convention, except if we're cross
+      # compiling. We use lib${ABI} if /usr/lib${ABI} exists and
+      # appears to not be a symlink to a different name.
+      *:linux*:32|*:linux*:64)
+       if test "$cross_compiling" = yes ; then
+          { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cross compiling for linux. Can't guess if libraries go in lib${ABI} or lib." >&5
+$as_echo "$as_me: WARNING: Cross compiling for linux. Can't guess if libraries go in lib${ABI} or lib." >&2;};         else
+         # The dash builtin pwd tries to be "helpful" and remember
+         # symlink names. Use -P option, and hope it's portable enough.
+         test -d /usr/lib${ABI} \
+           && (cd /usr/lib${ABI} && pwd -P | grep >/dev/null "/lib${ABI}"'$') \
+           && libdir='${exec_prefix}/'"lib${ABI}"
+       fi
+       ;;
+      # On freebsd, it seems 32-bit libraries are in lib32,
+      # and 64-bit in lib. Don't know about "kfreebsd", does
+      # it follow the Linux fhs conventions?
+      *:freebsd*:32)
+       libdir='${exec_prefix}/lib32'
+       ;;
+      *:freebsd*:64)
+       libdir='${exec_prefix}/lib'
+       ;;
+      *)
+        { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Don't know where to install $ABI-bit libraries on this system." >&5
+$as_echo "$as_me: WARNING: Don't know where to install $ABI-bit libraries on this system." >&2;};
+    esac
+    { $as_echo "$as_me:${as_lineno-$LINENO}: Libraries to be installed in $libdir." >&5
+$as_echo "$as_me: Libraries to be installed in $libdir." >&6;}
+  fi
+fi
+
+# Select assembler code
+asm_path=
+if test "x$enable_assembler" = xyes ; then
+  case "$host_cpu" in
+    i?86* | k[5-8]* | pentium* | athlon)
+      asm_path=x86
+      ;;
+    x86_64 | amd64)
+      if test "$ABI" = 64 ; then
+       asm_path=x86_64
+      else
+       asm_path=x86
+      fi
+      ;;
+    *sparc*)
+      if test "$ABI" = 64 ; then
+       asm_path=sparc64
+      else
+       asm_path=sparc32
+      fi
+      ;;
+    *)
+      enable_assembler=no
+      ;;
+  esac
+fi
+# echo "enable_assembler: $enable_assembler, asm_path: $asm_path"
+
+if test "x$enable_assembler" = xyes ; then
+  if test -n "$asm_path"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: Looking for assembler files in $asm_path/." >&5
+$as_echo "$as_me: Looking for assembler files in $asm_path/." >&6;}
+    found=no
+    for tmp_f in aes-encrypt-internal.asm aes-decrypt-internal.asm \
+                arcfour-crypt.asm camellia-crypt-internal.asm \
+                md5-compress.asm memxor.asm \
+                serpent-encrypt.asm serpent-decrypt.asm \
+                sha1-compress.asm machine.m4; do
+#       echo "Looking for $srcdir/$asm_path/$tmp_f"
+      if test -f "$srcdir/$asm_path/$tmp_f"; then
+#        echo found
+        found=yes
+        ac_config_links="$ac_config_links $tmp_f:$asm_path/$tmp_f"
+
+      fi
+    done
+    if test "$found" = no; then
+      enable_assembler=no
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No assembler files found." >&5
+$as_echo "$as_me: WARNING: No assembler files found." >&2;}
+    fi
+  fi
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking CCPIC" >&5
+$as_echo_n "checking CCPIC... " >&6; }
+if test "${lsh_cv_sys_ccpic+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  if test -z "$CCPIC" ; then
+    if test "$GCC" = yes ; then
+      case "$host_os" in
+       bsdi4.*)        CCPIC="-fPIC" ;;
+       bsdi*)          CCPIC="" ;;
+       darwin*)        CCPIC="-fPIC" ;;
+       # Could also use -fpic, depending on the number of symbol references
+       solaris*)       CCPIC="-fPIC" ;;
+       cygwin*)        CCPIC="" ;;
+       mingw32*)       CCPIC="" ;;
+       *)              CCPIC="-fpic" ;;
+      esac
+    else
+      case "$host_os" in
+       darwin*)        CCPIC="-fPIC" ;;
+        irix*)         CCPIC="-share" ;;
+       hpux*)          CCPIC="+z"; ;;
+       *freebsd*)      CCPIC="-fpic" ;;
+       sco*|sysv4.*)   CCPIC="-KPIC -dy -Bdynamic" ;;
+       solaris*)       CCPIC="-KPIC -Bdynamic" ;;
+       winnt*)         CCPIC="-shared" ;;
+       *)              CCPIC="" ;;
+      esac
+    fi
+  fi
+  OLD_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $CCPIC"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+exit(0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  lsh_cv_sys_ccpic="$CCPIC"
+else
+  lsh_cv_sys_ccpic=''
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS="$OLD_CFLAGS"
+
+fi
+
+CCPIC="$lsh_cv_sys_ccpic"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CCPIC" >&5
+$as_echo "$CCPIC" >&6; }
+
+
+SHLIBCFLAGS="$CCPIC"
+
+case "$host_os" in
+  mingw32*)
+    LIBNETTLE_FORLINK='libnettle-$(LIBNETTLE_MAJOR)-$(LIBNETTLE_MINOR).dll'
+    LIBNETTLE_SONAME=''
+    LIBNETTLE_FILE='libnettle.dll.a'
+    LIBNETTLE_LINK='$(CC) $(LDFLAGS) -shared -Wl,--out-implib=$(LIBNETTLE_FILE) -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive'
+    LIBNETTLE_LIBS='-Wl,--no-whole-archive $(LIBS)'
+
+    LIBHOGWEED_FORLINK='libhogweed-$(LIBHOGWEED_MAJOR)-$(LIBHOGWEED_MINOR).dll'
+    LIBHOGWEED_SONAME=''
+    LIBHOGWEED_FILE='libhogweed.dll.a'
+    LIBHOGWEED_LINK='$(CC) $(LDFLAGS) -shared -Wl,--out-implib=$(LIBHOGWEED_FILE) -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive'
+    LIBHOGWEED_LIBS='-Wl,--no-whole-archive $(LIBS) libnettle.dll.a'
+    ;;
+  cygwin*)
+    LIBNETTLE_FORLINK='cygnettle-$(LIBNETTLE_MAJOR)-$(LIBNETTLE_MINOR).dll'
+    LIBNETTLE_SONAME=''
+    LIBNETTLE_FILE='libnettle.dll.a'
+    LIBNETTLE_LINK='$(CC) $(LDFLAGS) -shared -Wl,--out-implib=$(LIBNETTLE_FILE) -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive'
+    LIBNETTLE_LIBS='-Wl,--no-whole-archive $(LIBS)'
+
+    LIBHOGWEED_FORLINK='cyghogweed-$(LIBHOGWEED_MAJOR)-$(LIBHOGWEED_MINOR).dll'
+    LIBHOGWEED_SONAME=''
+    LIBHOGWEED_FILE='libhogweed.dll.a'
+    LIBHOGWEED_LINK='$(CC) $(LDFLAGS) -shared -Wl,--out-implib=$(LIBHOGWEED_FILE) -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive'
+    LIBHOGWEED_LIBS='-Wl,--no-whole-archive $(LIBS)'
+    ;;
+  darwin*)
+    LIBNETTLE_FORLINK=libnettle.dylib
+    LIBNETTLE_SONAME='$(LIBNETTLE_FORLINK).$(LIBNETTLE_MAJOR)'
+    LIBNETTLE_FILE='$(LIBNETTLE_SONAME).$(LIBNETTLE_MINOR)'
+    LIBNETTLE_LINK='$(CC) -dynamiclib $(LDFLAGS)'
+    LIBNETTLE_LIBS=''
+
+    LIBHOGWEED_FORLINK=libhogweed.dylib
+    LIBHOGWEED_SONAME='$(LIBHOGWEED_FORLINK).$(LIBHOGWEED_MAJOR)'
+    LIBHOGWEED_FILE='$(LIBHOGWEED_SONAME).$(LIBHOGWEED_MINOR)'
+    LIBHOGWEED_LINK='$(CC) -dynamiclib $(LDFLAGS)'
+    LIBHOGWEED_LIBS=''
+    ;;
+  solaris*)
+    # Sun's ld uses -h to set the soname, and this option is passed
+    # through by both Sun's compiler and gcc. Might not work with GNU
+    # ld, but it's unusual to use GNU ld on Solaris.
+    LIBNETTLE_FORLINK=libnettle.so
+    LIBNETTLE_SONAME='$(LIBNETTLE_FORLINK).$(LIBNETTLE_MAJOR)'
+    LIBNETTLE_FILE='$(LIBNETTLE_SONAME).$(LIBNETTLE_MINOR)'
+    LIBNETTLE_LINK='$(CC) $(LDFLAGS) -G -h $(LIBNETTLE_SONAME)'
+    LIBNETTLE_LIBS=''
+
+    LIBHOGWEED_FORLINK=libhogweed.so
+    LIBHOGWEED_SONAME='$(LIBHOGWEED_FORLINK).$(LIBHOGWEED_MAJOR)'
+    LIBHOGWEED_FILE='$(LIBHOGWEED_SONAME).$(LIBHOGWEED_MINOR)'
+    LIBHOGWEED_LINK='$(CC) $(LDFLAGS) -L. -G -h $(LIBHOGWEED_SONAME)'
+    LIBHOGWEED_LIBS='-lnettle -lgmp'
+    ;;
+  *)
+    LIBNETTLE_FORLINK=libnettle.so
+    LIBNETTLE_SONAME='$(LIBNETTLE_FORLINK).$(LIBNETTLE_MAJOR)'
+    LIBNETTLE_FILE='$(LIBNETTLE_SONAME).$(LIBNETTLE_MINOR)'
+    LIBNETTLE_LINK='$(CC) $(LDFLAGS) -shared -Wl,-soname=$(LIBNETTLE_SONAME)'
+    LIBNETTLE_LIBS=''
+
+    LIBHOGWEED_FORLINK=libhogweed.so
+    LIBHOGWEED_SONAME='$(LIBHOGWEED_FORLINK).$(LIBHOGWEED_MAJOR)'
+    LIBHOGWEED_FILE='$(LIBHOGWEED_SONAME).$(LIBHOGWEED_MINOR)'
+    LIBHOGWEED_LINK='$(CC) $(LDFLAGS) -L. -shared -Wl,-soname=$(LIBHOGWEED_SONAME)'
+    # Requested by debian, to make linking with only -lhogweed work
+    # (does not work in general, e.g., with static linking all of
+    # -lhogweed -lgmp -lnettle are still required). Also makes dlopen
+    # of libhogweed.so work, without having to use RTLD_GLOBAL.
+    # Depends on -L. above, to locate nettle.so.
+    LIBHOGWEED_LIBS='-lnettle -lgmp'
+    ;;
+esac
+
+if test "x$enable_pic" = xyes; then
+  CCPIC_MAYBE="$CCPIC"
+else
+  CCPIC_MAYBE=''
+fi
+
+
+ASM_SYMBOL_PREFIX=''
+ASM_ELF_STYLE='no'
+ASM_TYPE_FUNCTION=''
+ASM_MARK_NOEXEC_STACK=''
+ASM_ALIGN_LOG=''
+
+if test x$enable_assembler = xyes ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if globals are prefixed by underscore" >&5
+$as_echo_n "checking if globals are prefixed by underscore... " >&6; }
+if test "${nettle_cv_asm_underscore+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+   # Default is no underscore
+    nettle_cv_asm_underscore=no
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int a_global_symbol;
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+   $NM conftest.$OBJEXT >conftest.out
+        if grep _a_global_symbol conftest.out >/dev/null ; then
+          nettle_cv_asm_underscore=yes
+        elif grep a_global_symbol conftest.out >/dev/null ; then
+          nettle_cv_asm_underscore=no
+        else
+          { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: nm doesn't list a_global_symbol at all" >&5
+$as_echo "$as_me: WARNING: nm doesn't list a_global_symbol at all" >&2;}
+       fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: test program with a single global could not be compiled!?" >&5
+$as_echo "$as_me: WARNING: test program with a single global could not be compiled!?" >&2;}
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nettle_cv_asm_underscore" >&5
+$as_echo "$nettle_cv_asm_underscore" >&6; }
+  if test x$nettle_cv_asm_underscore = xyes ; then
+    ASM_SYMBOL_PREFIX='_'
+  fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we should use a .note.GNU-stack section" >&5
+$as_echo_n "checking if we should use a .note.GNU-stack section... " >&6; }
+if test "${nettle_cv_asm_gnu_stack+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+   # Default
+    nettle_cv_asm_gnu_stack=no
+
+    cat >conftest.c <<EOF
+int foo() { return 0; }
+EOF
+    nettle_compile="$CC $CFLAGS $CPPFLAGS -c conftest.c >conftest.out 2>&1"
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$nettle_compile\""; } >&5
+  (eval $nettle_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+      cat conftest.out >&5
+      $OBJDUMP -x conftest.o | grep '\.note\.GNU-stack' > /dev/null \
+      && nettle_cv_asm_gnu_stack=yes
+    else
+      cat conftest.out >&5
+      echo "configure: failed program was:" >&5
+      cat conftest.s >&5
+    fi
+    rm -f conftest.*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nettle_cv_asm_gnu_stack" >&5
+$as_echo "$nettle_cv_asm_gnu_stack" >&6; }
+  if test x$nettle_cv_asm_gnu_stack = xyes ; then
+    ASM_MARK_NOEXEC_STACK='.section .note.GNU-stack,"",@progbits'
+  fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ELF-style .type,%function pseudo-ops" >&5
+$as_echo_n "checking for ELF-style .type,%function pseudo-ops... " >&6; }
+if test "${nettle_cv_asm_type_percent_function+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.s <<EOF
+
+.text
+.globl foo
+.type foo,%function
+foo:
+.Lend:
+
+.size foo, .Lend - foo
+
+EOF
+gmp_assemble="$CC $CFLAGS $CPPFLAGS -c conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+  (eval $gmp_assemble) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  cat conftest.out >&5
+  nettle_cv_asm_type_percent_function=yes
+else
+  cat conftest.out >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.s >&5
+  nettle_cv_asm_type_percent_function=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nettle_cv_asm_type_percent_function" >&5
+$as_echo "$nettle_cv_asm_type_percent_function" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ELF-style .type,#function pseudo-ops" >&5
+$as_echo_n "checking for ELF-style .type,#function pseudo-ops... " >&6; }
+if test "${nettle_cv_asm_type_hash_function+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.s <<EOF
+
+.text
+.globl foo
+.type foo,#function
+foo:
+.Lend:
+
+.size foo, .Lend - foo
+
+EOF
+gmp_assemble="$CC $CFLAGS $CPPFLAGS -c conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+  (eval $gmp_assemble) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  cat conftest.out >&5
+  nettle_cv_asm_type_hash_function=yes
+else
+  cat conftest.out >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.s >&5
+  nettle_cv_asm_type_hash_function=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nettle_cv_asm_type_hash_function" >&5
+$as_echo "$nettle_cv_asm_type_hash_function" >&6; }
+
+  if test x$nettle_cv_asm_type_percent_function = xyes ; then
+    ASM_ELF_STYLE='yes'
+    ASM_TYPE_FUNCTION='%function'
+  else
+    if test x$nettle_cv_asm_type_hash_function = xyes ; then
+      ASM_ELF_STYLE='yes'
+      ASM_TYPE_FUNCTION='#function'
+    fi
+  fi
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if .align assembly directive is logarithmic" >&5
+$as_echo_n "checking if .align assembly directive is logarithmic... " >&6; }
+if test "${nettle_cv_asm_align_log+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.s <<EOF
+
+.align 3
+
+EOF
+gmp_assemble="$CC $CFLAGS $CPPFLAGS -c conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+  (eval $gmp_assemble) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  cat conftest.out >&5
+  nettle_cv_asm_align_log=yes
+else
+  cat conftest.out >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.s >&5
+  nettle_cv_asm_align_log=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nettle_cv_asm_align_log" >&5
+$as_echo "$nettle_cv_asm_align_log" >&6; }
+  if test x$nettle_cv_asm_align_log = xyes ; then
+    ASM_ALIGN_LOG='yes'
+  fi
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Extract the first word of "m4", so it can be a program name with args.
+set dummy m4; 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_M4+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $M4 in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_M4="$M4" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_M4="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_M4" && ac_cv_path_M4="m4"
+  ;;
+esac
+fi
+M4=$ac_cv_path_M4
+if test -n "$M4"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $M4" >&5
+$as_echo "$M4" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+if test "x$enable_gcov" = "xyes"; then
+  CFLAGS="$CFLAGS -ftest-coverage -fprofile-arcs"
+fi
+
+# Checks for typedefs, structures, and compiler characteristics.
+{ $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 :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this.  */
+  typedef int charset[2];
+  const charset cs;
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *pcpcc;
+  char **ppc;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  pcpcc = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++pcpcc;
+  ppc = (char**) pcpcc;
+  pcpcc = (char const *const *) ppc;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+    if (s) return 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this 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;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+    if (!foo) return 0;
+  }
+  return !cs[0] && !zero.x;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_const=yes
+else
+  ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+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 :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+  inline | yes) ;;
+  *)
+    case $ac_cv_c_inline in
+      no) ac_val=;;
+      *) ac_val=$ac_cv_c_inline;;
+    esac
+    cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+    ;;
+esac
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+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 ; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $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 :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_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$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    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
+# 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
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  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
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $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 :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_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$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    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
+# 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
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  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
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5
+$as_echo_n "checking for uid_t in sys/types.h... " >&6; }
+if test "${ac_cv_type_uid_t+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "uid_t" >/dev/null 2>&1; then :
+  ac_cv_type_uid_t=yes
+else
+  ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5
+$as_echo "$ac_cv_type_uid_t" >&6; }
+if test $ac_cv_type_uid_t = no; then
+
+$as_echo "#define uid_t int" >>confdefs.h
+
+
+$as_echo "#define gid_t int" >>confdefs.h
+
+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 :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                  (('a' <= (c) && (c) <= 'i') \
+                    || ('j' <= (c) && (c) <= 'r') \
+                    || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+       || toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                 inttypes.h stdint.h unistd.h
+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
+"
+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
+
+fi
+
+done
+
+
+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 :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
+$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
+if test "${ac_cv_header_time+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_time=yes
+else
+  ac_cv_header_time=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
+$as_echo "$ac_cv_header_time" >&6; }
+if test $ac_cv_header_time = yes; then
+
+$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
+
+fi
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if test "${ac_cv_sizeof_long+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_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_error 77 "cannot compute sizeof (long)
+See \`config.log' for more details" "$LINENO" 5 ; }
+   else
+     ac_cv_sizeof_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+
+for ac_header in openssl/blowfish.h openssl/des.h openssl/cast.h openssl/aes.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"
+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
+
+else
+  enable_openssl=no
+ break
+fi
+
+done
+
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments.  Useless!
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5
+$as_echo_n "checking for working alloca.h... " >&6; }
+if test "${ac_cv_working_alloca_h+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <alloca.h>
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+                         if (p) return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_working_alloca_h=yes
+else
+  ac_cv_working_alloca_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5
+$as_echo "$ac_cv_working_alloca_h" >&6; }
+if test $ac_cv_working_alloca_h = yes; then
+
+$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5
+$as_echo_n "checking for alloca... " >&6; }
+if test "${ac_cv_func_alloca_works+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+#  include <malloc.h>
+#  define alloca _alloca
+# else
+#  ifdef HAVE_ALLOCA_H
+#   include <alloca.h>
+#  else
+#   ifdef _AIX
+ #pragma alloca
+#   else
+#    ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+int
+main ()
+{
+char *p = (char *) alloca (1);
+                                   if (p) return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_func_alloca_works=yes
+else
+  ac_cv_func_alloca_works=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5
+$as_echo "$ac_cv_func_alloca_works" >&6; }
+
+if test $ac_cv_func_alloca_works = yes; then
+
+$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h
+
+else
+  # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble.  Some versions do not even contain alloca or
+# contain a buggy version.  If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+
+ALLOCA=\${LIBOBJDIR}alloca.$ac_objext
+
+$as_echo "#define C_ALLOCA 1" >>confdefs.h
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5
+$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; }
+if test "${ac_cv_os_cray+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined CRAY && ! defined CRAY2
+webecray
+#else
+wenotbecray
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "webecray" >/dev/null 2>&1; then :
+  ac_cv_os_cray=yes
+else
+  ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5
+$as_echo "$ac_cv_os_cray" >&6; }
+if test $ac_cv_os_cray = yes; then
+  for ac_func in _getb67 GETB67 getb67; 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 CRAY_STACKSEG_END $ac_func
+_ACEOF
+
+    break
+fi
+
+  done
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5
+$as_echo_n "checking stack direction for C alloca... " >&6; }
+if test "${ac_cv_c_stack_direction+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_c_stack_direction=0
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+find_stack_direction ()
+{
+  static char *addr = 0;
+  auto char dummy;
+  if (addr == 0)
+    {
+      addr = &dummy;
+      return find_stack_direction ();
+    }
+  else
+    return (&dummy > addr) ? 1 : -1;
+}
+
+int
+main ()
+{
+  return find_stack_direction () < 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_c_stack_direction=1
+else
+  ac_cv_c_stack_direction=-1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5
+$as_echo "$ac_cv_c_stack_direction" >&6; }
+cat >>confdefs.h <<_ACEOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+_ACEOF
+
+
+fi
+
+for ac_header in malloc.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "malloc.h" "ac_cv_header_malloc_h" "$ac_includes_default"
+if test "x$ac_cv_header_malloc_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_MALLOC_H 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_func in strerror
+do :
+  ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror"
+if test "x$ac_cv_func_strerror" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STRERROR 1
+_ACEOF
+
+fi
+done
+
+
+
+# Needed by the supplied memcmp.c
+ { $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 :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_bigendian=unknown
+    # See if we're dealing with a universal compiler.
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __APPLE_CC__
+              not a universal capable compiler
+            #endif
+            typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+       # Check for potential -arch flags.  It is not universal unless
+       # there are at least two -arch flags with different values.
+       ac_arch=
+       ac_prev=
+       for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+        if test -n "$ac_prev"; then
+          case $ac_word in
+            i?86 | x86_64 | ppc | ppc64)
+              if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+                ac_arch=$ac_word
+              else
+                ac_cv_c_bigendian=universal
+                break
+              fi
+              ;;
+          esac
+          ac_prev=
+        elif test "x$ac_word" = "x-arch"; then
+          ac_prev=arch
+        fi
+       done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if sys/param.h defines the BYTE_ORDER macro.
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+            #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+                    && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+                    && LITTLE_ENDIAN)
+             bogus endian macros
+            #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+               #include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+                not big endian
+               #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_bigendian=yes
+else
+  ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    fi
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+             bogus endian macros
+            #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  # It does; now see whether it defined to _BIG_ENDIAN or not.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+                not big endian
+               #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_bigendian=yes
+else
+  ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    fi
+    if test $ac_cv_c_bigendian = unknown; then
+      # Compile a test program.
+      if test "$cross_compiling" = yes; then :
+  # Try to guess by grepping values from an object file.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+short int ascii_mm[] =
+                 { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+               short int ascii_ii[] =
+                 { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+               int use_ascii (int i) {
+                 return ascii_mm[i] + ascii_ii[i];
+               }
+               short int ebcdic_ii[] =
+                 { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+               short int ebcdic_mm[] =
+                 { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+               int use_ebcdic (int i) {
+                 return ebcdic_mm[i] + ebcdic_ii[i];
+               }
+               extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+             ac_cv_c_bigendian=yes
+           fi
+           if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+             if test "$ac_cv_c_bigendian" = unknown; then
+               ac_cv_c_bigendian=no
+             else
+               # finding both strings is unlikely to happen, but who knows?
+               ac_cv_c_bigendian=unknown
+             fi
+           fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+
+            /* Are we little or big endian?  From Harbison&Steele.  */
+            union
+            {
+              long int l;
+              char c[sizeof (long int)];
+            } u;
+            u.l = 1;
+            return u.c[sizeof (long int) - 1] == 1;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_c_bigendian=no
+else
+  ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+    fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+   yes)
+     $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+   no)
+      ;; #(
+   universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+     ;; #(
+   *)
+     as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5  ;;
+ esac
+
+ac_fn_c_check_func "$LINENO" "memxor" "ac_cv_func_memxor"
+if test "x$ac_cv_func_memxor" = x""yes; then :
+  $as_echo "#define HAVE_MEMXOR 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" memxor.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS memxor.$ac_objext"
+ ;;
+esac
+
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __attribute__" >&5
+$as_echo_n "checking for __attribute__... " >&6; }
+if test "${lsh_cv_c_attribute+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+
+static void foo(void) __attribute__ ((noreturn));
+
+static void __attribute__ ((noreturn))
+foo(void)
+{
+  exit(1);
+}
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  lsh_cv_c_attribute=yes
+else
+  lsh_cv_c_attribute=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lsh_cv_c_attribute" >&5
+$as_echo "$lsh_cv_c_attribute" >&6; }
+
+
+if test "x$lsh_cv_c_attribute" = "xyes"; then
+  $as_echo "#define HAVE_GCC_ATTRIBUTE 1" >>confdefs.h
+
+fi
+
+
+
+# According to Simon Josefsson, looking for uint32_t and friends in
+# sys/types.h is needed on some systems, in particular cygwin.
+# ------ AX CREATE STDINT H -------------------------------------
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint types" >&5
+$as_echo_n "checking for stdint types... " >&6; }
+ac_stdint_h=`echo nettle-stdint.h`
+# try to shortcircuit - if the default include path of the compiler
+# can find a "stdint.h" header then we assume that all compilers can.
+if test "${ac_cv_header_stdint_t+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS=""
+old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS=""
+old_CFLAGS="$CFLAGS"     ; CFLAGS=""
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdint.h>
+int
+main ()
+{
+int_least32_t v = 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_stdint_result="(assuming C99 compatible system)"
+ ac_cv_header_stdint_t="stdint.h";
+else
+  ac_cv_header_stdint_t=""
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+CXXFLAGS="$old_CXXFLAGS"
+CPPFLAGS="$old_CPPFLAGS"
+CFLAGS="$old_CFLAGS"
+fi
+
+
+v="... $ac_cv_header_stdint_h"
+if test "$ac_stdint_h" = "stdint.h" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: (are you sure you want them in ./stdint.h?)" >&5
+$as_echo "(are you sure you want them in ./stdint.h?)" >&6; }
+elif test "$ac_stdint_h" = "inttypes.h" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: (are you sure you want them in ./inttypes.h?)" >&5
+$as_echo "(are you sure you want them in ./inttypes.h?)" >&6; }
+elif test "_$ac_cv_header_stdint_t" = "_" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: (putting them into $ac_stdint_h)$v" >&5
+$as_echo "(putting them into $ac_stdint_h)$v" >&6; }
+else
+ ac_cv_header_stdint="$ac_cv_header_stdint_t"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdint (shortcircuit)" >&5
+$as_echo "$ac_cv_header_stdint (shortcircuit)" >&6; }
+fi
+
+if test "_$ac_cv_header_stdint_t" = "_" ; then # can not shortcircuit..
+
+
+inttype_headers=`echo sys/types.h | sed -e 's/,/ /g'`
+
+ac_cv_stdint_result="(no helpful system typedefs seen)"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint uintptr_t" >&5
+$as_echo_n "checking for stdint uintptr_t... " >&6; }
+if test "${ac_cv_header_stdint_x+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+ ac_cv_header_stdint_x="" # the 1997 typedefs (inttypes.h)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: (..)" >&5
+$as_echo "(..)" >&6; }
+  for i in stdint.h inttypes.h sys/inttypes.h $inttype_headers ; do
+   unset ac_cv_type_uintptr_t
+   unset ac_cv_type_uint64_t
+   ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "#include <$i>
+"
+if test "x$ac_cv_type_uintptr_t" = x""yes; then :
+  ac_cv_header_stdint_x=$i
+else
+       continue
+fi
+
+   ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "#include<$i>
+"
+if test "x$ac_cv_type_uint64_t" = x""yes; then :
+  and64="/uint64_t"
+else
+  and64=""
+fi
+
+   ac_cv_stdint_result="(seen uintptr_t$and64 in $i)"
+   break;
+  done
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint uintptr_t" >&5
+$as_echo_n "checking for stdint uintptr_t... " >&6; }
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdint_x" >&5
+$as_echo "$ac_cv_header_stdint_x" >&6; }
+
+if test "_$ac_cv_header_stdint_x" = "_" ; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint uint32_t" >&5
+$as_echo_n "checking for stdint uint32_t... " >&6; }
+if test "${ac_cv_header_stdint_o+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+ ac_cv_header_stdint_o="" # the 1995 typedefs (sys/inttypes.h)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: (..)" >&5
+$as_echo "(..)" >&6; }
+  for i in inttypes.h sys/inttypes.h stdint.h $inttype_headers ; do
+   unset ac_cv_type_uint32_t
+   unset ac_cv_type_uint64_t
+   ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "#include <$i>
+"
+if test "x$ac_cv_type_uint32_t" = x""yes; then :
+  ac_cv_header_stdint_o=$i
+else
+       continue
+fi
+
+   ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "#include<$i>
+"
+if test "x$ac_cv_type_uint64_t" = x""yes; then :
+  and64="/uint64_t"
+else
+  and64=""
+fi
+
+   ac_cv_stdint_result="(seen uint32_t$and64 in $i)"
+   break;
+  done
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint uint32_t" >&5
+$as_echo_n "checking for stdint uint32_t... " >&6; }
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdint_o" >&5
+$as_echo "$ac_cv_header_stdint_o" >&6; }
+fi
+
+if test "_$ac_cv_header_stdint_x" = "_" ; then
+if test "_$ac_cv_header_stdint_o" = "_" ; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint u_int32_t" >&5
+$as_echo_n "checking for stdint u_int32_t... " >&6; }
+if test "${ac_cv_header_stdint_u+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+ ac_cv_header_stdint_u="" # the BSD typedefs (sys/types.h)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: (..)" >&5
+$as_echo "(..)" >&6; }
+  for i in sys/types.h inttypes.h sys/inttypes.h $inttype_headers ; do
+   unset ac_cv_type_u_int32_t
+   unset ac_cv_type_u_int64_t
+   ac_fn_c_check_type "$LINENO" "u_int32_t" "ac_cv_type_u_int32_t" "#include <$i>
+"
+if test "x$ac_cv_type_u_int32_t" = x""yes; then :
+  ac_cv_header_stdint_u=$i
+else
+       continue
+fi
+
+   ac_fn_c_check_type "$LINENO" "u_int64_t" "ac_cv_type_u_int64_t" "#include<$i>
+"
+if test "x$ac_cv_type_u_int64_t" = x""yes; then :
+  and64="/u_int64_t"
+else
+  and64=""
+fi
+
+   ac_cv_stdint_result="(seen u_int32_t$and64 in $i)"
+   break;
+  done
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint u_int32_t" >&5
+$as_echo_n "checking for stdint u_int32_t... " >&6; }
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdint_u" >&5
+$as_echo "$ac_cv_header_stdint_u" >&6; }
+fi fi
+
+if test "_$ac_cv_header_stdint_x" = "_" ; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint datatype model" >&5
+$as_echo_n "checking for stdint datatype model... " >&6; }
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: (..)" >&5
+$as_echo "(..)" >&6; }
+   # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char" >&5
+$as_echo_n "checking size of char... " >&6; }
+if test "${ac_cv_sizeof_char+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char))" "ac_cv_sizeof_char"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_char" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (char)
+See \`config.log' for more details" "$LINENO" 5 ; }
+   else
+     ac_cv_sizeof_char=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char" >&5
+$as_echo "$ac_cv_sizeof_char" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_CHAR $ac_cv_sizeof_char
+_ACEOF
+
+
+   # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5
+$as_echo_n "checking size of short... " >&6; }
+if test "${ac_cv_sizeof_short+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_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_error 77 "cannot compute sizeof (short)
+See \`config.log' for more details" "$LINENO" 5 ; }
+   else
+     ac_cv_sizeof_short=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5
+$as_echo "$ac_cv_sizeof_short" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+_ACEOF
+
+
+   # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5
+$as_echo_n "checking size of int... " >&6; }
+if test "${ac_cv_sizeof_int+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_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_error 77 "cannot compute sizeof (int)
+See \`config.log' for more details" "$LINENO" 5 ; }
+   else
+     ac_cv_sizeof_int=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5
+$as_echo "$ac_cv_sizeof_int" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+_ACEOF
+
+
+   # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if test "${ac_cv_sizeof_long+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_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_error 77 "cannot compute sizeof (long)
+See \`config.log' for more details" "$LINENO" 5 ; }
+   else
+     ac_cv_sizeof_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+   # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void*" >&5
+$as_echo_n "checking size of void*... " >&6; }
+if test "${ac_cv_sizeof_voidp+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void*))" "ac_cv_sizeof_voidp"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_voidp" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (void*)
+See \`config.log' for more details" "$LINENO" 5 ; }
+   else
+     ac_cv_sizeof_voidp=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_voidp" >&5
+$as_echo "$ac_cv_sizeof_voidp" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_VOIDP $ac_cv_sizeof_voidp
+_ACEOF
+
+
+   ac_cv_stdint_char_model=""
+   ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_char"
+   ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_short"
+   ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_int"
+   ac_cv_stdint_long_model=""
+   ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_int"
+   ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_long"
+   ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_voidp"
+   name="$ac_cv_stdint_long_model"
+   case "$ac_cv_stdint_char_model/$ac_cv_stdint_long_model" in
+    122/242)     name="$name,  IP16 (standard 16bit machine)" ;;
+    122/244)     name="$name,  LP32 (standard 32bit mac/win)" ;;
+    122/*)       name="$name        (unusual int16 model)" ;;
+    124/444)     name="$name, ILP32 (standard 32bit unixish)" ;;
+    124/488)     name="$name,  LP64 (standard 64bit unixish)" ;;
+    124/448)     name="$name, LLP64 (unusual  64bit unixish)" ;;
+    124/*)       name="$name        (unusual int32 model)" ;;
+    128/888)     name="$name, ILP64 (unusual  64bit numeric)" ;;
+    128/*)       name="$name        (unusual int64 model)" ;;
+    222/*|444/*) name="$name        (unusual dsptype)" ;;
+     *)          name="$name        (very unusal model)" ;;
+   esac
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: combined for stdint datatype model...  $name" >&5
+$as_echo "combined for stdint datatype model...  $name" >&6; }
+fi
+
+if test "_$ac_cv_header_stdint_x" != "_" ; then
+   ac_cv_header_stdint="$ac_cv_header_stdint_x"
+elif  test "_$ac_cv_header_stdint_o" != "_" ; then
+   ac_cv_header_stdint="$ac_cv_header_stdint_o"
+elif  test "_$ac_cv_header_stdint_u" != "_" ; then
+   ac_cv_header_stdint="$ac_cv_header_stdint_u"
+else
+   ac_cv_header_stdint="stddef.h"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for extra inttypes in chosen header" >&5
+$as_echo_n "checking for extra inttypes in chosen header... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ($ac_cv_header_stdint)" >&5
+$as_echo "($ac_cv_header_stdint)" >&6; }
+unset ac_cv_type_int_least32_t
+unset ac_cv_type_int_fast32_t
+ac_fn_c_check_type "$LINENO" "int_least32_t" "ac_cv_type_int_least32_t" "#include <$ac_cv_header_stdint>
+"
+if test "x$ac_cv_type_int_least32_t" = x""yes; then :
+
+fi
+
+ac_fn_c_check_type "$LINENO" "int_fast32_t" "ac_cv_type_int_fast32_t" "#include<$ac_cv_header_stdint>
+"
+if test "x$ac_cv_type_int_fast32_t" = x""yes; then :
+
+fi
+
+ac_fn_c_check_type "$LINENO" "intmax_t" "ac_cv_type_intmax_t" "#include <$ac_cv_header_stdint>
+"
+if test "x$ac_cv_type_intmax_t" = x""yes; then :
+
+fi
+
+
+fi # shortcircut to system "stdint.h"
+# ------------------ PREPARE VARIABLES ------------------------------
+if test "$GCC" = "yes" ; then
+ac_cv_stdint_message="using gnu compiler "`$CC --version | head -1`
+else
+ac_cv_stdint_message="using $CC"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: make use of $ac_cv_header_stdint in $ac_stdint_h $ac_cv_stdint_result" >&5
+$as_echo "make use of $ac_cv_header_stdint in $ac_stdint_h $ac_cv_stdint_result" >&6; }
+
+# ----------------- DONE inttypes.h checks START header -------------
+ac_config_commands="$ac_config_commands $ac_stdint_h"
+
+
+
+# Check for file locking. We (AC_PROG_CC?) have already checked for
+# sys/types.h and unistd.h.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fcntl file locking" >&5
+$as_echo_n "checking for fcntl file locking... " >&6; }
+if test "${nettle_cv_fcntl_locking+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <fcntl.h>
+
+int
+main ()
+{
+
+int op = F_SETLKW;
+struct flock fl;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  nettle_cv_fcntl_locking=yes
+else
+  nettle_cv_fcntl_locking=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nettle_cv_fcntl_locking" >&5
+$as_echo "$nettle_cv_fcntl_locking" >&6; }
+
+
+if test "x$nettle_cv_fcntl_locking" = "xyes" ; then
+  $as_echo "#define HAVE_FCNTL_LOCKING 1" >>confdefs.h
+
+fi
+
+# Checks for libraries
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __gmpz_getlimbn in -lgmp" >&5
+$as_echo_n "checking for __gmpz_getlimbn in -lgmp... " >&6; }
+if test "${ac_cv_lib_gmp___gmpz_getlimbn+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgmp  $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 __gmpz_getlimbn ();
+int
+main ()
+{
+return __gmpz_getlimbn ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_gmp___gmpz_getlimbn=yes
+else
+  ac_cv_lib_gmp___gmpz_getlimbn=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_gmp___gmpz_getlimbn" >&5
+$as_echo "$ac_cv_lib_gmp___gmpz_getlimbn" >&6; }
+if test "x$ac_cv_lib_gmp___gmpz_getlimbn" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBGMP 1
+_ACEOF
+
+  LIBS="-lgmp $LIBS"
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GNU MP not found, or not 3.1 or up, see http://gmplib.org/.
+Support for public key algorithms will be unavailable." >&5
+$as_echo "$as_me: WARNING: GNU MP not found, or not 3.1 or up, see http://gmplib.org/.
+Support for public key algorithms will be unavailable." >&2;}
+    enable_public_key=no
+fi
+
+
+# Add -R flags needed to run programs linked with gmp
+if test $cross_compiling = no -a "x$RPATHFLAG" != x ; then
+  ac_success=no
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int main(int argc, char **argv) { return 0; }
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_success=yes
+else
+  ac_success=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+  if test $ac_success = no ; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking Running simple test program failed. Trying -R flags" >&5
+$as_echo_n "checking Running simple test program failed. Trying -R flags... " >&6; }
+    ac_remaining_dirs=''
+    ac_rpath_save_LDFLAGS="$LDFLAGS"
+    for d in $RPATH_CANDIDATE_DIRS ; do
+      if test $ac_success = yes ; then
+       ac_remaining_dirs="$ac_remaining_dirs $d"
+      else
+       LDFLAGS="$RPATHFLAG$d $LDFLAGS"
+       if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int main(int argc, char **argv) { return 0; }
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_success=yes
+         ac_rpath_save_LDFLAGS="$LDFLAGS"
+         { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding $RPATHFLAG$d" >&5
+$as_echo "adding $RPATHFLAG$d" >&6; }
+
+else
+  ac_remaining_dirs="$ac_remaining_dirs $d"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+       LDFLAGS="$ac_rpath_save_LDFLAGS"
+      fi
+    done
+    RPATH_CANDIDATE_DIRS=$ac_remaining_dirs
+  fi
+  if test $ac_success = no ; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+  fi
+fi
+
+
+
+ac_fn_c_check_func "$LINENO" "__gmpz_powm_sec" "ac_cv_func___gmpz_powm_sec"
+if test "x$ac_cv_func___gmpz_powm_sec" = x""yes; then :
+  $as_echo "#define HAVE_MPZ_POWM_SEC 1" >>confdefs.h
+
+fi
+
+
+
+
+if test "x$enable_public_key" = xyes ; then
+  $as_echo "#define WITH_HOGWEED 1" >>confdefs.h
+
+  IF_HOGWEED=''
+else
+  IF_HOGWEED='#'
+fi
+
+if test "x$enable_shared" = xyes ; then
+  IF_SHARED=''
+else
+  IF_SHARED='#'
+fi
+
+
+
+
+OPENSSL_LIBFLAGS=''
+
+# Check for openssl's libcrypto (used only for benchmarking)
+if test x$enable_openssl = xyes ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BF_ecb_encrypt in -lcrypto" >&5
+$as_echo_n "checking for BF_ecb_encrypt in -lcrypto... " >&6; }
+if test "${ac_cv_lib_crypto_BF_ecb_encrypt+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto  $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 BF_ecb_encrypt ();
+int
+main ()
+{
+return BF_ecb_encrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_crypto_BF_ecb_encrypt=yes
+else
+  ac_cv_lib_crypto_BF_ecb_encrypt=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_crypto_BF_ecb_encrypt" >&5
+$as_echo "$ac_cv_lib_crypto_BF_ecb_encrypt" >&6; }
+if test "x$ac_cv_lib_crypto_BF_ecb_encrypt" = x""yes; then :
+  OPENSSL_LIBFLAGS='-lcrypto'
+else
+  enable_openssl=no
+fi
+
+fi
+
+
+
+if test x$enable_openssl = xyes ; then
+  $as_echo "#define WITH_OPENSSL 1" >>confdefs.h
+
+fi
+
+
+
+# Choose strategy for Camellia round
+
+
+# clock_gettime is in librt on *-*-osf5.1 and on glibc, so add -lrt to
+# BENCH_LIBS if needed. On linux (tested on x86_32, 2.6.26),
+# clock_getres reports ns accuracy, while in a quick test on osf
+# clock_getres said only 1 millisecond.
+
+old_LIBS="$LIBS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5
+$as_echo_n "checking for library containing clock_gettime... " >&6; }
+if test "${ac_cv_search_clock_gettime+set}" = set; 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 clock_gettime ();
+int
+main ()
+{
+return clock_gettime ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' rt; 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_clock_gettime=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if test "${ac_cv_search_clock_gettime+set}" = set; then :
+  break
+fi
+done
+if test "${ac_cv_search_clock_gettime+set}" = set; then :
+
+else
+  ac_cv_search_clock_gettime=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5
+$as_echo "$ac_cv_search_clock_gettime" >&6; }
+ac_res=$ac_cv_search_clock_gettime
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+
+$as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h
+
+fi
+
+BENCH_LIBS="$LIBS"
+LIBS="$old_LIBS"
+
+
+
+# Set these flags *last*, or else the test programs won't compile
+if test x$GCC = xyes ; then
+  # Using -ggdb3 makes (some versions of) Redhat's gcc-2.96 dump core
+  if $CC --version | grep '^2\.96$' 1>/dev/null 2>&1; then
+    true
+  else
+    CFLAGS="$CFLAGS -ggdb3"
+  fi
+  # FIXME: It would be better to actually test if this option works and/or is needed.
+  # Or perhaps use -funsigned-char.
+  if $CC --version | grep 'gcc.* 4\.' 1>/dev/null 2>&1; then
+    CFLAGS="$CFLAGS -Wno-pointer-sign"
+  fi
+  CFLAGS="$CFLAGS -Wall -W \
+  -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes \
+  -Wpointer-arith -Wbad-function-cast -Wnested-externs"
+
+# Don't enable -Wcast-align as it results in tons of warnings in the
+# DES code. And when using stdio.
+# Don't enable -Waggregate-return, as that causes warnings for glibc
+# inttypes.h.
+fi
+
+ac_config_files="$ac_config_files config.make config.m4 Makefile"
+
+ac_config_files="$ac_config_files tools/Makefile testsuite/Makefile examples/Makefile"
+
+ac_config_files="$ac_config_files nettle.pc hogweed.pc"
+
+
+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
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+       "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\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" &&
+      { $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
+  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;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+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$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+       expr "X$arg" : "X\\(.*\\)$as_nl";
+       arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""       $as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# 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.
+as_fn_error ()
+{
+  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: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+           s//\1/
+           q
+         }
+         /^X\/\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\/\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='        ';;     # ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='        ';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... 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'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)[^/].*/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+      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"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  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
+
+# 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'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by nettle $as_me 2.4, which was
+generated by GNU Autoconf 2.67.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_links="$ac_config_links"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+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
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration links:
+$config_links
+
+Configuration commands:
+$config_commands
+
+Report bugs to <nettle-bugs@lists.lysator.liu.se>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+nettle config.status 2.4
+configured by $0, generated by GNU Autoconf 2.67,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+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_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    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;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+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
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+# variables for create stdint.h replacement
+PACKAGE="$PACKAGE"
+VERSION="$VERSION"
+ac_stdint_h="$ac_stdint_h"
+_ac_stdint_h=`$as_echo "_$PACKAGE-$ac_stdint_h" | $as_tr_cpp`
+ac_cv_stdint_message="$ac_cv_stdint_message"
+ac_cv_header_stdint_t="$ac_cv_header_stdint_t"
+ac_cv_header_stdint_x="$ac_cv_header_stdint_x"
+ac_cv_header_stdint_o="$ac_cv_header_stdint_o"
+ac_cv_header_stdint_u="$ac_cv_header_stdint_u"
+ac_cv_type_uint64_t="$ac_cv_type_uint64_t"
+ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t"
+ac_cv_stdint_char_model="$ac_cv_stdint_char_model"
+ac_cv_stdint_long_model="$ac_cv_stdint_long_model"
+ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t"
+ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t"
+ac_cv_type_intmax_t="$ac_cv_type_intmax_t"
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+    "dummy-dep-files") CONFIG_COMMANDS="$CONFIG_COMMANDS dummy-dep-files" ;;
+    "$tmp_f") CONFIG_LINKS="$CONFIG_LINKS $tmp_f:$asm_path/$tmp_f" ;;
+    "$ac_stdint_h") CONFIG_COMMANDS="$CONFIG_COMMANDS $ac_stdint_h" ;;
+    "config.make") CONFIG_FILES="$CONFIG_FILES config.make" ;;
+    "config.m4") CONFIG_FILES="$CONFIG_FILES config.m4" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;;
+    "testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;;
+    "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;;
+    "nettle.pc") CONFIG_FILES="$CONFIG_FILES nettle.pc" ;;
+    "hogweed.pc") CONFIG_FILES="$CONFIG_FILES hogweed.pc" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp=
+  trap 'exit_status=$?
+  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+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'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_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 '^'`
+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
+
+  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
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = "\a"
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+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
+_ACEOF
+
+# 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[        ]*=[    ]*/{
+h
+s///
+s/^/:/
+s/[     ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[  ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[      ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# 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 ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# 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
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[    ]*#[    ]*define[       ][      ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[    ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[        ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[    ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[        ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = "\a"
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS  :L $CONFIG_LINKS  :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$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 `:'.
+        test -f "$ac_f" ||
+          case $ac_f in
+          [\\/$]*) false;;
+          *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+          esac ||
+          as_fn_error 1 "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'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+         $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+       `' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5  ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_file" : 'X\(//\)[^/]' \| \
+        X"$ac_file" : 'X\(//\)$' \| \
+        X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)[^/].*/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+  ac_MKDIR_P=$MKDIR_P
+  case $MKDIR_P in
+  [\\/$]* | ?:[\\/]* ) ;;
+  */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+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
+
+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"; } &&
+  { $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
+$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;}
+
+  rm -f "$tmp/stdin"
+  case $ac_file in
+  -) cat "$tmp/out" && rm -f "$tmp/out";;
+  *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  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
+      { $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
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
+  fi
+ ;;
+  :L)
+  #
+  # CONFIG_LINK
+  #
+
+  if test "$ac_source" = "$ac_file" && test "$srcdir" = '.'; then
+    :
+  else
+    # Prefer the file from the source tree if names are identical.
+    if test "$ac_source" = "$ac_file" || test ! -r "$ac_source"; then
+      ac_source=$srcdir/$ac_source
+    fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: linking $ac_source to $ac_file" >&5
+$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
+    fi
+    rm -f "$ac_file"
+
+    # Try a relative symlink, then a hard link, then a copy.
+    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
+  fi
+ ;;
+  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
+
+
+  case $ac_file$ac_mode in
+    "dummy-dep-files":C) (cd "$srcdir" && find . -name '*.c' -print) \
+ | sed 's/\.c$//' | (while read f; do echo > "$f.o.d"; echo > "$f.po.d"; done)
+ ;;
+    "$ac_stdint_h":C)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_stdint_h : $_ac_stdint_h" >&5
+$as_echo "$as_me: creating $ac_stdint_h : $_ac_stdint_h" >&6;}
+ac_stdint=$tmp/_stdint.h
+
+echo "#ifndef" $_ac_stdint_h >$ac_stdint
+echo "#define" $_ac_stdint_h "1" >>$ac_stdint
+echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint
+echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint
+echo "/* generated $ac_cv_stdint_message */" >>$ac_stdint
+if test "_$ac_cv_header_stdint_t" != "_" ; then
+echo "#define _STDINT_HAVE_STDINT_H" "1" >>$ac_stdint
+fi
+
+cat >>$ac_stdint <<STDINT_EOF
+
+/* ................... shortcircuit part ........................... */
+
+#if defined HAVE_STDINT_H || defined _STDINT_HAVE_STDINT_H
+#include <stdint.h>
+#else
+#include <stddef.h>
+
+/* .................... configured part ............................ */
+
+STDINT_EOF
+
+echo "/* whether we have a C99 compatible stdint header file */" >>$ac_stdint
+if test "_$ac_cv_header_stdint_x" != "_" ; then
+  ac_header="$ac_cv_header_stdint_x"
+  echo "#define _STDINT_HEADER_INTPTR" '"'"$ac_header"'"' >>$ac_stdint
+else
+  echo "/* #undef _STDINT_HEADER_INTPTR */" >>$ac_stdint
+fi
+
+echo "/* whether we have a C96 compatible inttypes header file */" >>$ac_stdint
+if  test "_$ac_cv_header_stdint_o" != "_" ; then
+  ac_header="$ac_cv_header_stdint_o"
+  echo "#define _STDINT_HEADER_UINT32" '"'"$ac_header"'"' >>$ac_stdint
+else
+  echo "/* #undef _STDINT_HEADER_UINT32 */" >>$ac_stdint
+fi
+
+echo "/* whether we have a BSD compatible inet types header */" >>$ac_stdint
+if  test "_$ac_cv_header_stdint_u" != "_" ; then
+  ac_header="$ac_cv_header_stdint_u"
+  echo "#define _STDINT_HEADER_U_INT32" '"'"$ac_header"'"' >>$ac_stdint
+else
+  echo "/* #undef _STDINT_HEADER_U_INT32 */" >>$ac_stdint
+fi
+
+echo "" >>$ac_stdint
+
+if test "_$ac_header" != "_" ; then if test "$ac_header" != "stddef.h" ; then
+  echo "#include <$ac_header>" >>$ac_stdint
+  echo "" >>$ac_stdint
+fi fi
+
+echo "/* which 64bit typedef has been found */" >>$ac_stdint
+if test "$ac_cv_type_uint64_t" = "yes" ; then
+echo "#define   _STDINT_HAVE_UINT64_T" "1"  >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_UINT64_T */" >>$ac_stdint
+fi
+if test "$ac_cv_type_u_int64_t" = "yes" ; then
+echo "#define   _STDINT_HAVE_U_INT64_T" "1"  >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_U_INT64_T */" >>$ac_stdint
+fi
+echo "" >>$ac_stdint
+
+echo "/* which type model has been detected */" >>$ac_stdint
+if test "_$ac_cv_stdint_char_model" != "_" ; then
+echo "#define   _STDINT_CHAR_MODEL" "$ac_cv_stdint_char_model" >>$ac_stdint
+echo "#define   _STDINT_LONG_MODEL" "$ac_cv_stdint_long_model" >>$ac_stdint
+else
+echo "/* #undef _STDINT_CHAR_MODEL // skipped */" >>$ac_stdint
+echo "/* #undef _STDINT_LONG_MODEL // skipped */" >>$ac_stdint
+fi
+echo "" >>$ac_stdint
+
+echo "/* whether int_least types were detected */" >>$ac_stdint
+if test "$ac_cv_type_int_least32_t" = "yes"; then
+echo "#define   _STDINT_HAVE_INT_LEAST32_T" "1"  >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_INT_LEAST32_T */" >>$ac_stdint
+fi
+echo "/* whether int_fast types were detected */" >>$ac_stdint
+if test "$ac_cv_type_int_fast32_t" = "yes"; then
+echo "#define   _STDINT_HAVE_INT_FAST32_T" "1" >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_INT_FAST32_T */" >>$ac_stdint
+fi
+echo "/* whether intmax_t type was detected */" >>$ac_stdint
+if test "$ac_cv_type_intmax_t" = "yes"; then
+echo "#define   _STDINT_HAVE_INTMAX_T" "1" >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_INTMAX_T */" >>$ac_stdint
+fi
+echo "" >>$ac_stdint
+
+  cat >>$ac_stdint <<STDINT_EOF
+/* .................... detections part ............................ */
+
+/* whether we need to define bitspecific types from compiler base types */
+#ifndef _STDINT_HEADER_INTPTR
+#ifndef _STDINT_HEADER_UINT32
+#ifndef _STDINT_HEADER_U_INT32
+#define _STDINT_NEED_INT_MODEL_T
+#else
+#define _STDINT_HAVE_U_INT_TYPES
+#endif
+#endif
+#endif
+
+#ifdef _STDINT_HAVE_U_INT_TYPES
+#undef _STDINT_NEED_INT_MODEL_T
+#endif
+
+#ifdef  _STDINT_CHAR_MODEL
+#if     _STDINT_CHAR_MODEL+0 == 122 || _STDINT_CHAR_MODEL+0 == 124
+#ifndef _STDINT_BYTE_MODEL
+#define _STDINT_BYTE_MODEL 12
+#endif
+#endif
+#endif
+
+#ifndef _STDINT_HAVE_INT_LEAST32_T
+#define _STDINT_NEED_INT_LEAST_T
+#endif
+
+#ifndef _STDINT_HAVE_INT_FAST32_T
+#define _STDINT_NEED_INT_FAST_T
+#endif
+
+#ifndef _STDINT_HEADER_INTPTR
+#define _STDINT_NEED_INTPTR_T
+#ifndef _STDINT_HAVE_INTMAX_T
+#define _STDINT_NEED_INTMAX_T
+#endif
+#endif
+
+
+/* .................... definition part ............................ */
+
+/* some system headers have good uint64_t */
+#ifndef _HAVE_UINT64_T
+#if     defined _STDINT_HAVE_UINT64_T  || defined HAVE_UINT64_T
+#define _HAVE_UINT64_T
+#elif   defined _STDINT_HAVE_U_INT64_T || defined HAVE_U_INT64_T
+#define _HAVE_UINT64_T
+typedef u_int64_t uint64_t;
+#endif
+#endif
+
+#ifndef _HAVE_UINT64_T
+/* .. here are some common heuristics using compiler runtime specifics */
+#if defined __STDC_VERSION__ && defined __STDC_VERSION__ >= 199901L
+#define _HAVE_UINT64_T
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+
+#elif !defined __STRICT_ANSI__
+#if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__
+#define _HAVE_UINT64_T
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+#elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__
+/* note: all ELF-systems seem to have loff-support which needs 64-bit */
+#if !defined _NO_LONGLONG
+#define _HAVE_UINT64_T
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+#endif
+
+#elif defined __alpha || (defined __mips && defined _ABIN32)
+#if !defined _NO_LONGLONG
+typedef long int64_t;
+typedef unsigned long uint64_t;
+#endif
+  /* compiler/cpu type to define int64_t */
+#endif
+#endif
+#endif
+
+#if defined _STDINT_HAVE_U_INT_TYPES
+/* int8_t int16_t int32_t defined by inet code, redeclare the u_intXX types */
+typedef u_int8_t uint8_t;
+typedef u_int16_t uint16_t;
+typedef u_int32_t uint32_t;
+
+/* glibc compatibility */
+#ifndef __int8_t_defined
+#define __int8_t_defined
+#endif
+#endif
+
+#ifdef _STDINT_NEED_INT_MODEL_T
+/* we must guess all the basic types. Apart from byte-adressable system, */
+/* there a few 32-bit-only dsp-systems that we guard with BYTE_MODEL 8-} */
+/* (btw, those nibble-addressable systems are way off, or so we assume) */
+
+
+#if defined _STDINT_BYTE_MODEL
+#if _STDINT_LONG_MODEL+0 == 242
+/* 2:4:2 =  IP16 = a normal 16-bit system                */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned long   uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          long    int32_t;
+#endif
+#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL == 444
+/* 2:4:4 =  LP32 = a 32-bit system derived from a 16-bit */
+/* 4:4:4 = ILP32 = a normal 32-bit system                */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned int    uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          int     int32_t;
+#endif
+#elif _STDINT_LONG_MODEL+0 == 484 || _STDINT_LONG_MODEL+0 == 488
+/* 4:8:4 =  IP32 = a 32-bit system prepared for 64-bit    */
+/* 4:8:8 =  LP64 = a normal 64-bit system                 */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned int    uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          int     int32_t;
+#endif
+/* this system has a "long" of 64bit */
+#ifndef _HAVE_UINT64_T
+#define _HAVE_UINT64_T
+typedef unsigned long   uint64_t;
+typedef          long    int64_t;
+#endif
+#elif _STDINT_LONG_MODEL+0 == 448
+/*      LLP64   a 64-bit system derived from a 32-bit system */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned int    uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          int     int32_t;
+#endif
+/* assuming the system has a "long long" */
+#ifndef _HAVE_UINT64_T
+#define _HAVE_UINT64_T
+typedef unsigned long long uint64_t;
+typedef          long long  int64_t;
+#endif
+#else
+#define _STDINT_NO_INT32_T
+#endif
+#else
+#define _STDINT_NO_INT8_T
+#define _STDINT_NO_INT32_T
+#endif
+#endif
+
+/*
+ * quote from SunOS-5.8 sys/inttypes.h:
+ * Use at your own risk.  As of February 1996, the committee is squarely
+ * behind the fixed sized types; the "least" and "fast" types are still being
+ * discussed.  The probability that the "fast" types may be removed before
+ * the standard is finalized is high enough that they are not currently
+ * implemented.
+ */
+
+#if defined _STDINT_NEED_INT_LEAST_T
+typedef  int8_t    int_least8_t;
+typedef  int16_t   int_least16_t;
+typedef  int32_t   int_least32_t;
+#ifdef _HAVE_UINT64_T
+typedef  int64_t   int_least64_t;
+#endif
+
+typedef uint8_t   uint_least8_t;
+typedef uint16_t  uint_least16_t;
+typedef uint32_t  uint_least32_t;
+#ifdef _HAVE_UINT64_T
+typedef uint64_t  uint_least64_t;
+#endif
+  /* least types */
+#endif
+
+#if defined _STDINT_NEED_INT_FAST_T
+typedef  int8_t    int_fast8_t;
+typedef  int       int_fast16_t;
+typedef  int32_t   int_fast32_t;
+#ifdef _HAVE_UINT64_T
+typedef  int64_t   int_fast64_t;
+#endif
+
+typedef uint8_t   uint_fast8_t;
+typedef unsigned  uint_fast16_t;
+typedef uint32_t  uint_fast32_t;
+#ifdef _HAVE_UINT64_T
+typedef uint64_t  uint_fast64_t;
+#endif
+  /* fast types */
+#endif
+
+#ifdef _STDINT_NEED_INTMAX_T
+#ifdef _HAVE_UINT64_T
+typedef  int64_t       intmax_t;
+typedef uint64_t      uintmax_t;
+#else
+typedef          long  intmax_t;
+typedef unsigned long uintmax_t;
+#endif
+#endif
+
+#ifdef _STDINT_NEED_INTPTR_T
+#ifndef __intptr_t_defined
+#define __intptr_t_defined
+/* we encourage using "long" to store pointer values, never use "int" ! */
+#if   _STDINT_LONG_MODEL+0 == 242 || _STDINT_LONG_MODEL+0 == 484
+typedef  unsinged int   uintptr_t;
+typedef           int    intptr_t;
+#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL+0 == 444
+typedef  unsigned long  uintptr_t;
+typedef           long   intptr_t;
+#elif _STDINT_LONG_MODEL+0 == 448 && defined _HAVE_UINT64_T
+typedef        uint64_t uintptr_t;
+typedef         int64_t  intptr_t;
+#else /* matches typical system types ILP32 and LP64 - but not IP16 or LLP64 */
+typedef  unsigned long  uintptr_t;
+typedef           long   intptr_t;
+#endif
+#endif
+#endif
+
+  /* shortcircuit*/
+#endif
+  /* once */
+#endif
+#endif
+STDINT_EOF
+    if cmp -s $ac_stdint_h $ac_stdint 2>/dev/null; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_stdint_h is unchanged" >&5
+$as_echo "$as_me: $ac_stdint_h is unchanged" >&6;}
+    else
+      ac_dir=`$as_dirname -- "$ac_stdint_h" ||
+$as_expr X"$ac_stdint_h" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_stdint_h" : 'X\(//\)[^/]' \| \
+        X"$ac_stdint_h" : 'X\(//\)$' \| \
+        X"$ac_stdint_h" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_stdint_h" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)[^/].*/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+      as_dir="$ac_dir"; as_fn_mkdir_p
+      rm -f $ac_stdint_h
+      mv $ac_stdint $ac_stdint_h
+    fi
+ ;;
+
+  esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  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 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
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: summary of build options:
+
+  Version:           ${PACKAGE_STRING}
+  Host type:         ${host}
+  ABI:               ${ABI}
+  Assembly files:    ${asm_path:-none}
+  Install prefix:    ${prefix}
+  Library directory: ${libdir}
+  Compiler:          ${CC}
+  Shared libraries:  ${enable_shared}
+  Public key crypto: ${enable_public_key}
+" >&5
+$as_echo "$as_me: summary of build options:
+
+  Version:           ${PACKAGE_STRING}
+  Host type:         ${host}
+  ABI:               ${ABI}
+  Assembly files:    ${asm_path:-none}
+  Install prefix:    ${prefix}
+  Library directory: ${libdir}
+  Compiler:          ${CC}
+  Shared libraries:  ${enable_shared}
+  Public key crypto: ${enable_public_key}
+" >&6;}
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..4d5a497
--- /dev/null
@@ -0,0 +1,624 @@
+dnl -*- mode: shell-script; sh-indentation: 2; -*-
+
+dnl Process this file with autoconf to produce a configure script.
+
+AC_INIT([nettle], [2.4], [nettle-bugs@lists.lysator.liu.se])
+AC_PREREQ(2.61)
+AC_CONFIG_SRCDIR([arcfour.c])
+# Needed to stop autoconf from looking for files in parent directories.
+AC_CONFIG_AUX_DIR([.])
+
+AC_CONFIG_HEADER([config.h])
+
+LIBNETTLE_MAJOR=4
+LIBNETTLE_MINOR=3
+
+LIBHOGWEED_MAJOR=2
+LIBHOGWEED_MINOR=1
+
+AC_CANONICAL_HOST
+
+# Command line options
+AC_ARG_WITH(include-path,
+  AC_HELP_STRING([--with-include-path], [A colon-separated list of directories to search for include files]),,
+  [with_include_path=''])
+
+if test x$with_include_path != x ; then
+  CPPFLAGS="$CPPFLAGS -I`echo $with_include_path | sed 's/:/ -I/g'`"
+fi
+
+AC_ARG_WITH(lib-path,
+  AC_HELP_STRING([--with-lib-path], [A colon-separated list of directories to search for libraries]),,
+  [with_lib_path=''])
+
+if test x$with_lib_path != x ; then
+  LDFLAGS="$LDFLAGS -L`echo $with_lib_path | sed 's/:/ -L/g'`"
+fi
+
+AC_ARG_ENABLE(public-key,
+  AC_HELP_STRING([--disable-public-key], [Disable public key algorithms]),,
+  [enable_public_key=yes])
+
+AC_ARG_ENABLE(assembler,
+  AC_HELP_STRING([--disable-assembler],[Disable assembler code]),,
+  [enable_assembler=yes])
+
+AC_ARG_ENABLE(shared,
+  AC_HELP_STRING([--enable-shared], [Build a shared library]),,
+  [enable_shared=no])
+
+AC_ARG_ENABLE(pic,
+  AC_HELP_STRING([--disable-pic],
+  [Do not try to compile library files as position independent code]),,
+  [enable_pic=yes])
+
+AC_ARG_ENABLE(openssl,
+  AC_HELP_STRING([--disable-openssl], [Do not include openssl glue in the benchmark program]),,
+  [enable_openssl=yes])
+
+AC_ARG_ENABLE(gcov,
+  AC_HELP_STRING([--enable-gcov], [Instrument for gcov (requires a modern gcc)]),,
+  [enable_gcov=no])
+
+LSH_RPATH_INIT([`echo $with_lib_path | sed 's/:/ /g'` \
+    `echo $exec_prefix | sed "s@^NONE@$prefix/lib@g" | sed "s@^NONE@$ac_default_prefix/lib@g"` \
+    /usr/local/lib /sw/local/lib /sw/lib \
+    /usr/gnu/lib /opt/gnu/lib /sw/gnu/lib /usr/freeware/lib /usr/pkg/lib])
+
+# Checks for programs.
+AC_PROG_CC
+
+# When $CC foo.c -o foo creates both foo and foo.exe, autoconf picks
+# up the foo.exe and sets exeext to .exe. That is correct for cygwin,
+# which has some kind of magic link from foo to foo.exe, but not for
+# rntcl. A better check for the cygwin case would check if the
+# contents of foo and foo.exe are equal; in the rntcl case, foo is a
+# sh script, and foo.exe is a windows executable.
+
+if test "x$CC" = xrntcl ; then
+    AC_MSG_NOTICE([Compiling with rntcl; clearing EXEEXT and disabling assembler])
+    ac_exeext=''
+    ac_cv_exeext=''
+    EXEEXT=''
+    enable_assembler=no
+fi
+
+# Used by the testsuite only
+AC_PROG_CXX
+
+AC_LANG_PUSH(C++)
+AC_TRY_COMPILE([],[return 0;],[CXX_TESTS='cxx-test$(EXEEXT)'], [CXX_TESTS=''])
+AC_SUBST([CXX_TESTS])
+AC_LANG_POP
+
+AC_PROG_MAKE_SET
+AC_PROG_RANLIB
+AC_CHECK_TOOL(NM, nm, strings)
+# Used only for the GNU-stack configure test.
+AC_CHECK_TOOL(OBJDUMP, objdump, false)
+
+if test "x$ac_cv_prog_cc_stdc" = xno ; then
+  AC_ERROR([the C compiler doesn't handle ANSI-C]) #'
+fi
+
+AC_PROG_INSTALL
+
+# According to the autoconf manual, needs install-sh from
+# autoconf-2.60 or automake-1.10 to avoid races.
+AC_PROG_MKDIR_P
+
+LSH_DEPENDENCY_TRACKING
+
+if test x$enable_dependency_tracking = xyes ; then
+  # Since the makefiles use include to get the dependency files, we must
+  # make sure that the files exist. We generate some more files than are
+  # actually needed.
+
+  AC_CONFIG_COMMANDS([dummy-dep-files],
+  [(cd "$srcdir" && find . -name '*.c' -print) \
+ | sed 's/\.c$//' | (while read f; do echo > "$f.o.d"; echo > "$f.po.d"; done)
+])
+fi
+
+# Figure out ABI. Currently, configurable only by setting CFLAGS.
+ABI=standard
+
+case "$host_cpu" in
+  [x86_64 | amd64])
+    AC_TRY_COMPILE([
+#if defined(__x86_64__) || defined(__arch64__)
+#error 64-bit x86
+#endif
+    ], [], [
+      ABI=32
+    ], [
+      ABI=64
+    ])
+    ;;
+  *sparc*)
+    AC_TRY_COMPILE([
+#if defined(__sparcv9) || defined(__arch64__)
+#error 64-bit sparc
+#endif
+    ], [], [
+      ABI=32
+    ], [
+      ABI=64
+    ])
+    ;;
+esac
+
+if test "x$ABI" != xstandard ; then
+  AC_MSG_NOTICE([Compiler uses $ABI-bit ABI. To change, set CC.])
+  if test "$libdir" = '${exec_prefix}/lib' ; then
+    # Try setting a better default
+    case "$host_cpu:$host_os:$ABI" in
+      *:solaris*:32|*:sunos*:32)
+       libdir='${exec_prefix}/lib'
+       ;;
+      *:solaris*:64|*:sunos*:64)
+       libdir='${exec_prefix}/lib/64'
+       ;;
+      # Linux conventions are a mess... According to the Linux File
+      # Hierarchy Standard, all architectures except IA64 puts 32-bit
+      # libraries in lib, and 64-bit in lib64. Some distributions,
+      # e.g., Fedora and Gentoo, adhere to this standard, while at
+      # least Debian has decided to put 64-bit libraries in lib and
+      # 32-bit libraries in lib32.
+      
+      # We try to figure out the convention, except if we're cross
+      # compiling. We use lib${ABI} if /usr/lib${ABI} exists and
+      # appears to not be a symlink to a different name.
+      *:linux*:32|*:linux*:64)
+       if test "$cross_compiling" = yes ; then
+          AC_MSG_WARN([Cross compiling for linux. Can't guess if libraries go in lib${ABI} or lib.]); dnl '
+       else
+         # The dash builtin pwd tries to be "helpful" and remember
+         # symlink names. Use -P option, and hope it's portable enough.
+         test -d /usr/lib${ABI} \
+           && (cd /usr/lib${ABI} && pwd -P | grep >/dev/null "/lib${ABI}"'$') \
+           && libdir='${exec_prefix}/'"lib${ABI}"
+       fi
+       ;;
+      # On freebsd, it seems 32-bit libraries are in lib32,
+      # and 64-bit in lib. Don't know about "kfreebsd", does
+      # it follow the Linux fhs conventions?
+      *:freebsd*:32)
+       libdir='${exec_prefix}/lib32'
+       ;;
+      *:freebsd*:64)
+       libdir='${exec_prefix}/lib'
+       ;;
+      *)
+        AC_MSG_WARN([Don't know where to install $ABI-bit libraries on this system.]); dnl '
+
+    esac
+    AC_MSG_NOTICE([Libraries to be installed in $libdir.])
+  fi
+fi
+
+# Select assembler code
+asm_path=
+if test "x$enable_assembler" = xyes ; then
+  case "$host_cpu" in
+    [i?86* | k[5-8]* | pentium* | athlon])
+      asm_path=x86
+      ;;
+    [x86_64 | amd64])
+      if test "$ABI" = 64 ; then
+       asm_path=x86_64
+      else
+       asm_path=x86
+      fi
+      ;;
+    *sparc*)
+      if test "$ABI" = 64 ; then
+       asm_path=sparc64
+      else
+       asm_path=sparc32
+      fi
+      ;;
+    *)
+      enable_assembler=no
+      ;;
+  esac
+fi
+# echo "enable_assembler: $enable_assembler, asm_path: $asm_path"
+
+if test "x$enable_assembler" = xyes ; then
+  if test -n "$asm_path"; then
+    AC_MSG_NOTICE([Looking for assembler files in $asm_path/.])
+    found=no
+    for tmp_f in aes-encrypt-internal.asm aes-decrypt-internal.asm \
+                arcfour-crypt.asm camellia-crypt-internal.asm \
+                md5-compress.asm memxor.asm \
+                serpent-encrypt.asm serpent-decrypt.asm \
+                sha1-compress.asm machine.m4; do
+#       echo "Looking for $srcdir/$asm_path/$tmp_f"
+      if test -f "$srcdir/$asm_path/$tmp_f"; then
+#        echo found
+        found=yes
+        AC_CONFIG_LINKS($tmp_f:$asm_path/$tmp_f)
+      fi
+    done
+    if test "$found" = no; then
+      enable_assembler=no
+      AC_MSG_WARN([No assembler files found.])
+    fi
+  fi
+fi
+
+LSH_CCPIC
+
+SHLIBCFLAGS="$CCPIC"
+
+case "$host_os" in
+  mingw32*)
+    LIBNETTLE_FORLINK='libnettle-$(LIBNETTLE_MAJOR)-$(LIBNETTLE_MINOR).dll'
+    LIBNETTLE_SONAME=''
+    LIBNETTLE_FILE='libnettle.dll.a'
+    LIBNETTLE_LINK='$(CC) $(LDFLAGS) -shared -Wl,--out-implib=$(LIBNETTLE_FILE) -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive'
+    LIBNETTLE_LIBS='-Wl,--no-whole-archive $(LIBS)'
+
+    LIBHOGWEED_FORLINK='libhogweed-$(LIBHOGWEED_MAJOR)-$(LIBHOGWEED_MINOR).dll'
+    LIBHOGWEED_SONAME=''
+    LIBHOGWEED_FILE='libhogweed.dll.a'
+    LIBHOGWEED_LINK='$(CC) $(LDFLAGS) -shared -Wl,--out-implib=$(LIBHOGWEED_FILE) -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive'
+    LIBHOGWEED_LIBS='-Wl,--no-whole-archive $(LIBS) libnettle.dll.a'
+    ;;
+  cygwin*)
+    LIBNETTLE_FORLINK='cygnettle-$(LIBNETTLE_MAJOR)-$(LIBNETTLE_MINOR).dll'
+    LIBNETTLE_SONAME=''
+    LIBNETTLE_FILE='libnettle.dll.a'
+    LIBNETTLE_LINK='$(CC) $(LDFLAGS) -shared -Wl,--out-implib=$(LIBNETTLE_FILE) -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive'
+    LIBNETTLE_LIBS='-Wl,--no-whole-archive $(LIBS)'
+
+    LIBHOGWEED_FORLINK='cyghogweed-$(LIBHOGWEED_MAJOR)-$(LIBHOGWEED_MINOR).dll'
+    LIBHOGWEED_SONAME=''
+    LIBHOGWEED_FILE='libhogweed.dll.a'
+    LIBHOGWEED_LINK='$(CC) $(LDFLAGS) -shared -Wl,--out-implib=$(LIBHOGWEED_FILE) -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive'
+    LIBHOGWEED_LIBS='-Wl,--no-whole-archive $(LIBS)'
+    ;;
+  darwin*)
+    LIBNETTLE_FORLINK=libnettle.dylib
+    LIBNETTLE_SONAME='$(LIBNETTLE_FORLINK).$(LIBNETTLE_MAJOR)'
+    LIBNETTLE_FILE='$(LIBNETTLE_SONAME).$(LIBNETTLE_MINOR)'
+    LIBNETTLE_LINK='$(CC) -dynamiclib $(LDFLAGS)'
+    LIBNETTLE_LIBS=''
+
+    LIBHOGWEED_FORLINK=libhogweed.dylib
+    LIBHOGWEED_SONAME='$(LIBHOGWEED_FORLINK).$(LIBHOGWEED_MAJOR)'
+    LIBHOGWEED_FILE='$(LIBHOGWEED_SONAME).$(LIBHOGWEED_MINOR)'
+    LIBHOGWEED_LINK='$(CC) -dynamiclib $(LDFLAGS)'
+    LIBHOGWEED_LIBS=''
+    ;;
+  solaris*)
+    # Sun's ld uses -h to set the soname, and this option is passed
+    # through by both Sun's compiler and gcc. Might not work with GNU
+    # ld, but it's unusual to use GNU ld on Solaris.
+    LIBNETTLE_FORLINK=libnettle.so
+    LIBNETTLE_SONAME='$(LIBNETTLE_FORLINK).$(LIBNETTLE_MAJOR)'
+    LIBNETTLE_FILE='$(LIBNETTLE_SONAME).$(LIBNETTLE_MINOR)'
+    LIBNETTLE_LINK='$(CC) $(LDFLAGS) -G -h $(LIBNETTLE_SONAME)'
+    LIBNETTLE_LIBS=''
+
+    LIBHOGWEED_FORLINK=libhogweed.so
+    LIBHOGWEED_SONAME='$(LIBHOGWEED_FORLINK).$(LIBHOGWEED_MAJOR)'
+    LIBHOGWEED_FILE='$(LIBHOGWEED_SONAME).$(LIBHOGWEED_MINOR)'
+    LIBHOGWEED_LINK='$(CC) $(LDFLAGS) -L. -G -h $(LIBHOGWEED_SONAME)'
+    LIBHOGWEED_LIBS='-lnettle -lgmp'
+    ;;
+  *)
+    LIBNETTLE_FORLINK=libnettle.so
+    LIBNETTLE_SONAME='$(LIBNETTLE_FORLINK).$(LIBNETTLE_MAJOR)'
+    LIBNETTLE_FILE='$(LIBNETTLE_SONAME).$(LIBNETTLE_MINOR)'
+    LIBNETTLE_LINK='$(CC) $(LDFLAGS) -shared -Wl,-soname=$(LIBNETTLE_SONAME)'
+    LIBNETTLE_LIBS=''
+
+    LIBHOGWEED_FORLINK=libhogweed.so
+    LIBHOGWEED_SONAME='$(LIBHOGWEED_FORLINK).$(LIBHOGWEED_MAJOR)'
+    LIBHOGWEED_FILE='$(LIBHOGWEED_SONAME).$(LIBHOGWEED_MINOR)'
+    LIBHOGWEED_LINK='$(CC) $(LDFLAGS) -L. -shared -Wl,-soname=$(LIBHOGWEED_SONAME)'
+    # Requested by debian, to make linking with only -lhogweed work
+    # (does not work in general, e.g., with static linking all of
+    # -lhogweed -lgmp -lnettle are still required). Also makes dlopen
+    # of libhogweed.so work, without having to use RTLD_GLOBAL.
+    # Depends on -L. above, to locate nettle.so.
+    LIBHOGWEED_LIBS='-lnettle -lgmp'
+    ;;
+esac
+
+if test "x$enable_pic" = xyes; then
+  CCPIC_MAYBE="$CCPIC"
+else
+  CCPIC_MAYBE=''
+fi
+AC_SUBST([CCPIC_MAYBE])
+
+ASM_SYMBOL_PREFIX=''
+ASM_ELF_STYLE='no'
+ASM_TYPE_FUNCTION=''
+ASM_MARK_NOEXEC_STACK=''
+ASM_ALIGN_LOG=''
+
+if test x$enable_assembler = xyes ; then
+  AC_CACHE_CHECK([if globals are prefixed by underscore],
+  nettle_cv_asm_underscore,
+  [ # Default is no underscore
+    nettle_cv_asm_underscore=no
+    AC_COMPILE_IFELSE(
+      [int a_global_symbol;],
+      [ $NM conftest.$OBJEXT >conftest.out
+        if grep _a_global_symbol conftest.out >/dev/null ; then
+          nettle_cv_asm_underscore=yes
+        elif grep a_global_symbol conftest.out >/dev/null ; then
+          nettle_cv_asm_underscore=no
+        else
+          AC_MSG_WARN([nm doesn't list a_global_symbol at all])
+       fi],
+      [AC_MSG_WARN([test program with a single global could not be compiled!?])])])
+  if test x$nettle_cv_asm_underscore = xyes ; then
+    ASM_SYMBOL_PREFIX='_'
+  fi
+
+  AC_CACHE_CHECK([if we should use a .note.GNU-stack section],
+  nettle_cv_asm_gnu_stack,
+  [ # Default
+    nettle_cv_asm_gnu_stack=no
+
+    cat >conftest.c <<EOF
+int foo() { return 0; }
+EOF
+    nettle_compile="$CC $CFLAGS $CPPFLAGS -c conftest.c >conftest.out 2>&1"
+    if AC_TRY_EVAL(nettle_compile); then
+      cat conftest.out >&AC_FD_CC
+      $OBJDUMP -x conftest.o | grep '\.note\.GNU-stack' > /dev/null \
+      && nettle_cv_asm_gnu_stack=yes
+    else
+      cat conftest.out >&AC_FD_CC
+      echo "configure: failed program was:" >&AC_FD_CC
+      cat conftest.s >&AC_FD_CC
+    fi
+    rm -f conftest.*])
+  if test x$nettle_cv_asm_gnu_stack = xyes ; then
+    ASM_MARK_NOEXEC_STACK='.section .note.GNU-stack,"",@progbits'
+  fi
+
+  AC_CACHE_CHECK([for ELF-style .type,%function pseudo-ops],
+    [nettle_cv_asm_type_percent_function],
+    [GMP_TRY_ASSEMBLE([
+.text
+.globl foo
+.type foo,%function
+foo:
+.Lend:
+
+.size foo, .Lend - foo
+],
+       [nettle_cv_asm_type_percent_function=yes],
+       [nettle_cv_asm_type_percent_function=no])])
+
+dnl Needs double quote for the # character
+  AC_CACHE_CHECK([[for ELF-style .type,#function pseudo-ops]],
+    [nettle_cv_asm_type_hash_function],
+    [GMP_TRY_ASSEMBLE([
+.text
+.globl foo
+.type foo,#function
+foo:
+.Lend:
+
+.size foo, .Lend - foo
+],
+       [nettle_cv_asm_type_hash_function=yes],
+       [nettle_cv_asm_type_hash_function=no])])
+
+  if test x$nettle_cv_asm_type_percent_function = xyes ; then
+    ASM_ELF_STYLE='yes'
+    ASM_TYPE_FUNCTION='%function'
+  else
+    if test x$nettle_cv_asm_type_hash_function = xyes ; then
+      ASM_ELF_STYLE='yes'
+      ASM_TYPE_FUNCTION='#function'
+    fi
+  fi
+  AC_CACHE_CHECK([if .align assembly directive is logarithmic],
+    [nettle_cv_asm_align_log],
+    [GMP_TRY_ASSEMBLE([
+.align 3
+],
+       [nettle_cv_asm_align_log=yes],
+       [nettle_cv_asm_align_log=no])])
+  if test x$nettle_cv_asm_align_log = xyes ; then
+    ASM_ALIGN_LOG='yes'
+  fi
+fi
+
+AC_SUBST(ASM_SYMBOL_PREFIX)
+AC_SUBST(ASM_ELF_STYLE)
+AC_SUBST(ASM_TYPE_FUNCTION)
+AC_SUBST(ASM_MARK_NOEXEC_STACK)
+AC_SUBST(ASM_ALIGN_LOG)
+
+AC_SUBST(SHLIBCFLAGS)
+
+AC_SUBST(LIBNETTLE_MAJOR)
+AC_SUBST(LIBNETTLE_MINOR)
+AC_SUBST(LIBNETTLE_FORLINK)
+AC_SUBST(LIBNETTLE_SONAME)
+AC_SUBST(LIBNETTLE_FILE)
+AC_SUBST(LIBNETTLE_LINK)
+AC_SUBST(LIBNETTLE_LIBS)
+
+AC_SUBST(LIBHOGWEED_MAJOR)
+AC_SUBST(LIBHOGWEED_MINOR)
+AC_SUBST(LIBHOGWEED_FORLINK)
+AC_SUBST(LIBHOGWEED_SONAME)
+AC_SUBST(LIBHOGWEED_FILE)
+AC_SUBST(LIBHOGWEED_LINK)
+AC_SUBST(LIBHOGWEED_LIBS)
+
+AC_PATH_PROG(M4, m4, m4)
+
+if test "x$enable_gcov" = "xyes"; then
+  CFLAGS="$CFLAGS -ftest-coverage -fprofile-arcs"
+fi
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_UID_T
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+AC_CHECK_SIZEOF(long)
+
+AC_CHECK_HEADERS([openssl/blowfish.h openssl/des.h openssl/cast.h openssl/aes.h],,
+[enable_openssl=no
+ break])
+
+LSH_FUNC_ALLOCA
+LSH_FUNC_STRERROR
+
+# Needed by the supplied memcmp.c
+AC_C_BIGENDIAN
+AC_REPLACE_FUNCS(memxor)
+
+LSH_GCC_ATTRIBUTES
+
+# According to Simon Josefsson, looking for uint32_t and friends in
+# sys/types.h is needed on some systems, in particular cygwin.
+AX_CREATE_STDINT_H([nettle-stdint.h], [sys/types.h])
+
+# Check for file locking. We (AC_PROG_CC?) have already checked for
+# sys/types.h and unistd.h.
+AC_CACHE_CHECK([for fcntl file locking],
+               nettle_cv_fcntl_locking,
+[AC_TRY_COMPILE([
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <fcntl.h>
+],[
+int op = F_SETLKW;
+struct flock fl;
+],
+nettle_cv_fcntl_locking=yes,
+nettle_cv_fcntl_locking=no)])
+
+AH_TEMPLATE([HAVE_FCNTL_LOCKING], [Define if fcntl file locking is available])
+if test "x$nettle_cv_fcntl_locking" = "xyes" ; then
+  AC_DEFINE(HAVE_FCNTL_LOCKING)
+fi
+
+# Checks for libraries
+AC_CHECK_LIB(gmp, __gmpz_getlimbn,,
+    [AC_MSG_WARN(
+[GNU MP not found, or not 3.1 or up, see http://gmplib.org/.
+Support for public key algorithms will be unavailable.])]
+    enable_public_key=no)
+
+# Add -R flags needed to run programs linked with gmp
+LSH_RPATH_FIX
+
+AH_TEMPLATE([HAVE_MPZ_POWM_SEC], [Define if mpz_powm_sec is available (appeared in GMP-5)])
+AC_CHECK_FUNC(__gmpz_powm_sec, [AC_DEFINE(HAVE_MPZ_POWM_SEC)])
+
+AH_TEMPLATE([WITH_HOGWEED], [Defined if public key features are enabled])
+
+if test "x$enable_public_key" = xyes ; then
+  AC_DEFINE(WITH_HOGWEED)
+  IF_HOGWEED=''
+else
+  IF_HOGWEED='#'
+fi
+
+if test "x$enable_shared" = xyes ; then
+  IF_SHARED=''
+else
+  IF_SHARED='#'
+fi
+
+AC_SUBST(IF_HOGWEED)
+AC_SUBST(IF_SHARED)
+
+OPENSSL_LIBFLAGS=''
+
+# Check for openssl's libcrypto (used only for benchmarking)
+if test x$enable_openssl = xyes ; then
+  AC_CHECK_LIB(crypto, BF_ecb_encrypt,
+    [OPENSSL_LIBFLAGS='-lcrypto'],
+    [enable_openssl=no])
+fi
+
+AH_TEMPLATE([WITH_OPENSSL],
+           [Define if you have openssl's libcrypto (used for benchmarking)])
+
+if test x$enable_openssl = xyes ; then
+  AC_DEFINE(WITH_OPENSSL)
+fi
+
+AC_SUBST(OPENSSL_LIBFLAGS)
+
+# Choose strategy for Camellia round
+AH_BOTTOM(
+[/* Needs include of <limits.h> before use. */
+#define HAVE_NATIVE_64_BIT (SIZEOF_LONG * CHAR_BIT >= 64)
+])
+
+# clock_gettime is in librt on *-*-osf5.1 and on glibc, so add -lrt to
+# BENCH_LIBS if needed. On linux (tested on x86_32, 2.6.26),
+# clock_getres reports ns accuracy, while in a quick test on osf
+# clock_getres said only 1 millisecond.
+
+old_LIBS="$LIBS"
+AC_SEARCH_LIBS(clock_gettime, rt, [
+  AC_DEFINE([HAVE_CLOCK_GETTIME],1,[Define to 1 if you have the `clock_gettime' function])])
+BENCH_LIBS="$LIBS"
+LIBS="$old_LIBS"
+
+AC_SUBST(BENCH_LIBS)
+
+# Set these flags *last*, or else the test programs won't compile
+if test x$GCC = xyes ; then
+  # Using -ggdb3 makes (some versions of) Redhat's gcc-2.96 dump core
+  if $CC --version | grep '^2\.96$' 1>/dev/null 2>&1; then
+    true
+  else
+    CFLAGS="$CFLAGS -ggdb3"
+  fi
+  # FIXME: It would be better to actually test if this option works and/or is needed.
+  # Or perhaps use -funsigned-char.
+  if $CC --version | grep 'gcc.* 4\.' 1>/dev/null 2>&1; then
+    CFLAGS="$CFLAGS -Wno-pointer-sign"
+  fi
+  CFLAGS="$CFLAGS -Wall -W \
+  -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes \
+  -Wpointer-arith -Wbad-function-cast -Wnested-externs"
+
+# Don't enable -Wcast-align as it results in tons of warnings in the
+# DES code. And when using stdio.
+# Don't enable -Waggregate-return, as that causes warnings for glibc
+# inttypes.h.
+fi
+
+AC_CONFIG_FILES([config.make config.m4 Makefile])
+AC_CONFIG_FILES([tools/Makefile testsuite/Makefile examples/Makefile])
+AC_CONFIG_FILES([nettle.pc hogweed.pc])
+
+AC_OUTPUT
+
+AC_MSG_NOTICE([summary of build options:
+
+  Version:           ${PACKAGE_STRING}
+  Host type:         ${host}
+  ABI:               ${ABI}
+  Assembly files:    ${asm_path:-none}
+  Install prefix:    ${prefix}
+  Library directory: ${libdir}
+  Compiler:          ${CC}
+  Shared libraries:  ${enable_shared}
+  Public key crypto: ${enable_public_key}
+])
diff --git a/ctr.c b/ctr.c
new file mode 100644 (file)
index 0000000..d217013
--- /dev/null
+++ b/ctr.c
@@ -0,0 +1,128 @@
+/* ctr.c
+ *
+ * Cipher counter mode.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2005 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ctr.h"
+
+#include "macros.h"
+#include "memxor.h"
+#include "nettle-internal.h"
+
+#define NBLOCKS 4
+
+void
+ctr_crypt(void *ctx, nettle_crypt_func f,
+         unsigned block_size, uint8_t *ctr,
+         unsigned length, uint8_t *dst,
+         const uint8_t *src)
+{
+  if (src != dst)
+    {
+      if (length == block_size)
+       {
+         f(ctx, block_size, dst, ctr);
+         INCREMENT(block_size, ctr);
+         memxor(dst, src, block_size);
+       }
+      else
+       {
+         unsigned left;
+         uint8_t *p;     
+
+         for (p = dst, left = length;
+              left >= block_size;
+              left -= block_size, p += block_size)
+           {
+             memcpy (p, ctr, block_size);
+             INCREMENT(block_size, ctr);
+           }
+
+         f(ctx, length - left, dst, dst);
+         memxor(dst, src, length - left);
+
+         if (left)
+           {
+             TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
+             TMP_ALLOC(buffer, block_size);
+
+             f(ctx, block_size, buffer, ctr);
+             INCREMENT(block_size, ctr);
+             memxor3(dst + length - left, src + length - left, buffer, left);
+           }
+       }
+    }
+  else
+    {
+      if (length <= block_size)
+       {
+         TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
+         TMP_ALLOC(buffer, block_size);
+
+         f(ctx, block_size, buffer, ctr);
+         INCREMENT(block_size, ctr);
+         memxor3(dst, src, buffer, length);
+       }
+      else
+       {
+         TMP_DECL(buffer, uint8_t, NBLOCKS * NETTLE_MAX_CIPHER_BLOCK_SIZE);
+         unsigned chunk = NBLOCKS * block_size;
+
+         TMP_ALLOC(buffer, chunk);
+
+         for (; length >= chunk;
+              length -= chunk, src += chunk, dst += chunk)
+           {
+             unsigned n;
+             uint8_t *p;         
+             for (n = 0, p = buffer; n < NBLOCKS; n++, p += block_size)
+               {
+                 memcpy (p, ctr, block_size);
+                 INCREMENT(block_size, ctr);
+               }
+             f(ctx, chunk, buffer, buffer);
+             memxor(dst, buffer, chunk);
+           }
+
+         if (length > 0)
+           {
+             /* Final, possibly partial, blocks */
+             for (chunk = 0; chunk < length; chunk += block_size)
+               {
+                 memcpy (buffer + chunk, ctr, block_size);
+                 INCREMENT(block_size, ctr);
+               }
+             f(ctx, chunk, buffer, buffer);
+             memxor3(dst, src, buffer, length);
+           }
+       }
+    }
+}
diff --git a/ctr.h b/ctr.h
new file mode 100644 (file)
index 0000000..80abb6e
--- /dev/null
+++ b/ctr.h
@@ -0,0 +1,62 @@
+/* ctr.h
+ *
+ * Counter mode, using an network byte order incremented counter,
+ * matching the testcases of NIST 800-38A.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2005 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_CTR_H_INCLUDED
+#define NETTLE_CTR_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define ctr_crypt nettle_ctr_crypt
+
+void
+ctr_crypt(void *ctx, nettle_crypt_func f,
+         unsigned block_size, uint8_t *ctr,
+         unsigned length, uint8_t *dst,
+         const uint8_t *src);
+
+#define CTR_CTX(type, size) \
+{ type ctx; uint8_t ctr[size]; }
+
+#define CTR_SET_COUNTER(ctx, data) \
+memcpy((ctx)->ctr, (data), sizeof((ctx)->ctr))
+
+#define CTR_CRYPT(self, f, length, dst, src)           \
+(0 ? ((f)(&(self)->ctx, 0, NULL, NULL))                        \
+   : ctr_crypt((void *) &(self)->ctx,                  \
+               (nettle_crypt_func) (f),                        \
+              sizeof((self)->ctr), (self)->ctr,        \
+               (length), (dst), (src)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_CTR_H_INCLUDED */
diff --git a/der-iterator.c b/der-iterator.c
new file mode 100644 (file)
index 0000000..a724471
--- /dev/null
@@ -0,0 +1,272 @@
+/* der-iterator.c
+ *
+ * Parses DER encoded objects.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2005 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+
+#if HAVE_LIBGMP
+#include "bignum.h"
+#endif
+
+#include "asn1.h"
+
+#include "macros.h"
+
+/* Basic DER syntax: (reference: A Layman's Guide to a Subset of ASN.1, BER, and DER,
+   http://luca.ntop.org/Teaching/Appunti/asn1.html)
+
+   The DER header contains a tag and a length. First, the tag. cls is
+   the class number, c is one if the object is "constructed" and zero
+   if it is primitive. The tag is represented either using a single
+   byte,
+
+     7 6   5   4 3 2 1 0
+    _____________________
+   |_cls_|_c_|_______tag_|   0 <= tag <= 30
+
+   or multiple bytes
+
+     7 6   5   4 3 2 1 0
+    _____________________
+   |_cls_|_c_|_1_1_1_1_1_|
+
+   followed by the real tag number, in base 128, with all but the
+   final byte having the most significant bit set. The tag must be
+   represented with as few bytes as possible. High tag numbers are
+   currently *not* supported.
+   
+   Next, the length, either a single byte with the most significant bit clear, or
+
+     7 6 5 4 3 2 1 0
+    _________________
+   |_1_|___________k_|
+
+   followed by k additional bytes that give the length, in network
+   byte order. The length must be encoded using as few bytes as
+   possible, and k = 0 is reserved for the "indefinite length form"
+   which is not supported.
+
+   After the length comes the contets. For primitive objects (c == 0),
+   it's depends on the type. For constructed objects, it's a
+   concatenation of the DER encodings of zero or more other objects.
+*/
+
+enum {
+  TAG_MASK = 0x1f,
+  CLASS_MASK = 0xc0,
+  CONSTRUCTED_MASK = 0x20,
+};
+
+/* Initializes the iterator, but one has to call next to get to the
+ * first element. */
+static void
+asn1_der_iterator_init(struct asn1_der_iterator *iterator,
+                      unsigned length, const uint8_t *input)
+{
+  iterator->buffer_length = length;
+  iterator->buffer = input;
+  iterator->pos = 0;
+  iterator->type = 0;
+  iterator->length = 0;
+  iterator->data = NULL;
+}
+
+#define LEFT(i) ((i)->buffer_length - (i)->pos)
+#define NEXT(i) ((i)->buffer[(i)->pos++])
+
+/* Gets type and length of the next object. */
+enum asn1_iterator_result
+asn1_der_iterator_next(struct asn1_der_iterator *i)
+{
+  uint8_t tag;
+  
+  if (!LEFT(i))
+    return ASN1_ITERATOR_END;
+
+  tag = NEXT(i);
+  if (!LEFT(i))
+    return ASN1_ITERATOR_ERROR;
+
+  if ( (tag & TAG_MASK) == TAG_MASK)
+    {
+      /* FIXME: Long tags not supported */
+      return ASN1_ITERATOR_ERROR;
+    }
+
+  i->length = NEXT(i);
+  if (i->length & 0x80)
+    {
+      unsigned k = i->length & 0x7f;
+      unsigned j;
+      const uint8_t *data = i->buffer + i->pos;
+      
+      if (k == 0)
+       /* Indefinite encoding. Not supported. */
+       return ASN1_ITERATOR_ERROR;
+
+      if (LEFT(i) < k)
+       return ASN1_ITERATOR_ERROR;
+
+      if (k > sizeof(unsigned))
+       return ASN1_ITERATOR_ERROR;
+
+      i->pos += k;
+      i->length = data[0];
+      if (i->length == 0
+         || (k == 1 && i->length < 0x80))
+       return ASN1_ITERATOR_ERROR;
+
+      for (j = 1; j < k; j++)
+       i->length = (i->length << 8) | data[j];
+    }
+  if (LEFT(i) < i->length)
+    return ASN1_ITERATOR_ERROR;
+
+  i->data = i->buffer + i->pos;
+  i->pos += i->length;
+
+  i->type = tag & TAG_MASK;
+  i->type |= (tag & CLASS_MASK) << (ASN1_CLASS_SHIFT - 6);
+  if (tag & CONSTRUCTED_MASK)
+    {
+      i->type |= ASN1_TYPE_CONSTRUCTED;
+      return ASN1_ITERATOR_CONSTRUCTED;
+    }
+  else
+    return ASN1_ITERATOR_PRIMITIVE;
+}
+
+enum asn1_iterator_result
+asn1_der_iterator_first(struct asn1_der_iterator *i,
+                       unsigned length, const uint8_t *input)
+{
+  asn1_der_iterator_init(i, length, input);
+  return asn1_der_iterator_next(i);
+}
+
+enum asn1_iterator_result
+asn1_der_decode_constructed(struct asn1_der_iterator *i,
+                           struct asn1_der_iterator *contents)
+{
+  assert(i->type & ASN1_TYPE_CONSTRUCTED);
+  return asn1_der_iterator_first(contents, i->length, i->data);
+}
+
+enum asn1_iterator_result
+asn1_der_decode_constructed_last(struct asn1_der_iterator *i)
+{
+  if (LEFT(i) > 0)
+    return ASN1_ITERATOR_ERROR;
+
+  return asn1_der_decode_constructed(i, i);
+}
+
+/* Decoding a DER object which is wrapped in a bit string. */
+enum asn1_iterator_result
+asn1_der_decode_bitstring(struct asn1_der_iterator *i,
+                         struct asn1_der_iterator *contents)
+{
+  assert(i->type == ASN1_BITSTRING);
+  /* First byte is the number of padding bits, which must be zero. */
+  if (i->length == 0  || i->data[0] != 0)
+    return ASN1_ITERATOR_ERROR;
+
+  return asn1_der_iterator_first(contents, i->length - 1, i->data + 1);
+}
+
+enum asn1_iterator_result
+asn1_der_decode_bitstring_last(struct asn1_der_iterator *i)
+{
+  if (LEFT(i) > 0)
+    return ASN1_ITERATOR_ERROR;
+
+  return asn1_der_decode_bitstring(i, i);
+}
+
+int
+asn1_der_get_uint32(struct asn1_der_iterator *i,
+                   uint32_t *x)
+{
+  /* Big endian, two's complement, minimum number of octets (except 0,
+     which is encoded as a single octet */
+  uint32_t value = 0;
+  unsigned length = i->length;
+  unsigned k;
+
+  if (!length || length > 5)
+    return 0;
+
+  if (i->data[length - 1] >= 0x80)
+    /* Signed number */
+    return 0;
+
+  if (length > 1
+      && i->data[length -1] == 0
+      && i->data[length -2] < 0x80)
+    /* Non-minimal number of digits */
+    return 0;
+
+  if (length == 5)
+    {
+      if (i->data[4])
+       return 0;
+      length--;
+    }
+
+  for (value = k = 0; k < length; k++)
+    value = (value << 8) | i->data[k];
+
+  *x = value;
+  return 1;
+}
+
+#if HAVE_LIBGMP
+int
+asn1_der_get_bignum(struct asn1_der_iterator *i,
+                   mpz_t x, unsigned max_bits)
+{
+  if (i->length > 1
+      && ((i->data[0] == 0 && i->data[1] < 0x80)
+         || (i->data[0] == 0xff && i->data[1] >= 0x80)))
+    /* Non-minimal number of digits */
+    return 0;
+
+  /* Allow some extra here, for leading sign octets. */
+  if (max_bits && (8 * i->length > (16 + max_bits)))
+    return 0;
+
+  nettle_mpz_set_str_256_s(x, i->length, i->data);
+
+  /* FIXME: How to interpret a max_bits for negative numbers? */
+  if (max_bits && mpz_sizeinbase(x, 2) > max_bits)
+    return 0;
+
+  return 1;
+}
+#endif /* HAVE_LIBGMP */
diff --git a/der2dsa.c b/der2dsa.c
new file mode 100644 (file)
index 0000000..0a7ef01
--- /dev/null
+++ b/der2dsa.c
@@ -0,0 +1,117 @@
+/* der2dsa.c
+ *
+ * Decoding of DSA keys in OpenSSL and X509.1 format.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2005, 2009 Niels Möller, Magnus Holmgren
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "dsa.h"
+
+#include "bignum.h"
+#include "asn1.h"
+
+#define GET(i, x, l)                                   \
+(asn1_der_iterator_next((i)) == ASN1_ITERATOR_PRIMITIVE        \
+ && (i)->type == ASN1_INTEGER                          \
+ && asn1_der_get_bignum((i), (x), (l))                 \
+ && mpz_sgn((x)) > 0)
+
+int
+dsa_params_from_der_iterator(struct dsa_public_key *pub,
+                            unsigned p_max_bits,
+                            struct asn1_der_iterator *i)
+{
+  /* Dss-Parms ::= SEQUENCE {
+        p  INTEGER,
+        q  INTEGER,
+        g  INTEGER
+     }
+  */
+  return (i->type == ASN1_INTEGER
+         && asn1_der_get_bignum(i, pub->p, p_max_bits)
+         && mpz_sgn(pub->p) > 0
+         && GET(i, pub->q, DSA_SHA1_Q_BITS)
+         && GET(i, pub->g, p_max_bits)
+         && asn1_der_iterator_next(i) == ASN1_ITERATOR_END);
+}
+
+int
+dsa_public_key_from_der_iterator(struct dsa_public_key *pub,
+                                unsigned p_max_bits,
+                                struct asn1_der_iterator *i)
+{
+  /* DSAPublicKey ::= INTEGER
+  */
+
+  return (i->type == ASN1_INTEGER
+         && asn1_der_get_bignum(i, pub->y, p_max_bits)
+         && mpz_sgn(pub->y) > 0);
+}
+
+int
+dsa_openssl_private_key_from_der_iterator(struct dsa_public_key *pub,
+                                         struct dsa_private_key *priv,
+                                         unsigned p_max_bits,
+                                         struct asn1_der_iterator *i)
+{
+  /* DSAPrivateKey ::= SEQUENCE {
+         version           Version,
+        p                 INTEGER,
+        q                 INTEGER,
+        g                 INTEGER,
+        pub_key           INTEGER,  -- y
+        priv_key          INTEGER,  -- x
+    }
+  */
+
+  uint32_t version;
+  
+  return (i->type == ASN1_SEQUENCE
+         && asn1_der_decode_constructed_last(i) == ASN1_ITERATOR_PRIMITIVE
+         && i->type == ASN1_INTEGER
+         && asn1_der_get_uint32(i, &version)
+         && version == 0
+         && GET(i, pub->p, p_max_bits)
+         && GET(i, pub->q, DSA_SHA1_Q_BITS)
+         && GET(i, pub->g, p_max_bits)
+         && GET(i, pub->y, p_max_bits)
+         && GET(i, priv->x, DSA_SHA1_Q_BITS)
+         && asn1_der_iterator_next(i) == ASN1_ITERATOR_END);
+}
+
+int
+dsa_openssl_private_key_from_der(struct dsa_public_key *pub,
+                    struct dsa_private_key *priv,
+                    unsigned p_max_bits,
+                    unsigned length, const uint8_t *data)
+{
+  struct asn1_der_iterator i;
+  enum asn1_iterator_result res;
+
+  res = asn1_der_iterator_first(&i, length, data);
+
+  return (res == ASN1_ITERATOR_CONSTRUCTED
+         && dsa_openssl_private_key_from_der_iterator(pub, priv, p_max_bits, &i));
+}
diff --git a/der2rsa.c b/der2rsa.c
new file mode 100644 (file)
index 0000000..679b336
--- /dev/null
+++ b/der2rsa.c
@@ -0,0 +1,133 @@
+/* der2rsa.c
+ *
+ * Decoding of keys in PKCS#1 format.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2005 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "rsa.h"
+
+#include "bignum.h"
+#include "asn1.h"
+
+#define GET(i, x, l)                                   \
+(asn1_der_iterator_next((i)) == ASN1_ITERATOR_PRIMITIVE        \
+ && (i)->type == ASN1_INTEGER                          \
+ && asn1_der_get_bignum((i), (x), (l))                 \
+ && mpz_sgn((x)) > 0)
+
+int
+rsa_public_key_from_der_iterator(struct rsa_public_key *pub,
+                                unsigned limit,
+                                struct asn1_der_iterator *i)
+{
+  /* RSAPublicKey ::= SEQUENCE {
+         modulus           INTEGER,  -- n
+        publicExponent    INTEGER   -- e
+      }
+  */
+
+  return (i->type == ASN1_SEQUENCE
+         && asn1_der_decode_constructed_last(i) == ASN1_ITERATOR_PRIMITIVE
+         && asn1_der_get_bignum(i, pub->n, limit) 
+         && mpz_sgn(pub->n) > 0
+         && GET(i, pub->e, limit)
+         && asn1_der_iterator_next(i) == ASN1_ITERATOR_END
+         && rsa_public_key_prepare(pub));
+}
+
+int
+rsa_private_key_from_der_iterator(struct rsa_public_key *pub,
+                                 struct rsa_private_key *priv,
+                                 unsigned limit,
+                                 struct asn1_der_iterator *i)
+{
+  /* RSAPrivateKey ::= SEQUENCE {
+         version           Version,
+        modulus           INTEGER,  -- n
+        publicExponent    INTEGER,  -- e
+        privateExponent   INTEGER,  -- d
+        prime1            INTEGER,  -- p
+        prime2            INTEGER,  -- q
+        exponent1         INTEGER,  -- d mod (p-1)
+        exponent2         INTEGER,  -- d mod (q-1)
+        coefficient       INTEGER,  -- (inverse of q) mod p
+        otherPrimeInfos   OtherPrimeInfos OPTIONAL
+    }
+  */
+
+  uint32_t version;
+  
+  if (i->type != ASN1_SEQUENCE)
+    return 0;
+
+  if (asn1_der_decode_constructed_last(i) == ASN1_ITERATOR_PRIMITIVE
+      && i->type == ASN1_INTEGER
+      && asn1_der_get_uint32(i, &version)
+      && version <= 1
+      && GET(i, pub->n, limit)
+      && GET(i, pub->e, limit)
+      && rsa_public_key_prepare(pub)
+      && GET(i, priv->d, limit)
+      && GET(i, priv->p, limit)
+      && GET(i, priv->q, limit)
+      && GET(i, priv->a, limit)
+      && GET(i, priv->b, limit)
+      && GET(i, priv->c, limit)
+      && rsa_private_key_prepare(priv))
+    {
+      if (version == 1)
+       {
+         /* otherPrimeInfos must be present. We ignore the contents */
+         if (!(asn1_der_iterator_next(i) == ASN1_ITERATOR_CONSTRUCTED
+               && i->type == ASN1_SEQUENCE))
+           return 0;
+       }
+
+      return (asn1_der_iterator_next(i) == ASN1_ITERATOR_END);
+    }
+  
+  return 0;
+}
+
+int
+rsa_keypair_from_der(struct rsa_public_key *pub,
+                    struct rsa_private_key *priv,
+                    unsigned limit, 
+                    unsigned length, const uint8_t *data)
+{
+  struct asn1_der_iterator i;
+  enum asn1_iterator_result res;
+
+  res = asn1_der_iterator_first(&i, length, data);
+
+  if (res != ASN1_ITERATOR_CONSTRUCTED)
+    return 0;
+
+  if (priv)
+    return rsa_private_key_from_der_iterator(pub, priv, limit, &i);
+  else
+    return rsa_public_key_from_der_iterator(pub, limit, &i);    
+}
diff --git a/des-compat.c b/des-compat.c
new file mode 100644 (file)
index 0000000..cd8cd1d
--- /dev/null
@@ -0,0 +1,222 @@
+/* des-compat.h
+ *
+ * The des block cipher, libdes/openssl-style interface.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+#include <assert.h>
+
+#include "des-compat.h"
+
+#include "cbc.h"
+#include "macros.h"
+#include "memxor.h"
+
+struct des_compat_des3 { const struct des_ctx *keys[3]; }; 
+
+static void
+des_compat_des3_encrypt(struct des_compat_des3 *ctx,
+                       uint32_t length, uint8_t *dst, const uint8_t *src)
+{
+  nettle_des_encrypt(ctx->keys[0], length, dst, src);
+  nettle_des_decrypt(ctx->keys[1], length, dst, dst);
+  nettle_des_encrypt(ctx->keys[2], length, dst, dst);
+}
+
+static void
+des_compat_des3_decrypt(struct des_compat_des3 *ctx,
+                       uint32_t length, uint8_t *dst, const uint8_t *src)
+{
+  nettle_des_decrypt(ctx->keys[2], length, dst, src);
+  nettle_des_encrypt(ctx->keys[1], length, dst, dst);
+  nettle_des_decrypt(ctx->keys[0], length, dst, dst);
+}
+
+void
+des_ecb3_encrypt(const_des_cblock *src, des_cblock *dst,
+                des_key_schedule k1,
+                des_key_schedule k2,
+                des_key_schedule k3, int enc)
+{
+  struct des_compat_des3 keys;
+  keys.keys[0] = k1;
+  keys.keys[1] = k2;
+  keys.keys[2] = k3;
+
+  ((enc == DES_ENCRYPT) ? des_compat_des3_encrypt : des_compat_des3_decrypt)
+    (&keys, DES_BLOCK_SIZE, *dst, *src);
+}
+
+/* If input is not a integral number of blocks, the final block is
+   padded with zeros, no length field or anything like that. That's
+   pretty broken, since it means that "$100" and "$100\0" always have
+   the same checksum, but I think that's how it's supposed to work. */
+uint32_t
+des_cbc_cksum(const uint8_t *src, des_cblock *dst,
+             long length, des_key_schedule ctx,
+             const_des_cblock *iv)
+{
+  /* FIXME: I'm not entirely sure how this function is supposed to
+   * work, in particular what it should return, and if iv can be
+   * modified. */
+  uint8_t block[DES_BLOCK_SIZE];
+
+  memcpy(block, *iv, DES_BLOCK_SIZE);
+
+  while (length >= DES_BLOCK_SIZE)
+    {
+      memxor(block, src, DES_BLOCK_SIZE);
+      nettle_des_encrypt(ctx, DES_BLOCK_SIZE, block, block);
+
+      src += DES_BLOCK_SIZE;
+      length -= DES_BLOCK_SIZE;          
+    }
+  if (length > 0)
+    {
+      memxor(block, src, length);
+      nettle_des_encrypt(ctx, DES_BLOCK_SIZE, block, block);     
+    }
+  memcpy(*dst, block, DES_BLOCK_SIZE);
+
+  return LE_READ_UINT32(block + 4);
+}
+
+void
+des_ncbc_encrypt(const_des_cblock *src, des_cblock *dst, long length,
+                 des_key_schedule ctx, des_cblock *iv,
+                 int enc)
+{
+  switch (enc)
+    {
+    case DES_ENCRYPT:
+      nettle_cbc_encrypt(ctx, (nettle_crypt_func *) des_encrypt,
+                        DES_BLOCK_SIZE, *iv,
+                        length, *dst, *src);
+      break;
+    case DES_DECRYPT:
+      nettle_cbc_decrypt(ctx,
+                        (nettle_crypt_func *) des_decrypt,
+                        DES_BLOCK_SIZE, *iv,
+                        length, *dst, *src);
+      break;
+    default:
+      abort();
+    }
+}
+
+void
+des_cbc_encrypt(const_des_cblock *src, des_cblock *dst, long length,
+               des_key_schedule ctx, const_des_cblock *civ,
+               int enc)
+{
+  des_cblock iv;
+
+  memcpy(iv, civ, DES_BLOCK_SIZE);
+
+  des_ncbc_encrypt(src, dst, length, ctx, &iv, enc);
+}
+
+
+void
+des_ecb_encrypt(const_des_cblock *src, des_cblock *dst,
+               des_key_schedule ctx,
+               int enc)
+{
+  ((enc == DES_ENCRYPT) ? nettle_des_encrypt : nettle_des_decrypt)
+    (ctx, DES_BLOCK_SIZE, *dst, *src);
+}
+
+void
+des_ede3_cbc_encrypt(const_des_cblock *src, des_cblock *dst, long length,
+                    des_key_schedule k1,
+                    des_key_schedule k2,
+                    des_key_schedule k3,
+                    des_cblock *iv,
+                    int enc)
+{
+  struct des_compat_des3 keys;
+  keys.keys[0] = k1;
+  keys.keys[1] = k2;
+  keys.keys[2] = k3;
+
+  switch (enc)
+    {
+    case DES_ENCRYPT:
+      nettle_cbc_encrypt(&keys, (nettle_crypt_func *) des_compat_des3_encrypt,
+                        DES_BLOCK_SIZE, *iv,
+                        length, *dst, *src);
+      break;
+    case DES_DECRYPT:
+      nettle_cbc_decrypt(&keys, (nettle_crypt_func *) des_compat_des3_decrypt,
+                        DES_BLOCK_SIZE, *iv,
+                        length, *dst, *src);
+      break;
+    default:
+      abort();
+    }
+}
+
+int
+des_set_odd_parity(des_cblock *key)
+{
+  nettle_des_fix_parity(DES_KEY_SIZE, *key, *key);
+
+  /* FIXME: What to return? */
+  return 0;
+}
+
+
+/* If des_check_key is non-zero, returns
+ *
+ *   0 for ok, -1 for bad parity, and -2 for weak keys.
+ *
+ * If des_check_key is zero (the default), always returns zero.
+ */
+
+int des_check_key = 0;
+
+int
+des_key_sched(const_des_cblock *key, des_key_schedule ctx)
+{
+  if (des_check_key && !des_check_parity (DES_KEY_SIZE, *key))
+    /* Bad parity */
+    return -1;
+  
+  if (!nettle_des_set_key(ctx, *key) && des_check_key)
+    /* Weak key */
+    return -2;
+
+  return 0;
+}
+
+int
+des_is_weak_key(const_des_cblock *key)
+{
+  struct des_ctx ctx;
+
+  return !nettle_des_set_key(&ctx, *key);
+}
diff --git a/des-compat.h b/des-compat.h
new file mode 100644 (file)
index 0000000..8aab3bc
--- /dev/null
@@ -0,0 +1,154 @@
+/* des-compat.h
+ *
+ * The des block cipher, libdes/openssl-style interface.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_DES_COMPAT_H_INCLUDED
+#define NETTLE_DES_COMPAT_H_INCLUDED
+
+/* According to Assar, des_set_key, des_set_key_odd_parity,
+ * des_is_weak_key, plus the encryption functions (des_*_encrypt and
+ * des_cbc_cksum) would be a pretty useful subset. */
+
+/* NOTE: This is quite experimental, and not all functions are
+ * implemented. Contributions, in particular test cases are welcome. */
+
+#include "des.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* We use some name mangling, to avoid collisions with either other
+ * nettle functions or with libcrypto. */
+
+#define des_ecb3_encrypt nettle_openssl_des_ecb3_encrypt
+#define des_cbc_cksum nettle_openssl_des_cbc_cksum
+#define des_ncbc_encrypt nettle_openssl_des_ncbc_encrypt
+#define des_cbc_encrypt nettle_openssl_des_cbc_encrypt
+#define des_ecb_encrypt nettle_openssl_des_ecb_encrypt
+#define des_ede3_cbc_encrypt nettle_openssl_des_ede3_cbc_encrypt
+#define des_set_odd_parity nettle_openssl_des_set_odd_parity
+#define des_check_key nettle_openssl_des_check_key
+#define des_key_sched nettle_openssl_des_key_sched
+#define des_is_weak_key nettle_openssl_des_is_weak_key
+
+/* An extra alias */
+#undef des_set_key
+#define des_set_key nettle_openssl_des_key_sched
+
+enum { DES_DECRYPT = 0, DES_ENCRYPT = 1 };
+
+/* Types */
+typedef uint32_t DES_LONG;
+
+/* Note: Typedef:ed arrays should be avoided, but they're used here
+ * for compatibility. */
+typedef struct des_ctx des_key_schedule[1];
+
+typedef uint8_t des_cblock[DES_BLOCK_SIZE];
+/* Note: The proper definition,
+
+     typedef const uint8_t const_des_cblock[DES_BLOCK_SIZE];
+
+   would have worked, *if* all the prototypes had used arguments like
+   foo(const_des_cblock src, des_cblock dst), letting argument arrays
+   "decay" into pointers of type uint8_t * and const uint8_t *.
+
+   But since openssl's prototypes use *pointers* const_des_cblock *src,
+   des_cblock *dst, this ends up in type conflicts, and the workaround
+   is to not use const at all.
+*/
+#define const_des_cblock des_cblock
+
+/* Aliases */
+#define des_ecb2_encrypt(i,o,k1,k2,e) \
+       des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+       des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+/* Global flag */
+extern int des_check_key;
+
+/* Prototypes */
+
+/* Typing is a little confusing. Since both des_cblock and
+   des_key_schedule are typedef:ed arrays, it automatically decay to
+   a pointers.
+
+   But the functions are declared taking pointers to des_cblock, i.e.
+   pointers to arrays. And on the other hand, they take plain
+   des_key_schedule arguments, which is equivalent to pointers to
+   struct des_ctx.  */
+void
+des_ecb3_encrypt(const_des_cblock *src, des_cblock *dst,
+                des_key_schedule k1,
+                des_key_schedule k2,
+                des_key_schedule k3, int enc);
+
+/* des_cbc_cksum in libdes returns a 32 bit integer, representing the
+ * latter half of the output block, using little endian byte order. */
+uint32_t
+des_cbc_cksum(const uint8_t *src, des_cblock *dst,
+              long length, des_key_schedule ctx,
+              const_des_cblock *iv);
+
+/* NOTE: Doesn't update iv. */
+void
+des_cbc_encrypt(const_des_cblock *src, des_cblock *dst, long length,
+               des_key_schedule ctx, const_des_cblock *iv,
+               int enc);
+
+/* Similar, but updates iv. */
+void
+des_ncbc_encrypt(const_des_cblock *src, des_cblock *dst, long length,
+                des_key_schedule ctx, des_cblock *iv,
+                 int enc);
+
+void
+des_ecb_encrypt(const_des_cblock *src, des_cblock *dst,
+               des_key_schedule ctx, int enc);
+
+void
+des_ede3_cbc_encrypt(const_des_cblock *src, des_cblock *dst, long length,
+                    des_key_schedule k1,
+                    des_key_schedule k2,
+                    des_key_schedule k3,
+                    des_cblock *iv,
+                    int enc);
+
+int
+des_set_odd_parity(des_cblock *key);
+
+int
+des_key_sched(const_des_cblock *key, des_key_schedule ctx);
+
+int
+des_is_weak_key(const_des_cblock *key);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_DES_COMPAT_H_INCLUDED */
diff --git a/des.c b/des.c
new file mode 100644 (file)
index 0000000..7faadd0
--- /dev/null
+++ b/des.c
@@ -0,0 +1,296 @@
+/* des.c
+ *
+ * The des block cipher.
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/*     des - fast & portable DES encryption & decryption.
+ *     Copyright (C) 1992  Dana L. How
+ *     Please see the file `descore.README' for the complete copyright notice.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "des.h"
+
+#include "desCode.h"
+
+/* various tables */
+
+static const uint32_t
+des_keymap[] = {
+#include       "keymap.h"
+};
+
+static const uint8_t
+rotors[] = {
+#include       "rotors.h"
+};
+
+static ENCRYPT(DesSmallFipsEncrypt,TEMPSMALL, LOADFIPS,KEYMAPSMALL,SAVEFIPS)
+static DECRYPT(DesSmallFipsDecrypt,TEMPSMALL, LOADFIPS,KEYMAPSMALL,SAVEFIPS)
+
+/* If parity bits are used, keys should have odd parity. We use a
+   small table, to not waste any memory on this fairly obscure DES
+   feature. */
+
+static const unsigned
+parity_16[16] =
+{ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
+
+#define PARITY(x) (parity_16[(x)&0xf] ^ parity_16[((x)>>4) & 0xf])
+
+int
+des_check_parity(unsigned length, const uint8_t *key)
+{
+  unsigned i;
+  for (i = 0; i<length; i++)
+    if (!PARITY(key[i]))
+      return 0;
+
+  return 1;
+}
+
+void
+des_fix_parity(unsigned length, uint8_t *dst,
+              const uint8_t *src)
+{
+  unsigned i;
+  for (i = 0; i<length; i++)
+    dst[i] = src[i] ^ PARITY(src[i]) ^ 1;
+}
+
+/* Weak and semiweak keys, excluding parity:
+ *
+ * 00 00 00 00  00 00 00 00
+ * 7f 7f 7f 7f  7f 7f 7f 7f 
+ * 0f 0f 0f 0f  07 07 07 07
+ * 70 70 70 70  78 78 78 78
+ *
+ * 00 7f 00 7f  00 7f 00 7f
+ * 7f 00 7f 00  7f 00 7f 00
+ *
+ * 0f 70 0f 70  07 78 07 78
+ * 70 0f 70 0f  78 07 78 07
+ *
+ * 00 70 00 70  00 78 00 78
+ * 70 00 70 00  78 00 78 00
+ *
+ * 0f 7f 0f 7f  07 7f 07 7f
+ * 7f 0f 7f 0f  7f 07 7f 07
+ *
+ * 00 0f 00 0f  00 07 00 07
+ * 0f 00 0f 00  07 00 07 00
+ *
+ * 70 7f 70 7f  78 7f 78 7f
+ * 7f 70 7f 70  7f 78 7f 78
+ */
+
+static int
+des_weak_p(const uint8_t *key)
+{
+  /* Hash function generated using gperf. */
+  static const unsigned char asso_values[0x81] =
+    {
+      16,  9, 26, 26, 26, 26, 26, 26, 26, 26,
+      26, 26, 26, 26, 26,  6,  2, 26, 26, 26,
+      26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+      26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+      26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+      26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+      26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+      26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+      26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+      26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+      26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+      26, 26,  3,  1, 26, 26, 26, 26, 26, 26,
+      26, 26, 26, 26, 26, 26, 26,  0,  0
+    };
+
+  static const int8_t weak_key_hash[26][4] =
+    {
+      /*  0 */ {0x7f,0x7f, 0x7f,0x7f},
+      /*  1 */ {0x7f,0x70, 0x7f,0x78},
+      /*  2 */ {0x7f,0x0f, 0x7f,0x07},
+      /*  3 */ {0x70,0x7f, 0x78,0x7f},
+      /*  4 */ {0x70,0x70, 0x78,0x78},
+      /*  5 */ {0x70,0x0f, 0x78,0x07},
+      /*  6 */ {0x0f,0x7f, 0x07,0x7f},
+      /*  7 */ {0x0f,0x70, 0x07,0x78},
+      /*  8 */ {0x0f,0x0f, 0x07,0x07},
+      /*  9 */ {0x7f,0x00, 0x7f,0x00},
+      /* 10 */ {-1,-1,-1,-1},
+      /* 11 */ {-1,-1,-1,-1},
+      /* 12 */ {0x70,0x00, 0x78,0x00},
+      /* 13 */ {-1,-1,-1,-1},
+      /* 14 */ {-1,-1,-1,-1},
+      /* 15 */ {0x0f,0x00, 0x07,0x00},
+      /* 16 */ {0x00,0x7f, 0x00,0x7f},
+      /* 17 */ {0x00,0x70, 0x00,0x78},
+      /* 18 */ {0x00,0x0f, 0x00,0x07},
+      /* 19 */ {-1,-1,-1,-1},
+      /* 20 */ {-1,-1,-1,-1},
+      /* 21 */ {-1,-1,-1,-1},
+      /* 22 */ {-1,-1,-1,-1},
+      /* 23 */ {-1,-1,-1,-1},
+      /* 24 */ {-1,-1,-1,-1},
+      /* 25 */ {0x00,0x00, 0x00,0x00}
+    };
+
+  int8_t k0 = key[0] >> 1;
+  int8_t k1 = key[1] >> 1;
+
+  unsigned hash = asso_values[k1 + 1] + asso_values[k0];
+  const int8_t *candidate = weak_key_hash[hash];
+
+  if (hash > 25)
+    return 0;
+  if (k0 != candidate[0]
+      || k1 != candidate[1])
+    return 0;
+  
+  if ( (key[2] >> 1) != k0
+       || (key[3] >> 1) != k1)
+    return 0;
+
+  k0 = key[4] >> 1;
+  k1 = key[5] >> 1;
+  if (k0 != candidate[2]
+      || k1 != candidate[3])
+    return 0;
+  if ( (key[6] >> 1) != k0
+       || (key[7] >> 1) != k1)
+    return 0;
+
+  return 1;
+}
+
+int
+des_set_key(struct des_ctx *ctx, const uint8_t *key)
+{
+  register uint32_t n, w;
+  register char * b0, * b1;
+  char bits0[56], bits1[56];
+  uint32_t *method;
+  const uint8_t *k;
+
+  /* explode the bits */
+  n = 56;
+  b0 = bits0;
+  b1 = bits1;
+  k = key;
+  do {
+    w = (256 | *k++) << 2;
+    do {
+      --n;
+      b1[n] = 8 & w;
+      w >>= 1;
+      b0[n] = 4 & w;
+    } while ( w >= 16 );
+  } while ( n );
+
+  /* put the bits in the correct places */
+  n = 16;
+  k = rotors;
+  method = ctx->key;
+  
+  do {
+    w   = (b1[k[ 0   ]] | b0[k[ 1   ]]) << 4;
+    w  |= (b1[k[ 2   ]] | b0[k[ 3   ]]) << 2;
+    w  |=  b1[k[ 4   ]] | b0[k[ 5   ]];
+    w <<= 8;
+    w  |= (b1[k[ 6   ]] | b0[k[ 7   ]]) << 4;
+    w  |= (b1[k[ 8   ]] | b0[k[ 9   ]]) << 2;
+    w  |=  b1[k[10   ]] | b0[k[11   ]];
+    w <<= 8;
+    w  |= (b1[k[12   ]] | b0[k[13   ]]) << 4;
+    w  |= (b1[k[14   ]] | b0[k[15   ]]) << 2;
+    w  |=  b1[k[16   ]] | b0[k[17   ]];
+    w <<= 8;
+    w  |= (b1[k[18   ]] | b0[k[19   ]]) << 4;
+    w  |= (b1[k[20   ]] | b0[k[21   ]]) << 2;
+    w  |=  b1[k[22   ]] | b0[k[23   ]];
+
+    method[0] = w;
+
+    w   = (b1[k[ 0+24]] | b0[k[ 1+24]]) << 4;
+    w  |= (b1[k[ 2+24]] | b0[k[ 3+24]]) << 2;
+    w  |=  b1[k[ 4+24]] | b0[k[ 5+24]];
+    w <<= 8;
+    w  |= (b1[k[ 6+24]] | b0[k[ 7+24]]) << 4;
+    w  |= (b1[k[ 8+24]] | b0[k[ 9+24]]) << 2;
+    w  |=  b1[k[10+24]] | b0[k[11+24]];
+    w <<= 8;
+    w  |= (b1[k[12+24]] | b0[k[13+24]]) << 4;
+    w  |= (b1[k[14+24]] | b0[k[15+24]]) << 2;
+    w  |=  b1[k[16+24]] | b0[k[17+24]];
+    w <<= 8;
+    w  |= (b1[k[18+24]] | b0[k[19+24]]) << 4;
+    w  |= (b1[k[20+24]] | b0[k[21+24]]) << 2;
+    w  |=  b1[k[22+24]] | b0[k[23+24]];
+
+    ROR(w, 4, 28);             /* could be eliminated */
+    method[1] = w;
+
+    k  += 48;
+    method     += 2;
+  } while ( --n );
+
+  return !des_weak_p (key);
+}
+
+void
+des_encrypt(const struct des_ctx *ctx,
+           unsigned length, uint8_t *dst,
+           const uint8_t *src)
+{
+  assert(!(length % DES_BLOCK_SIZE));
+  
+  while (length)
+    {
+      DesSmallFipsEncrypt(dst, ctx->key, src);
+      length -= DES_BLOCK_SIZE;
+      src += DES_BLOCK_SIZE;
+      dst += DES_BLOCK_SIZE;
+    }
+}
+
+void
+des_decrypt(const struct des_ctx *ctx,
+           unsigned length, uint8_t *dst,
+           const uint8_t *src)
+{
+  assert(!(length % DES_BLOCK_SIZE));
+
+  while (length)
+    {
+      DesSmallFipsDecrypt(dst, ctx->key, src);
+      length -= DES_BLOCK_SIZE;
+      src += DES_BLOCK_SIZE;
+      dst += DES_BLOCK_SIZE;
+    }
+}
diff --git a/des.h b/des.h
new file mode 100644 (file)
index 0000000..3f0f9ef
--- /dev/null
+++ b/des.h
@@ -0,0 +1,111 @@
+/* des.h
+ *
+ * The des block cipher. And triple des.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 1992, 2001, Dana L. How, Niels Möller
+ * 
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/*
+ *     des - fast & portable DES encryption & decryption.
+ *     Copyright (C) 1992  Dana L. How
+ *     Please see the file `../lib/descore.README' for the complete copyright
+ *     notice.
+ *
+ * Slightly edited by Niels Möller, 1997
+ */
+
+#ifndef NETTLE_DES_H_INCLUDED
+#define NETTLE_DES_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Namespace mangling */
+#define des_set_key nettle_des_set_key
+#define des_encrypt nettle_des_encrypt
+#define des_decrypt nettle_des_decrypt
+#define des_check_parity nettle_des_check_parity
+#define des_fix_parity nettle_des_fix_parity
+#define des3_set_key nettle_des3_set_key
+#define des3_encrypt nettle_des3_encrypt
+#define des3_decrypt nettle_des3_decrypt
+
+#define DES_KEY_SIZE 8
+#define DES_BLOCK_SIZE 8
+
+/* Expanded key length */
+#define _DES_KEY_LENGTH 32
+
+struct des_ctx
+{
+  uint32_t key[_DES_KEY_LENGTH];
+};
+
+/* Returns 1 for good keys and 0 for weak keys. */
+int
+des_set_key(struct des_ctx *ctx, const uint8_t *key);
+
+void
+des_encrypt(const struct des_ctx *ctx,
+           unsigned length, uint8_t *dst,
+           const uint8_t *src);
+void
+des_decrypt(const struct des_ctx *ctx,
+           unsigned length, uint8_t *dst,
+           const uint8_t *src);
+
+int
+des_check_parity(unsigned length, const uint8_t *key);
+
+void
+des_fix_parity(unsigned length, uint8_t *dst,
+              const uint8_t *src);
+
+#define DES3_KEY_SIZE 24
+#define DES3_BLOCK_SIZE DES_BLOCK_SIZE
+
+struct des3_ctx
+{
+  struct des_ctx des[3];
+};
+
+
+/* Returns 1 for good keys and 0 for weak keys. */
+int
+des3_set_key(struct des3_ctx *ctx, const uint8_t *key);
+
+void
+des3_encrypt(const struct des3_ctx *ctx,
+            unsigned length, uint8_t *dst,
+            const uint8_t *src);
+void
+des3_decrypt(const struct des3_ctx *ctx,
+            unsigned length, uint8_t *dst,
+            const uint8_t *src);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_DES_H_INCLUDED */
diff --git a/des3.c b/des3.c
new file mode 100644 (file)
index 0000000..e574abf
--- /dev/null
+++ b/des3.c
@@ -0,0 +1,74 @@
+/* des3.h
+ *
+ * Triple DES cipher. Three key encrypt-decrypt-encrypt.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "des.h"
+
+/* It's possible to make some more general pipe construction, like the
+ * lsh/src/cascade.c, but as in practice it's never used for anything
+ * like triple DES, it's not worth the effort. */
+
+/* Returns 1 for good keys and 0 for weak keys. */
+int
+des3_set_key(struct des3_ctx *ctx, const uint8_t *key)
+{
+  unsigned i;
+  int is_good = 1;
+  
+  for (i = 0; i<3; i++, key += DES_KEY_SIZE)
+    if (!des_set_key(&ctx->des[i], key))
+      is_good = 0;
+
+  return is_good;
+}
+
+void
+des3_encrypt(const struct des3_ctx *ctx,
+            unsigned length, uint8_t *dst,
+            const uint8_t *src)
+{
+  des_encrypt(&ctx->des[0],
+             length, dst, src);
+  des_decrypt(&ctx->des[1],
+             length, dst, dst);
+  des_encrypt(&ctx->des[2],
+             length, dst, dst);
+}
+
+void
+des3_decrypt(const struct des3_ctx *ctx,
+            unsigned length, uint8_t *dst,
+            const uint8_t *src)
+{
+  des_decrypt(&ctx->des[2],
+             length, dst, src);
+  des_encrypt(&ctx->des[1],
+             length, dst, dst);
+  des_decrypt(&ctx->des[0],
+             length, dst, dst);
+} 
diff --git a/desCode.h b/desCode.h
new file mode 100644 (file)
index 0000000..6c18fab
--- /dev/null
+++ b/desCode.h
@@ -0,0 +1,412 @@
+/* desCode.h
+ *
+ * $Id: desCode.h,v 1.1 2007-04-05 14:20:35 nisse Exp $ */
+
+/*     des - fast & portable DES encryption & decryption.
+ *     Copyright (C) 1992  Dana L. How
+ *     Please see the file `descore.README' for the complete copyright notice.
+ */
+
+#include "des.h"
+
+/* optional customization:
+ * the idea here is to alter the code so it will still run correctly
+ * on any machine,  but the quickest on the specific machine in mind.
+ * note that these silly tweaks can give you a 15%-20% speed improvement
+ * on the sparc -- it's probably even more significant on the 68000. */
+
+/* take care of machines with incredibly few registers */
+#if    defined(i386)
+#define        REGISTER                /* only x, y, z will be declared register */
+#else
+#define        REGISTER        register
+#endif /* i386 */
+
+/* is auto inc/dec faster than 7bit unsigned indexing? */
+#if    defined(vax) || defined(mc68000)
+#define        FIXR            r += 32;
+#define        FIXS            s +=  8;
+#define        PREV(v,o)       *--v
+#define        NEXT(v,o)       *v++
+#else
+#define        FIXR
+#define        FIXS
+#define        PREV(v,o)       v[o]
+#define        NEXT(v,o)       v[o]
+#endif
+
+/* if no machine type, default is indexing, 6 registers and cheap literals */
+#if    !defined(i386) && !defined(vax) && !defined(mc68000) && !defined(sparc)
+#define        vax
+#endif
+
+
+/* handle a compiler which can't reallocate registers */
+/* The BYTE type is used as parameter for the encrypt/decrypt functions.
+ * It's pretty bad to have the function prototypes depend on
+ * a macro definition that the users of the function doesn't
+ * know about. /Niels */
+#if    0                       /* didn't feel like deleting */
+#define        SREGFREE        ; s = (uint8_t *) D
+#define        DEST            s
+#define        D               m0
+#define        BYTE            uint32_t
+#else
+#define        SREGFREE
+#define        DEST            d
+#define        D               d
+#define        BYTE            uint8_t
+#endif
+
+/* handle constants in the optimal way for 386 & vax */
+/* 386: we declare 3 register variables (see above) and use 3 more variables;
+ * vax: we use 6 variables, all declared register;
+ * we assume address literals are cheap & unrestricted;
+ * we assume immediate constants are cheap & unrestricted. */
+#if    defined(i386) || defined(vax)
+#define        MQ0      des_bigmap
+#define        MQ1     (des_bigmap +  64)
+#define        MQ2     (des_bigmap + 128)
+#define        MQ3     (des_bigmap + 192)
+#define        HQ0(z)                          /*      z |= 0x01000000L; */
+#define        HQ2(z)                          /*      z |= 0x03000200L; */
+#define        LQ0(z)  0xFCFC & z
+#define        LQ1(z)  0xFCFC & z
+#define        LQ2(z)  0xFCFC & z
+#define        LQ3(z)  0xFCFC & z
+#define        SQ      16
+#define        MS0      des_keymap 
+#define        MS1     (des_keymap +  64)
+#define        MS2     (des_keymap + 128)
+#define        MS3     (des_keymap + 192)
+#define        MS4     (des_keymap + 256)
+#define        MS5     (des_keymap + 320)
+#define        MS6     (des_keymap + 384)
+#define        MS7     (des_keymap + 448)
+#define        HS(z)
+#define        LS0(z)  0xFC & z
+#define        LS1(z)  0xFC & z
+#define        LS2(z)  0xFC & z
+#define        LS3(z)  0xFC & z
+#define        REGQUICK
+#define        SETQUICK
+#define        REGSMALL
+#define        SETSMALL
+#endif /* defined(i386) || defined(vax) */
+
+/* handle constants in the optimal way for mc68000 */
+/* in addition to the core 6 variables, we declare 3 registers holding constants
+ * and 4 registers holding address literals.
+ * at most 6 data values and 5 address values are actively used at once.
+ * we assume address literals are so expensive we never use them;
+ * we assume constant index offsets > 127 are expensive, so they are not used.
+ * we assume all constants are expensive and put them in registers,
+ * including shift counts greater than 8. */
+#if    defined(mc68000)
+#define        MQ0     m0
+#define        MQ1     m1
+#define        MQ2     m2
+#define        MQ3     m3
+#define        HQ0(z)
+#define        HQ2(z)
+#define        LQ0(z)  k0 & z
+#define        LQ1(z)  k0 & z
+#define        LQ2(z)  k0 & z
+#define        LQ3(z)  k0 & z
+#define        SQ      k1
+#define        MS0     m0
+#define        MS1     m0
+#define        MS2     m1
+#define        MS3     m1
+#define        MS4     m2
+#define        MS5     m2
+#define        MS6     m3
+#define        MS7     m3
+#define        HS(z)   z |= k0;
+#define        LS0(z)  k1 & z
+#define        LS1(z)  k2 & z
+#define        LS2(z)  k1 & z
+#define        LS3(z)  k2 & z
+#define        REGQUICK                                \
+       register uint32_t k0, k1;               \
+       register uint32_t *m0, *m1, *m2, *m3;
+#define        SETQUICK                                \
+       ; k0 = 0xFCFC                           \
+       ; k1 = 16                               \
+       /*k2 = 28 to speed up ROL */            \
+       ; m0 = des_bigmap                       \
+       ; m1 = m0 + 64                          \
+       ; m2 = m1 + 64                          \
+       ; m3 = m2 + 64
+#define        REGSMALL                                \
+       register uint32_t k0, k1, k2;           \
+       register uint32_t *m0, *m1, *m2, *m3;
+#define        SETSMALL                                \
+       ; k0 = 0x01000100L                      \
+       ; k1 = 0x0FC                            \
+       ; k2 = 0x1FC                            \
+       ; m0 = des_keymap                       \
+       ; m1 = m0 + 128                         \
+       ; m2 = m1 + 128                         \
+       ; m3 = m2 + 128
+#endif /* defined(mc68000) */
+
+/* handle constants in the optimal way for sparc */
+/* in addition to the core 6 variables, we either declare:
+ * 4 registers holding address literals and 1 register holding a constant, or
+ * 8 registers holding address literals.
+ * up to 14 register variables are declared (sparc has %i0-%i5, %l0-%l7).
+ * we assume address literals are so expensive we never use them;
+ * we assume any constant with >10 bits is expensive and put it in a register,
+ * and any other is cheap and is coded in-line. */
+#if    defined(sparc)
+#define        MQ0     m0
+#define        MQ1     m1
+#define        MQ2     m2
+#define        MQ3     m3
+#define        HQ0(z)
+#define        HQ2(z)
+#define        LQ0(z)  k0 & z
+#define        LQ1(z)  k0 & z
+#define        LQ2(z)  k0 & z
+#define        LQ3(z)  k0 & z
+#define        SQ      16
+#define        MS0     m0
+#define        MS1     m1
+#define        MS2     m2
+#define        MS3     m3
+#define        MS4     m4
+#define        MS5     m5
+#define        MS6     m6
+#define        MS7     m7
+#define        HS(z)
+#define        LS0(z)  0xFC & z
+#define        LS1(z)  0xFC & z
+#define        LS2(z)  0xFC & z
+#define        LS3(z)  0xFC & z
+#define        REGQUICK                                \
+       register uint32_t k0;                   \
+       register uint32_t *m0, *m1, *m2, *m3;
+#define        SETQUICK                                \
+       ; k0 = 0xFCFC                           \
+       ; m0 = des_bigmap                       \
+       ; m1 = m0 + 64                          \
+       ; m2 = m1 + 64                          \
+       ; m3 = m2 + 64
+#define        REGSMALL                                \
+       register uint32_t *m0, *m1, *m2, *m3, *m4, *m5, *m6, *m7;
+#define        SETSMALL                                \
+       ; m0 = des_keymap                       \
+       ; m1 = m0 + 64                          \
+       ; m2 = m1 + 64                          \
+       ; m3 = m2 + 64                          \
+       ; m4 = m3 + 64                          \
+       ; m5 = m4 + 64                          \
+       ; m6 = m5 + 64                          \
+       ; m7 = m6 + 64
+#endif /* defined(sparc) */
+
+
+/* some basic stuff */
+
+/* generate addresses from a base and an index */
+/* FIXME: This is used only as *ADD(msi,lsi(z)) or *ADD(mqi,lqi(z)).
+ * Why not use plain indexing instead? /Niels */
+#define        ADD(b,x)        (uint32_t *) ((uint8_t *)b + (x))
+
+/* low level rotate operations */
+#define        NOP(d,c,o)
+#define        ROL(d,c,o)      d = d << c | d >> o
+#define        ROR(d,c,o)      d = d >> c | d << o
+#define        ROL1(d)         ROL(d, 1, 31)
+#define        ROR1(d)         ROR(d, 1, 31)
+
+/* elementary swap for doing IP/FP */
+#define        SWAP(x,y,m,b)                           \
+       z  = ((x >> b) ^ y) & m;                \
+       x ^= z << b;                            \
+       y ^= z
+
+
+/* the following macros contain all the important code fragments */
+
+/* load input data, then setup special registers holding constants */
+#define        TEMPQUICK(LOAD)                         \
+       REGQUICK                                \
+       LOAD()                                  \
+       SETQUICK
+#define        TEMPSMALL(LOAD)                         \
+       REGSMALL                                \
+       LOAD()                                  \
+       SETSMALL
+
+/* load data */
+#define        LOADDATA(x,y)                           \
+       FIXS                                    \
+       y  = PREV(s, 7); y<<= 8;                \
+       y |= PREV(s, 6); y<<= 8;                \
+       y |= PREV(s, 5); y<<= 8;                \
+       y |= PREV(s, 4);                        \
+       x  = PREV(s, 3); x<<= 8;                \
+       x |= PREV(s, 2); x<<= 8;                \
+       x |= PREV(s, 1); x<<= 8;                \
+       x |= PREV(s, 0)                         \
+       SREGFREE
+/* load data without initial permutation and put into efficient position */
+#define        LOADCORE()                              \
+       LOADDATA(x, y);                         \
+       ROR1(x);                                \
+       ROR1(y)
+/* load data, do the initial permutation and put into efficient position */
+#define        LOADFIPS()                              \
+       LOADDATA(y, x);                         \
+       SWAP(x, y, 0x0F0F0F0FL, 004);           \
+       SWAP(y, x, 0x0000FFFFL, 020);           \
+       SWAP(x, y, 0x33333333L, 002);           \
+       SWAP(y, x, 0x00FF00FFL, 010);           \
+       ROR1(x);                                \
+       z  = (x ^ y) & 0x55555555L;             \
+       y ^= z;                                 \
+       x ^= z;                                 \
+       ROR1(y)
+
+
+/* core encryption/decryption operations */
+/* S box mapping and P perm */
+#define        KEYMAPSMALL(x,z,mq0,mq1,hq,lq0,lq1,sq,ms0,ms1,ms2,ms3,hs,ls0,ls1,ls2,ls3)\
+       hs(z)                                   \
+       x ^= *ADD(ms3, ls3(z));                 \
+       z>>= 8;                                 \
+       x ^= *ADD(ms2, ls2(z));                 \
+       z>>= 8;                                 \
+       x ^= *ADD(ms1, ls1(z));                 \
+       z>>= 8;                                 \
+       x ^= *ADD(ms0, ls0(z))
+/* alternate version: use 64k of tables */
+#define        KEYMAPQUICK(x,z,mq0,mq1,hq,lq0,lq1,sq,ms0,ms1,ms2,ms3,hs,ls0,ls1,ls2,ls3)\
+       hq(z)                                   \
+       x ^= *ADD(mq0, lq0(z));                 \
+       z>>= sq;                                \
+       x ^= *ADD(mq1, lq1(z))
+/* apply 24 key bits and do the odd  s boxes */
+#define        S7S1(x,y,z,r,m,KEYMAP,LOAD)             \
+       z  = LOAD(r, m);                        \
+       z ^= y;                                 \
+       KEYMAP(x,z,MQ0,MQ1,HQ0,LQ0,LQ1,SQ,MS0,MS1,MS2,MS3,HS,LS0,LS1,LS2,LS3)
+/* apply 24 key bits and do the even s boxes */
+#define        S6S0(x,y,z,r,m,KEYMAP,LOAD)             \
+       z  = LOAD(r, m);                        \
+       z ^= y;                                 \
+       ROL(z, 4, 28);                          \
+       KEYMAP(x,z,MQ2,MQ3,HQ2,LQ2,LQ3,SQ,MS4,MS5,MS6,MS7,HS,LS0,LS1,LS2,LS3)
+/* actual iterations.  equivalent except for UPDATE & swapping m and n */
+#define        ENCR(x,y,z,r,m,n,KEYMAP)                \
+       S7S1(x,y,z,r,m,KEYMAP,NEXT);            \
+       S6S0(x,y,z,r,n,KEYMAP,NEXT)
+#define        DECR(x,y,z,r,m,n,KEYMAP)                \
+       S6S0(x,y,z,r,m,KEYMAP,PREV);            \
+       S7S1(x,y,z,r,n,KEYMAP,PREV)
+
+/* write out result in correct byte order */
+#define        SAVEDATA(x,y)                           \
+       NEXT(DEST, 0) = x; x>>= 8;              \
+       NEXT(DEST, 1) = x; x>>= 8;              \
+       NEXT(DEST, 2) = x; x>>= 8;              \
+       NEXT(DEST, 3) = x;                      \
+       NEXT(DEST, 4) = y; y>>= 8;              \
+       NEXT(DEST, 5) = y; y>>= 8;              \
+       NEXT(DEST, 6) = y; y>>= 8;              \
+       NEXT(DEST, 7) = y
+/* write out result */
+#define        SAVECORE()                              \
+       ROL1(x);                                \
+       ROL1(y);                                \
+       SAVEDATA(y, x)
+/* do final permutation and write out result */
+#define        SAVEFIPS()                              \
+       ROL1(x);                                \
+       z  = (x ^ y) & 0x55555555L;             \
+       y ^= z;                                 \
+       x ^= z;                                 \
+       ROL1(y);                                \
+       SWAP(x, y, 0x00FF00FFL, 010);           \
+       SWAP(y, x, 0x33333333L, 002);           \
+       SWAP(x, y, 0x0000FFFFL, 020);           \
+       SWAP(y, x, 0x0F0F0F0FL, 004);           \
+       SAVEDATA(x, y)
+
+
+/* the following macros contain the encryption/decryption skeletons */
+
+#define        ENCRYPT(NAME, TEMP, LOAD, KEYMAP, SAVE) \
+                                               \
+void                                           \
+NAME(REGISTER BYTE *D,                         \
+     REGISTER const uint32_t *r,               \
+     REGISTER const uint8_t *s)                        \
+{                                              \
+       register uint32_t x, y, z;              \
+                                               \
+       /* declare temps & load data */         \
+       TEMP(LOAD);                             \
+                                               \
+       /* do the 16 iterations */              \
+       ENCR(x,y,z,r, 0, 1,KEYMAP);             \
+       ENCR(y,x,z,r, 2, 3,KEYMAP);             \
+       ENCR(x,y,z,r, 4, 5,KEYMAP);             \
+       ENCR(y,x,z,r, 6, 7,KEYMAP);             \
+       ENCR(x,y,z,r, 8, 9,KEYMAP);             \
+       ENCR(y,x,z,r,10,11,KEYMAP);             \
+       ENCR(x,y,z,r,12,13,KEYMAP);             \
+       ENCR(y,x,z,r,14,15,KEYMAP);             \
+       ENCR(x,y,z,r,16,17,KEYMAP);             \
+       ENCR(y,x,z,r,18,19,KEYMAP);             \
+       ENCR(x,y,z,r,20,21,KEYMAP);             \
+       ENCR(y,x,z,r,22,23,KEYMAP);             \
+       ENCR(x,y,z,r,24,25,KEYMAP);             \
+       ENCR(y,x,z,r,26,27,KEYMAP);             \
+       ENCR(x,y,z,r,28,29,KEYMAP);             \
+       ENCR(y,x,z,r,30,31,KEYMAP);             \
+                                               \
+       /* save result */                       \
+       SAVE();                                 \
+                                               \
+       return;                                 \
+}
+
+#define        DECRYPT(NAME, TEMP, LOAD, KEYMAP, SAVE) \
+                                               \
+void                                           \
+NAME(REGISTER BYTE *D,                         \
+     REGISTER const uint32_t *r,               \
+     REGISTER const uint8_t *s)                        \
+{                                              \
+       register uint32_t x, y, z;              \
+                                               \
+       /* declare temps & load data */         \
+       TEMP(LOAD);                             \
+                                               \
+       /* do the 16 iterations */              \
+       FIXR                                    \
+       DECR(x,y,z,r,31,30,KEYMAP);             \
+       DECR(y,x,z,r,29,28,KEYMAP);             \
+       DECR(x,y,z,r,27,26,KEYMAP);             \
+       DECR(y,x,z,r,25,24,KEYMAP);             \
+       DECR(x,y,z,r,23,22,KEYMAP);             \
+       DECR(y,x,z,r,21,20,KEYMAP);             \
+       DECR(x,y,z,r,19,18,KEYMAP);             \
+       DECR(y,x,z,r,17,16,KEYMAP);             \
+       DECR(x,y,z,r,15,14,KEYMAP);             \
+       DECR(y,x,z,r,13,12,KEYMAP);             \
+       DECR(x,y,z,r,11,10,KEYMAP);             \
+       DECR(y,x,z,r, 9, 8,KEYMAP);             \
+       DECR(x,y,z,r, 7, 6,KEYMAP);             \
+       DECR(y,x,z,r, 5, 4,KEYMAP);             \
+       DECR(x,y,z,r, 3, 2,KEYMAP);             \
+       DECR(y,x,z,r, 1, 0,KEYMAP);             \
+                                               \
+       /* save result */                       \
+       SAVE();                                 \
+                                               \
+       return;                                 \
+}
diff --git a/descore.README b/descore.README
new file mode 100644 (file)
index 0000000..9fcc3ac
--- /dev/null
@@ -0,0 +1,313 @@
+des - fast & portable DES encryption & decryption.
+Copyright (C) 1992  Dana L. How
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Library 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 Library General Public License for more details.
+
+You should have received a copy of the GNU Library 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
+
+Author's address: how@isl.stanford.edu
+
+$Id: descore.README,v 1.1 2007-04-05 14:20:35 nisse Exp $
+
+
+==>> To compile after untarring/unsharring, just `make' <<==
+
+
+This package was designed with the following goals:
+1.     Highest possible encryption/decryption PERFORMANCE.
+2.     PORTABILITY to any byte-addressable machine with a 32bit unsigned C type
+3.     Plug-compatible replacement for KERBEROS's low-level routines.
+
+
+performance comparison to other available des code which i could
+compile on a SPARCStation 1 (cc -O4):
+
+this code (byte-order independent):
+   30us per encryption (options: 64k tables, no IP/FP)
+   33us per encryption (options: 64k tables, FIPS standard bit ordering)
+   45us per encryption (options:  2k tables, no IP/FP)
+   49us per encryption (options:  2k tables, FIPS standard bit ordering)
+  275us to set a new key (uses 1k of key tables)
+       this has the quickest encryption/decryption routines i've seen.
+       since i was interested in fast des filters rather than crypt(3)
+       and password cracking, i haven't really bothered yet to speed up
+       the key setting routine. also, i have no interest in re-implementing
+       all the other junk in the mit kerberos des library, so i've just
+       provided my routines with little stub interfaces so they can be
+       used as drop-in replacements with mit's code or any of the mit-
+       compatible packages below. (note that the first two timings above
+       are highly variable because of cache effects).
+
+kerberos des replacement from australia:
+   68us per encryption (uses 2k of tables)
+   96us to set a new key (uses 2.25k of key tables)
+       this is a very nice package which implements the most important
+       of the optimizations which i did in my encryption routines.
+       it's a bit weak on common low-level optimizations which is why
+       it's 39%-106% slower.  because he was interested in fast crypt(3) and
+       password-cracking applications,  he also used the same ideas to
+       speed up the key-setting routines with impressive results.
+       (at some point i may do the same in my package).  he also implements
+       the rest of the mit des library.
+       (code from eay@psych.psy.uq.oz.au via comp.sources.misc)
+
+fast crypt(3) package from denmark:
+       the des routine here is buried inside a loop to do the
+       crypt function and i didn't feel like ripping it out and measuring
+       performance. his code takes 26 sparc instructions to compute one
+       des iteration; above, Quick (64k) takes 21 and Small (2k) takes 37.
+       he claims to use 280k of tables but the iteration calculation seems
+       to use only 128k.  his tables and code are machine independent.
+       (code from glad@daimi.aau.dk via alt.sources or comp.sources.misc)
+
+swedish reimplementation of Kerberos des library
+  108us per encryption (uses 34k worth of tables)
+  134us to set a new key (uses 32k of key tables to get this speed!)
+       the tables used seem to be machine-independent;
+       he seems to have included a lot of special case code
+       so that, e.g., `long' loads can be used instead of 4 `char' loads
+       when the machine's architecture allows it.
+       (code obtained from chalmers.se:pub/des)
+
+crack 3.3c package from england:
+       as in crypt above, the des routine is buried in a loop. it's
+       also very modified for crypt.  his iteration code uses 16k
+       of tables and appears to be slow.
+       (code obtained from aem@aber.ac.uk via alt.sources or comp.sources.misc)
+
+``highly optimized'' and tweaked Kerberos/Athena code (byte-order dependent):
+  165us per encryption (uses 6k worth of tables)
+  478us to set a new key (uses <1k of key tables)
+       so despite the comments in this code, it was possible to get
+       faster code AND smaller tables, as well as making the tables
+       machine-independent.
+       (code obtained from prep.ai.mit.edu)
+
+UC Berkeley code (depends on machine-endedness):
+  226us per encryption
+10848us to set a new key
+       table sizes are unclear, but they don't look very small
+       (code obtained from wuarchive.wustl.edu)
+
+
+motivation and history
+
+a while ago i wanted some des routines and the routines documented on sun's
+man pages either didn't exist or dumped core.  i had heard of kerberos,
+and knew that it used des,  so i figured i'd use its routines.  but once
+i got it and looked at the code,  it really set off a lot of pet peeves -
+it was too convoluted, the code had been written without taking
+advantage of the regular structure of operations such as IP, E, and FP
+(i.e. the author didn't sit down and think before coding),
+it was excessively slow,  the author had attempted to clarify the code
+by adding MORE statements to make the data movement more `consistent'
+instead of simplifying his implementation and cutting down on all data
+movement (in particular, his use of L1, R1, L2, R2), and it was full of
+idiotic `tweaks' for particular machines which failed to deliver significant
+speedups but which did obfuscate everything.  so i took the test data
+from his verification program and rewrote everything else.
+
+a while later i ran across the great crypt(3) package mentioned above.
+the fact that this guy was computing 2 sboxes per table lookup rather
+than one (and using a MUCH larger table in the process) emboldened me to
+do the same - it was a trivial change from which i had been scared away
+by the larger table size.  in his case he didn't realize you don't need to keep
+the working data in TWO forms, one for easy use of half the sboxes in
+indexing, the other for easy use of the other half; instead you can keep
+it in the form for the first half and use a simple rotate to get the other
+half.  this means i have (almost) half the data manipulation and half
+the table size.  in fairness though he might be encoding something particular
+to crypt(3) in his tables - i didn't check.
+
+i'm glad that i implemented it the way i did, because this C version is
+portable (the ifdef's are performance enhancements) and it is faster
+than versions hand-written in assembly for the sparc!
+
+
+porting notes
+
+one thing i did not want to do was write an enormous mess
+which depended on endedness and other machine quirks,
+and which necessarily produced different code and different lookup tables
+for different machines.  see the kerberos code for an example
+of what i didn't want to do; all their endedness-specific `optimizations'
+obfuscate the code and in the end were slower than a simpler machine
+independent approach.  however, there are always some portability
+considerations of some kind, and i have included some options
+for varying numbers of register variables.
+perhaps some will still regard the result as a mess!
+
+1) i assume everything is byte addressable, although i don't actually
+   depend on the byte order, and that bytes are 8 bits.
+   i assume word pointers can be freely cast to and from char pointers.
+   note that 99% of C programs make these assumptions.
+   i always use unsigned char's if the high bit could be set.
+2) the typedef `word' means a 32 bit unsigned integral type.
+   if `unsigned long' is not 32 bits, change the typedef in desCore.h.
+   i assume sizeof(word) == 4 EVERYWHERE.
+
+the (worst-case) cost of my NOT doing endedness-specific optimizations
+in the data loading and storing code surrounding the key iterations
+is less than 12%.  also, there is the added benefit that
+the input and output work areas do not need to be word-aligned.
+
+
+OPTIONAL performance optimizations
+
+1) you should define one of `i386,' `vax,' `mc68000,' or `sparc,'
+   whichever one is closest to the capabilities of your machine.
+   see the start of desCode.h to see exactly what this selection implies.
+   note that if you select the wrong one, the des code will still work;
+   these are just performance tweaks.
+2) for those with functional `asm' keywords: you should change the
+   ROR and ROL macros to use machine rotate instructions if you have them.
+   this will save 2 instructions and a temporary per use,
+   or about 32 to 40 instructions per en/decryption.
+
+these optimizations are all rather persnickety, yet with them you should
+be able to get performance equal to assembly-coding, except that:
+1) with the lack of a bit rotate operator in C, rotates have to be synthesized
+   from shifts.  so access to `asm' will speed things up if your machine
+   has rotates, as explained above in (3).
+2) if your machine has less than 12 32-bit registers i doubt your compiler will
+   generate good code.
+   `i386' tries to configure the code for a 386 by only declaring 3 registers
+   (it appears that gcc can use ebx, esi and edi to hold register variables).
+   however, if you like assembly coding, the 386 does have 7 32-bit registers,
+   and if you use ALL of them, use `scaled by 8' address modes with displacement
+   and other tricks, you can get reasonable routines for DesQuickCore... with
+   about 250 instructions apiece.  For DesSmall... it will help to rearrange
+   des_keymap, i.e., now the sbox # is the high part of the index and
+   the 6 bits of data is the low part; it helps to exchange these.
+   since i have no way to conveniently test it i have not provided my
+   shoehorned 386 version.
+
+coding notes
+
+the en/decryption routines each use 6 necessary register variables,
+with 4 being actively used at once during the inner iterations.
+if you don't have 4 register variables get a new machine.
+up to 8 more registers are used to hold constants in some configurations.
+
+i assume that the use of a constant is more expensive than using a register:
+a) additionally, i have tried to put the larger constants in registers.
+   registering priority was by the following:
+       anything more than 12 bits (bad for RISC and CISC)
+       greater than 127 in value (can't use movq or byte immediate on CISC)
+       9-127 (may not be able to use CISC shift immediate or add/sub quick),
+       1-8 were never registered, being the cheapest constants.
+b) the compiler may be too stupid to realize table and table+256 should
+   be assigned to different constant registers and instead repetitively
+   do the arithmetic, so i assign these to explicit `m' register variables
+   when possible and helpful.
+
+i assume that indexing is cheaper or equivalent to auto increment/decrement,
+where the index is 7 bits unsigned or smaller.
+this assumption is reversed for 68k and vax.
+
+i assume that addresses can be cheaply formed from two registers,
+or from a register and a small constant.  i never use the `two registers
+and offset' form you see in some CISC machines.
+all index scaling is done explicitly - no hidden shifts by log2(sizeof).
+
+the code is written so that even a dumb compiler
+should never need more than one hidden temporary,
+increasing the chance that everything will fit in the registers.
+KEEP THIS MORE SUBTLE POINT IN MIND IF YOU REWRITE ANYTHING.
+
+
+special efficient data format
+
+bits are manipulated in this arrangement most of the time (S7 S5 S3 S1):
+       003130292827xxxx242322212019xxxx161514131211xxxx080706050403xxxx
+(the x bits are still there, i'm just emphasizing where the S boxes are).
+bits are rotated left 4 when computing S6 S4 S2 S0:
+       282726252423xxxx201918171615xxxx121110090807xxxx040302010031xxxx
+the rightmost two bits are usually cleared so the lower byte can be used
+as an index into an sbox mapping table. the next two x'd bits are set
+to various values to access different parts of the tables.
+
+
+how to use the routines
+
+datatypes:
+       pointer to 8 byte area of type DesData
+       used to hold keys and input/output blocks to des.
+
+       pointer to 128 byte area of type DesKeys
+       used to hold full 768-bit key.
+       must be long-aligned.
+
+DesQuickInit()
+       call this before using any other routine with `Quick' in its name.
+       it generates the special 64k table these routines need.
+DesQuickDone()
+       frees this table
+
+DesMethod(m, k)
+       m points to a 128byte block, k points to an 8 byte des key
+       which must have odd parity (or -1 is returned) and which must
+       not be a (semi-)weak key (or -2 is returned).
+       normally DesMethod() returns 0.
+       m is filled in from k so that when one of the routines below
+       is called with m, the routine will act like standard des
+       en/decryption with the key k. if you use DesMethod,
+       you supply a standard 56bit key; however, if you fill in
+       m yourself, you will get a 768bit key - but then it won't
+       be standard.  it's 768bits not 1024 because the least significant
+       two bits of each byte are not used.  and yes, each byte controls
+       a specific sbox during a specific iteration.
+       NOTE: actually, every other word has been rotated right 4 bits
+       to reduce the number of temporaries needed when the key is used.
+       you really shouldn't use the 768bit format directly;  i should
+       provide a routine that converts 128 6-bit bytes (specified in
+       S-box mapping order or something) into the right format for you.
+       this would entail some byte concatenation and rotation.
+
+Des{Small|Quick}{Fips|Core}{Encrypt|Decrypt}(d, m, s)
+       performs des on the 8 bytes at s into the 8 bytes at d. (d,s: char *).
+       uses m as a 768bit key as explained above.
+       the Encrypt|Decrypt choice is obvious.
+       Fips|Core determines whether a completely standard FIPS initial
+       and final permutation is done; if not, then the data is loaded
+       and stored in a nonstandard bit order (FIPS w/o IP/FP).
+       Fips slows down Quick by 10%, Small by 9%.
+       Small|Quick determines whether you use the normal routine
+       or the crazy quick one which gobbles up 64k more of memory.
+       Small is 50% slower then Quick, but Quick needs 32 times as much
+       memory.  Quick is included for programs that do nothing but DES,
+       e.g., encryption filters, etc.
+
+
+Getting it to compile on your machine
+
+there are no machine-dependencies in the code (see porting),
+except perhaps the `now()' macro in desTest.c.
+ALL generated tables are machine independent.
+you should edit the Makefile with the appropriate optimization flags
+for your compiler (MAX optimization).
+
+
+Speeding up kerberos (and/or its des library)
+
+note that i have included a kerberos-compatible interface in desUtil.c
+through the functions des_key_sched() and des_ecb_encrypt().
+to use these with kerberos or kerberos-compatible code put desCore.a
+ahead of the kerberos-compatible library on your linker's command line.
+you should not need to #include desCore.h;  just include the header
+file provided with the kerberos library.
+
+Other uses
+
+the macros in desCode.h would be very useful for putting inline des
+functions in more complicated encryption routines.
diff --git a/desdata.c b/desdata.c
new file mode 100644 (file)
index 0000000..81cc726
--- /dev/null
+++ b/desdata.c
@@ -0,0 +1,198 @@
+/* desdata.c
+ *
+ * Generate tables used by des.c and desCode.h.
+ *
+ * $Id: desdata.c,v 1.1 2007-04-05 14:20:35 nisse Exp $ */
+
+/*
+ *     des - fast & portable DES encryption & decryption.
+ *     Copyright (C) 1992  Dana L. How
+ *     Please see the file `descore.README' for the complete copyright notice.
+ *
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include       "desinfo.h"
+
+#include       "desCode.h"
+
+
+/* list of weak and semi-weak keys
+
+        +0   +1   +2   +3   +4   +5   +6   +7
+       0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01
+       0x01 0x1f 0x01 0x1f 0x01 0x0e 0x01 0x0e
+       0x01 0xe0 0x01 0xe0 0x01 0xf1 0x01 0xf1
+       0x01 0xfe 0x01 0xfe 0x01 0xfe 0x01 0xfe
+       0x1f 0x01 0x1f 0x01 0x0e 0x01 0x0e 0x01
+       0x1f 0x1f 0x1f 0x1f 0x0e 0x0e 0x0e 0x0e
+       0x1f 0xe0 0x1f 0xe0 0x0e 0xf1 0x0e 0xf1
+       0x1f 0xfe 0x1f 0xfe 0x0e 0xfe 0x0e 0xfe
+       0xe0 0x01 0xe0 0x01 0xf1 0x01 0xf1 0x01
+       0xe0 0x1f 0xe0 0x1f 0xf1 0x0e 0xf1 0x0e
+       0xe0 0xe0 0xe0 0xe0 0xf1 0xf1 0xf1 0xf1
+       0xe0 0xfe 0xe0 0xfe 0xf1 0xfe 0xf1 0xfe
+       0xfe 0x01 0xfe 0x01 0xfe 0x01 0xfe 0x01
+       0xfe 0x1f 0xfe 0x1f 0xfe 0x0e 0xfe 0x0e
+       0xfe 0xe0 0xfe 0xe0 0xfe 0xf1 0xfe 0xf1
+       0xfe 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe
+ */
+
+/* key bit order in each method pair: bits 31->00 of 1st, bits 31->00 of 2nd */
+/* this does not reflect the rotate of the 2nd word */
+
+#define        S(box,bit)      (box*6+bit)
+int korder[] = {
+       S(7, 5), S(7, 4), S(7, 3), S(7, 2), S(7, 1), S(7, 0),
+       S(5, 5), S(5, 4), S(5, 3), S(5, 2), S(5, 1), S(5, 0),
+       S(3, 5), S(3, 4), S(3, 3), S(3, 2), S(3, 1), S(3, 0),
+       S(1, 5), S(1, 4), S(1, 3), S(1, 2), S(1, 1), S(1, 0),
+       S(6, 5), S(6, 4), S(6, 3), S(6, 2), S(6, 1), S(6, 0),
+       S(4, 5), S(4, 4), S(4, 3), S(4, 2), S(4, 1), S(4, 0),
+       S(2, 5), S(2, 4), S(2, 3), S(2, 2), S(2, 1), S(2, 0),
+       S(0, 5), S(0, 4), S(0, 3), S(0, 2), S(0, 1), S(0, 0),
+};
+
+/* the order in which the algorithm accesses the s boxes */
+
+int sorder[] = {
+       7, 5, 3, 1, 6, 4, 2, 0,
+};
+
+int printf(const char *, ...);
+
+int
+main(int argc UNUSED, char **argv UNUSED)
+{
+       uint32_t d, i, j, k, l, m, n, s;
+       char b[256], ksr[56];
+
+       switch ( argv[1][0] ) {
+
+       /*
+        * <<< make the key parity table >>>
+        */
+
+case 'p':
+       (void)printf(
+"/* automagically produced - do not fuss with this information */\n\n");
+
+       /* store parity information */
+       for ( i = 0; i < 256; i++ ) {
+               j  = i;
+               j ^= j >> 4;    /* bits 3-0 have pairs */
+               j ^= j << 2;    /* bits 3-2 have quads */
+               j ^= j << 1;    /* bit  3 has the entire eight (no cox) */
+               b[i] = 8 & ~j;  /* 0 is okay and 8 is bad parity */
+       }
+
+       /* only these characters can appear in a weak key */
+       b[0x01] = 1;
+       b[0x0e] = 2;
+       b[0x1f] = 3;
+       b[0xe0] = 4;
+       b[0xf1] = 5;
+       b[0xfe] = 6;
+
+       /* print it out */
+       for ( i = 0; i < 256; i++ ) {
+               (void)printf("%d,", b[i]);
+               if ( (i & 31) == 31 )
+                       (void)printf("\n");
+       }
+
+       break;
+
+
+       /*
+        * <<< make the key usage table >>>
+        */
+
+case 'r':
+       (void)printf("/* automagically made - do not fuss with this */\n\n");
+
+       /* KL specifies the initial key bit positions */
+       for (i = 0; i < 56; i++)
+               ksr[i] = (KL[i] - 1) ^ 7;
+
+       for (i = 0; i < 16; i++) {
+
+               /* apply the appropriate number of left shifts */
+               for (j = 0; j < KS[i]; j++) {
+                       m = ksr[ 0];
+                       n = ksr[28];
+                       for (k = 0; k < 27; k++)
+                               ksr[k     ] = ksr[k +  1],
+                               ksr[k + 28] = ksr[k + 29];
+                       ksr[27] = m;
+                       ksr[55] = n;
+               }
+
+               /* output the key bit numbers */
+               for (j = 0; j < 48; j++) {
+                       m = ksr[KC[korder[j]] - 1];
+                       m = (m / 8) * 7 + (m % 8) - 1;
+                       m = 55 - m;
+                       (void)printf(" %2ld,", (long) m);
+                       if ((j % 12) == 11)
+                               (void)printf("\n");
+               }
+               (void)printf("\n");
+       }
+
+       break;
+
+
+       /*
+        * <<< make the keymap table >>>
+        */
+
+case 'k':
+       (void)printf("/* automagically made - do not fuss with this */\n\n");
+
+       for ( i = 0; i <= 7 ; i++ ) {
+               s = sorder[i];
+               for ( d = 0; d <= 63; d++ ) {
+                       /* flip bits */
+                       k =     ((d << 5) & 32) |
+                               ((d << 3) & 16) |
+                               ((d << 1) &  8) |
+                               ((d >> 1) &  4) |
+                               ((d >> 3) &  2) |
+                               ((d >> 5) &  1) ;
+                       /* more bit twiddling */
+                       l =     ((k << 0) & 32) |       /* overlap bit */
+                               ((k << 4) & 16) |       /* overlap bit */
+                               ((k >> 1) & 15) ;       /* unique bits */
+                       /* look up s box value */
+                       m = SB[s][l];
+                       /* flip bits */
+                       n =     ((m << 3) &  8) |
+                               ((m << 1) &  4) |
+                               ((m >> 1) &  2) |
+                               ((m >> 3) &  1) ;
+                       /* put in correct nybble */
+                       n <<= (s << 2);
+                       /* perform p permutation */
+                       for ( m = j = 0; j < 32; j++ )
+                               if ( n & (1 << (SP[j] - 1)) )
+                                       m |= (1 << j);
+                       /* rotate right (alg keeps everything rotated by 1) */
+                       ROR(m, 1, 31);
+                       /* print it out */
+                       (void)printf(" 0x%08lx,", (long) m);
+                       if ( ( d & 3 ) == 3 )
+                               (void)printf("\n");
+               }
+               (void)printf("\n");
+       }
+
+       break;
+
+       }
+
+       return 0;
+}
diff --git a/desinfo.h b/desinfo.h
new file mode 100644 (file)
index 0000000..6b10c20
--- /dev/null
+++ b/desinfo.h
@@ -0,0 +1,96 @@
+/* desinfo.h
+ *
+ * Tables describing DES rather than just this implementation.
+ * These are used in desdata but NOT in runtime code.
+ *
+ * $Id: desinfo.h,v 1.1 2007-04-05 14:20:35 nisse Exp $ */
+
+/*     des - fast & portable DES encryption & decryption.
+ *     Copyright (C) 1992  Dana L. How
+ *     Please see the file `descore.README' for the complete copyright notice.
+ */
+
+/* the initial permutation, E selection, and final permutation are hardwired */
+
+/* Key Load: how to load the shift register from the user key */
+
+unsigned char KL[] = {
+
+       57, 49, 41, 33, 25, 17,  9,  1, 58, 50, 42, 34, 26, 18,
+       10,  2, 59, 51, 43, 35, 27, 19, 11,  3, 60, 52, 44, 36,
+
+       63, 55, 47, 39, 31, 23, 15,  7, 62, 54, 46, 38, 30, 22,
+       14,  6, 61, 53, 45, 37, 29, 21, 13,  5, 28, 20, 12,  4,
+};
+
+/* Key Shift: how many times to shift the key shift register */
+
+unsigned char KS[] = {
+
+       1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
+};
+
+/* Key Choose: which key bits from shift reg are used in the key schedule */
+
+unsigned char KC[] = {
+
+       14, 17, 11, 24,  1,  5,  3, 28, 15,  6, 21, 10,
+       23, 19, 12,  4, 26,  8, 16,  7, 27, 20, 13,  2,
+
+       41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
+       44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32,
+};
+
+/* S Boxes */
+
+unsigned char SB[8][64] = {
+  {
+       14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
+        0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
+        4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
+       15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
+  },{
+       15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
+        3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
+        0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
+       13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
+  },{
+       10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
+       13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
+       13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
+        1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
+  },{
+        7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
+       13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
+       10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
+        3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
+  },{
+        2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
+       14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
+        4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
+       11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
+  },{
+       12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
+       10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
+        9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
+        4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
+  },{
+        4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
+       13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
+        1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
+        6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
+  },{
+       13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
+        1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
+        7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
+        2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11
+  }
+};
+
+/* Sbox Permutation */
+
+char SP[] = {  
+
+       16,  7, 20, 21, 29, 12, 28, 17,  1, 15, 23, 26,  5, 18, 31, 10,
+        2,  8, 24, 14, 32, 27,  3,  9, 19, 13, 30,  6, 22, 11,  4, 25,
+};
diff --git a/dsa-keygen.c b/dsa-keygen.c
new file mode 100644 (file)
index 0000000..00bd35f
--- /dev/null
@@ -0,0 +1,125 @@
+/* dsa-keygen.c
+ *
+ * Generation of DSA keypairs
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "dsa.h"
+
+#include "bignum.h"
+#include "nettle-internal.h"
+
+
+/* Valid sizes, according to FIPS 186-3 are (1024, 160), (2048. 224),
+   (2048, 256), (3072, 256). Currenty, we use only q_bits of 160 or
+   256. */
+int
+dsa_generate_keypair(struct dsa_public_key *pub,
+                    struct dsa_private_key *key,
+                    void *random_ctx, nettle_random_func random,
+                    void *progress_ctx, nettle_progress_func progress,
+                    unsigned p_bits, unsigned q_bits)
+{
+  mpz_t p0, p0q, r;
+  unsigned p0_bits;
+  unsigned a;
+
+  switch (q_bits)
+    {
+    case 160:
+      if (p_bits < DSA_SHA1_MIN_P_BITS)
+       return 0;
+      break;
+    case 256:
+      if (p_bits < DSA_SHA256_MIN_P_BITS)
+       return 0;
+      break;
+    default:
+      return 0;
+    }
+
+  mpz_init (p0);
+  mpz_init (p0q);
+  mpz_init (r);
+
+  nettle_random_prime (pub->q, q_bits, 0, random_ctx, random,
+                      progress_ctx, progress);
+
+  p0_bits = (p_bits + 3)/2;
+  
+  nettle_random_prime (p0, p0_bits, 0,
+                      random_ctx, random,
+                      progress_ctx, progress);
+
+  if (progress)
+    progress (progress_ctx, 'q');
+  
+  /* Generate p = 2 r q p0 + 1, such that 2^{n-1} < p < 2^n.
+   *
+   * We select r in the range i + 1 < r <= 2i, with i = floor (2^{n-2} / (p0 q). */
+
+  mpz_mul (p0q, p0, pub->q);
+
+  _nettle_generate_pocklington_prime (pub->p, r, p_bits, 0,
+                                     random_ctx, random,
+                                     p0, pub->q, p0q);
+
+  if (progress)
+    progress (progress_ctx, 'p');
+
+  mpz_mul (r, r, p0);
+
+  for (a = 2; ; a++)
+    {
+      mpz_set_ui (pub->g, a);
+      mpz_powm (pub->g, pub->g, r, pub->p);
+      if (mpz_cmp_ui (pub->g, 1) != 0)
+       break;
+    }
+
+  if (progress)
+    progress (progress_ctx, 'g');
+
+  mpz_set(r, pub->q);
+  mpz_sub_ui(r, r, 2);
+  nettle_mpz_random(key->x, random_ctx, random, r);
+
+  mpz_add_ui(key->x, key->x, 1);
+
+  mpz_powm(pub->y, pub->g, key->x, pub->p);
+
+  if (progress)
+    progress (progress_ctx, '\n');
+  
+  mpz_clear (p0);
+  mpz_clear (p0q);
+  mpz_clear (r);
+
+  return 1;
+}
diff --git a/dsa-sha1-sign.c b/dsa-sha1-sign.c
new file mode 100644 (file)
index 0000000..5654c49
--- /dev/null
@@ -0,0 +1,56 @@
+/* dsa-sha1-sign.c
+ *
+ * The original DSA publickey algorithm, using SHA-1.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "dsa.h"
+
+int
+dsa_sha1_sign_digest(const struct dsa_public_key *pub,
+                    const struct dsa_private_key *key,
+                    void *random_ctx, nettle_random_func random,
+                    const uint8_t *digest,
+                    struct dsa_signature *signature)
+{
+  return _dsa_sign(pub, key, random_ctx, random,
+                  SHA1_DIGEST_SIZE, digest, signature);
+}
+
+
+int
+dsa_sha1_sign(const struct dsa_public_key *pub,
+             const struct dsa_private_key *key,
+             void *random_ctx, nettle_random_func random,
+             struct sha1_ctx *hash,
+             struct dsa_signature *signature)
+{
+  uint8_t digest[SHA1_DIGEST_SIZE];
+  sha1_digest(hash, sizeof(digest), digest);
+
+  return _dsa_sign(pub, key, random_ctx, random,
+                  sizeof(digest), digest, signature);
+}
diff --git a/dsa-sha1-verify.c b/dsa-sha1-verify.c
new file mode 100644 (file)
index 0000000..73e948c
--- /dev/null
@@ -0,0 +1,51 @@
+/* dsa-sha1-verify.c
+ *
+ * The original DSA publickey algorithm, using SHA-1.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002, 2003, 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+
+#include "dsa.h"
+
+int
+dsa_sha1_verify_digest(const struct dsa_public_key *key,
+                      const uint8_t *digest,
+                      const struct dsa_signature *signature)
+{
+  return _dsa_verify(key, SHA1_DIGEST_SIZE, digest, signature);
+}
+
+int
+dsa_sha1_verify(const struct dsa_public_key *key,
+               struct sha1_ctx *hash,
+               const struct dsa_signature *signature)
+{
+  uint8_t digest[SHA1_DIGEST_SIZE];
+  sha1_digest(hash, sizeof(digest), digest);
+
+  return _dsa_verify(key, sizeof(digest), digest, signature);
+}
diff --git a/dsa-sha256-sign.c b/dsa-sha256-sign.c
new file mode 100644 (file)
index 0000000..ea82022
--- /dev/null
@@ -0,0 +1,55 @@
+/* dsa-sha256-sign.c
+ *
+ * The DSA publickey algorithm, using SHA-256 (FIPS186-3).
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "dsa.h"
+
+int
+dsa_sha256_sign_digest(const struct dsa_public_key *pub,
+                      const struct dsa_private_key *key,
+                      void *random_ctx, nettle_random_func random,
+                      const uint8_t *digest,
+                      struct dsa_signature *signature)
+{
+  return _dsa_sign(pub, key, random_ctx, random,
+                  SHA256_DIGEST_SIZE, digest, signature);
+}
+
+int
+dsa_sha256_sign(const struct dsa_public_key *pub,
+               const struct dsa_private_key *key,
+               void *random_ctx, nettle_random_func random,
+               struct sha256_ctx *hash,
+               struct dsa_signature *signature)
+{
+  uint8_t digest[SHA256_DIGEST_SIZE];
+  sha256_digest(hash, sizeof(digest), digest);
+
+  return _dsa_sign(pub, key, random_ctx, random,
+                  sizeof(digest), digest, signature);
+}
diff --git a/dsa-sha256-verify.c b/dsa-sha256-verify.c
new file mode 100644 (file)
index 0000000..ed79a86
--- /dev/null
@@ -0,0 +1,51 @@
+/* dsa-sha256-verify.c
+ *
+ * The DSA publickey algorithm, using SHA-256 (FIPS186-3).
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+
+#include "dsa.h"
+
+int
+dsa_sha256_verify_digest(const struct dsa_public_key *key,
+                        const uint8_t *digest,
+                        const struct dsa_signature *signature)
+{
+  return _dsa_verify(key, SHA256_DIGEST_SIZE, digest, signature);
+}
+
+int
+dsa_sha256_verify(const struct dsa_public_key *key,
+                 struct sha256_ctx *hash,
+                 const struct dsa_signature *signature)
+{
+  uint8_t digest[SHA256_DIGEST_SIZE];
+  sha256_digest(hash, sizeof(digest), digest);
+
+  return _dsa_verify(key, sizeof(digest), digest, signature);
+}
diff --git a/dsa-sign.c b/dsa-sign.c
new file mode 100644 (file)
index 0000000..9c5a29c
--- /dev/null
@@ -0,0 +1,90 @@
+/* dsa-sign.c
+ *
+ * The DSA publickey algorithm.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002, 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "dsa.h"
+
+#include "bignum.h"
+
+
+int
+_dsa_sign(const struct dsa_public_key *pub,
+         const struct dsa_private_key *key,
+         void *random_ctx, nettle_random_func random,
+         unsigned digest_size,
+         const uint8_t *digest,
+         struct dsa_signature *signature)
+{
+  mpz_t k;
+  mpz_t h;
+  mpz_t tmp;
+
+  /* Require precise match of bitsize of q and hash size. The general
+     description of DSA in FIPS186-3 allows both larger and smaller q;
+     in the the latter case, the hash must be truncated to the right
+     number of bits. */
+  if (mpz_sizeinbase(pub->q, 2) != 8 * digest_size)
+    return 0;
+
+  /* Select k, 0<k<q, randomly */
+  mpz_init_set(tmp, pub->q);
+  mpz_sub_ui(tmp, tmp, 1);
+
+  mpz_init(k);
+  nettle_mpz_random(k, random_ctx, random, tmp);
+  mpz_add_ui(k, k, 1);
+
+  /* Compute r = (g^k (mod p)) (mod q) */
+  mpz_powm(tmp, pub->g, k, pub->p);
+  mpz_fdiv_r(signature->r, tmp, pub->q);
+
+  /* Compute hash */
+  mpz_init(h);
+  nettle_mpz_set_str_256_u(h, digest_size, digest);
+
+  /* Compute k^-1 (mod q) */
+  if (!mpz_invert(k, k, pub->q))
+    /* What do we do now? The key is invalid. */
+    return 0;
+
+  /* Compute signature s = k^-1 (h + xr) (mod q) */
+  mpz_mul(tmp, signature->r, key->x);
+  mpz_fdiv_r(tmp, tmp, pub->q);
+  mpz_add(tmp, tmp, h);
+  mpz_mul(tmp, tmp, k);
+  mpz_fdiv_r(signature->s, tmp, pub->q);
+
+  mpz_clear(k);
+  mpz_clear(h);
+  mpz_clear(tmp);
+
+  return 1;
+}
diff --git a/dsa-verify.c b/dsa-verify.c
new file mode 100644 (file)
index 0000000..faea0a0
--- /dev/null
@@ -0,0 +1,101 @@
+/* dsa-verify.c
+ *
+ * The DSA publickey algorithm.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002, 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+
+#include "dsa.h"
+
+#include "bignum.h"
+
+int
+_dsa_verify(const struct dsa_public_key *key,
+           unsigned digest_size,
+           const uint8_t *digest,
+           const struct dsa_signature *signature)
+{
+  mpz_t w;
+  mpz_t tmp;
+  mpz_t v;
+
+  int res;
+
+  if (mpz_sizeinbase(key->q, 2) != 8 * digest_size)
+    return 0;
+
+  /* Check that r and s are in the proper range */
+  if (mpz_sgn(signature->r) <= 0 || mpz_cmp(signature->r, key->q) >= 0)
+    return 0;
+
+  if (mpz_sgn(signature->s) <= 0 || mpz_cmp(signature->s, key->q) >= 0)
+    return 0;
+
+  mpz_init(w);
+
+  /* Compute w = s^-1 (mod q) */
+
+  /* NOTE: In gmp-2, mpz_invert sometimes generates negative inverses,
+   * so we need gmp-3 or better. */
+  if (!mpz_invert(w, signature->s, key->q))
+    {
+      mpz_clear(w);
+      return 0;
+    }
+
+  mpz_init(tmp);
+  mpz_init(v);
+
+  /* The message digest */
+  nettle_mpz_set_str_256_u(tmp, digest_size, digest);
+  
+  /* v = g^{w * h (mod q)} (mod p)  */
+  mpz_mul(tmp, tmp, w);
+  mpz_fdiv_r(tmp, tmp, key->q);
+
+  mpz_powm(v, key->g, tmp, key->p);
+
+  /* y^{w * r (mod q) } (mod p) */
+  mpz_mul(tmp, signature->r, w);
+  mpz_fdiv_r(tmp, tmp, key->q);
+
+  mpz_powm(tmp, key->y, tmp, key->p);
+
+  /* v = (g^{w * h} * y^{w * r} (mod p) ) (mod q) */
+  mpz_mul(v, v, tmp);
+  mpz_fdiv_r(v, v, key->p);
+
+  mpz_fdiv_r(v, v, key->q);
+
+  res = !mpz_cmp(v, signature->r);
+
+  mpz_clear(w);
+  mpz_clear(tmp);
+  mpz_clear(v);
+
+  return res;
+}
diff --git a/dsa.c b/dsa.c
new file mode 100644 (file)
index 0000000..02cc785
--- /dev/null
+++ b/dsa.c
@@ -0,0 +1,78 @@
+/* dsa.h
+ *
+ * The DSA publickey algorithm.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "dsa.h"
+
+#include "bignum.h"
+
+void
+dsa_public_key_init(struct dsa_public_key *key)
+{
+  mpz_init(key->p);
+  mpz_init(key->q);
+  mpz_init(key->g);
+  mpz_init(key->y);
+}
+
+void
+dsa_public_key_clear(struct dsa_public_key *key)
+{
+  mpz_clear(key->p);
+  mpz_clear(key->q);
+  mpz_clear(key->g);
+  mpz_clear(key->y);
+}
+
+
+void
+dsa_private_key_init(struct dsa_private_key *key)
+{
+  mpz_init(key->x);
+}
+
+void
+dsa_private_key_clear(struct dsa_private_key *key)
+{
+  mpz_clear(key->x);
+}
+
+
+void
+dsa_signature_init(struct dsa_signature *signature)
+{
+  mpz_init(signature->r);
+  mpz_init(signature->s);
+}
+
+void
+dsa_signature_clear(struct dsa_signature *signature)
+{
+  mpz_clear(signature->r);
+  mpz_clear(signature->s);
+}
diff --git a/dsa.h b/dsa.h
new file mode 100644 (file)
index 0000000..412178b
--- /dev/null
+++ b/dsa.h
@@ -0,0 +1,295 @@
+/* dsa.h
+ *
+ * The DSA publickey algorithm.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_DSA_H_INCLUDED
+#define NETTLE_DSA_H_INCLUDED
+
+#include <gmp.h>
+
+#include "nettle-types.h"
+
+#include "sha.h"
+
+/* For nettle_random_func */
+#include "nettle-meta.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define dsa_public_key_init nettle_dsa_public_key_init
+#define dsa_public_key_clear nettle_dsa_public_key_clear
+#define dsa_private_key_init nettle_dsa_private_key_init
+#define dsa_private_key_clear nettle_dsa_private_key_clear
+#define dsa_signature_init nettle_dsa_signature_init
+#define dsa_signature_clear nettle_dsa_signature_clear
+#define dsa_sha1_sign nettle_dsa_sha1_sign
+#define dsa_sha1_verify nettle_dsa_sha1_verify
+#define dsa_sha256_sign nettle_dsa_sha256_sign
+#define dsa_sha256_verify nettle_dsa_sha256_verify
+#define dsa_sha1_sign_digest nettle_dsa_sha1_sign_digest
+#define dsa_sha1_verify_digest nettle_dsa_sha1_verify_digest
+#define dsa_sha256_sign_digest nettle_dsa_sha256_sign_digest
+#define dsa_sha256_verify_digest nettle_dsa_sha256_verify_digest
+#define dsa_generate_keypair nettle_dsa_generate_keypair
+#define dsa_signature_from_sexp nettle_dsa_signature_from_sexp
+#define dsa_keypair_to_sexp nettle_dsa_keypair_to_sexp
+#define dsa_keypair_from_sexp_alist nettle_dsa_keypair_from_sexp_alist
+#define dsa_sha1_keypair_from_sexp nettle_dsa_sha1_keypair_from_sexp
+#define dsa_sha256_keypair_from_sexp nettle_dsa_sha256_keypair_from_sexp
+#define dsa_params_from_der_iterator nettle_dsa_params_from_der_iterator
+#define dsa_public_key_from_der_iterator nettle_dsa_public_key_from_der_iterator
+#define dsa_openssl_private_key_from_der_iterator nettle_dsa_openssl_private_key_from_der_iterator 
+#define dsa_openssl_private_key_from_der nettle_openssl_provate_key_from_der
+#define _dsa_sign _nettle_dsa_sign
+#define _dsa_verify _nettle_dsa_verify
+
+#define DSA_SHA1_MIN_P_BITS 512
+#define DSA_SHA1_Q_OCTETS 20
+#define DSA_SHA1_Q_BITS 160
+
+#define DSA_SHA256_MIN_P_BITS 1024
+#define DSA_SHA256_Q_OCTETS 32
+#define DSA_SHA256_Q_BITS 256
+  
+struct dsa_public_key
+{  
+  /* Modulo */
+  mpz_t p;
+
+  /* Group order */
+  mpz_t q;
+
+  /* Generator */
+  mpz_t g;
+  
+  /* Public value */
+  mpz_t y;
+};
+
+struct dsa_private_key
+{
+  /* Unlike an rsa public key, private key operations will need both
+   * the private and the public information. */
+  mpz_t x;
+};
+
+struct dsa_signature
+{
+  mpz_t r;
+  mpz_t s;
+};
+
+/* Signing a message works as follows:
+ *
+ * Store the private key in a dsa_private_key struct.
+ *
+ * Initialize a hashing context, by callling
+ *   sha1_init
+ *
+ * Hash the message by calling
+ *   sha1_update
+ *
+ * Create the signature by calling
+ *   dsa_sha1_sign
+ *
+ * The signature is represented as a struct dsa_signature. This call also
+ * resets the hashing context.
+ *
+ * When done with the key and signature, don't forget to call
+ * dsa_signature_clear.
+ */
+
+/* Calls mpz_init to initialize bignum storage. */
+void
+dsa_public_key_init(struct dsa_public_key *key);
+
+/* Calls mpz_clear to deallocate bignum storage. */
+void
+dsa_public_key_clear(struct dsa_public_key *key);
+
+
+/* Calls mpz_init to initialize bignum storage. */
+void
+dsa_private_key_init(struct dsa_private_key *key);
+
+/* Calls mpz_clear to deallocate bignum storage. */
+void
+dsa_private_key_clear(struct dsa_private_key *key);
+
+/* Calls mpz_init to initialize bignum storage. */
+void
+dsa_signature_init(struct dsa_signature *signature);
+
+/* Calls mpz_clear to deallocate bignum storage. */
+void
+dsa_signature_clear(struct dsa_signature *signature);
+
+
+int
+dsa_sha1_sign(const struct dsa_public_key *pub,
+             const struct dsa_private_key *key,
+             void *random_ctx, nettle_random_func random,
+             struct sha1_ctx *hash,
+             struct dsa_signature *signature);
+
+int
+dsa_sha256_sign(const struct dsa_public_key *pub,
+               const struct dsa_private_key *key,
+               void *random_ctx, nettle_random_func random,
+               struct sha256_ctx *hash,
+               struct dsa_signature *signature);
+
+int
+dsa_sha1_verify(const struct dsa_public_key *key,
+               struct sha1_ctx *hash,
+               const struct dsa_signature *signature);
+
+int
+dsa_sha256_verify(const struct dsa_public_key *key,
+                 struct sha256_ctx *hash,
+                 const struct dsa_signature *signature);
+
+int
+dsa_sha1_sign_digest(const struct dsa_public_key *pub,
+                    const struct dsa_private_key *key,
+                    void *random_ctx, nettle_random_func random,
+                    const uint8_t *digest,
+                    struct dsa_signature *signature);
+int
+dsa_sha256_sign_digest(const struct dsa_public_key *pub,
+                      const struct dsa_private_key *key,
+                      void *random_ctx, nettle_random_func random,
+                      const uint8_t *digest,
+                      struct dsa_signature *signature);
+
+int
+dsa_sha1_verify_digest(const struct dsa_public_key *key,
+                      const uint8_t *digest,
+                      const struct dsa_signature *signature);
+
+int
+dsa_sha256_verify_digest(const struct dsa_public_key *key,
+                        const uint8_t *digest,
+                        const struct dsa_signature *signature);
+
+/* Key generation */
+
+int
+dsa_generate_keypair(struct dsa_public_key *pub,
+                    struct dsa_private_key *key,
+
+                    void *random_ctx, nettle_random_func random,
+
+                    void *progress_ctx, nettle_progress_func progress,
+                    unsigned p_bits, unsigned q_bits);
+
+/* Keys in sexp form. */
+
+struct nettle_buffer;
+
+/* Generates a public-key expression if PRIV is NULL .*/
+int
+dsa_keypair_to_sexp(struct nettle_buffer *buffer,
+                   const char *algorithm_name, /* NULL means "dsa" */
+                   const struct dsa_public_key *pub,
+                   const struct dsa_private_key *priv);
+
+struct sexp_iterator;
+
+int
+dsa_signature_from_sexp(struct dsa_signature *rs,
+                       struct sexp_iterator *i,
+                       unsigned q_bits);
+
+int
+dsa_keypair_from_sexp_alist(struct dsa_public_key *pub,
+                           struct dsa_private_key *priv,
+                           unsigned p_max_bits,
+                           unsigned q_bits,
+                           struct sexp_iterator *i);
+
+/* If PRIV is NULL, expect a public-key expression. If PUB is NULL,
+ * expect a private key expression and ignore the parts not needed for
+ * the public key. */
+/* Keys must be initialized before calling this function, as usual. */
+int
+dsa_sha1_keypair_from_sexp(struct dsa_public_key *pub,
+                          struct dsa_private_key *priv,
+                          unsigned p_max_bits,
+                          unsigned length, const uint8_t *expr);
+
+int
+dsa_sha256_keypair_from_sexp(struct dsa_public_key *pub,
+                            struct dsa_private_key *priv,
+                            unsigned p_max_bits,
+                            unsigned length, const uint8_t *expr);
+
+/* Keys in X.509 andd OpenSSL format. */
+struct asn1_der_iterator;
+
+int
+dsa_params_from_der_iterator(struct dsa_public_key *pub,
+                            unsigned p_max_bits,
+                            struct asn1_der_iterator *i);
+int
+dsa_public_key_from_der_iterator(struct dsa_public_key *pub,
+                                unsigned p_max_bits,
+                                struct asn1_der_iterator *i);
+
+int
+dsa_openssl_private_key_from_der_iterator(struct dsa_public_key *pub,
+                                         struct dsa_private_key *priv,
+                                         unsigned p_max_bits,
+                                         struct asn1_der_iterator *i);
+
+int
+dsa_openssl_private_key_from_der(struct dsa_public_key *pub,
+                                struct dsa_private_key *priv,
+                                unsigned p_max_bits, 
+                                unsigned length, const uint8_t *data);
+
+
+/* Internal functions. */
+int
+_dsa_sign(const struct dsa_public_key *pub,
+         const struct dsa_private_key *key,
+         void *random_ctx, nettle_random_func random,
+         unsigned digest_size,
+         const uint8_t *digest,
+         struct dsa_signature *signature);
+
+int
+_dsa_verify(const struct dsa_public_key *key,
+           unsigned digest_size,
+           const uint8_t *digest,
+           const struct dsa_signature *signature);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_DSA_H_INCLUDED */
diff --git a/dsa2sexp.c b/dsa2sexp.c
new file mode 100644 (file)
index 0000000..213903d
--- /dev/null
@@ -0,0 +1,54 @@
+/* dsa2sexp.c
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002, 2009 Niels Möller, Magnus Holmgren
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "dsa.h"
+
+#include "sexp.h"
+
+int
+dsa_keypair_to_sexp(struct nettle_buffer *buffer,
+                   const char *algorithm_name,
+                   const struct dsa_public_key *pub,
+                   const struct dsa_private_key *priv)
+{
+  if (!algorithm_name)
+    algorithm_name = "dsa";
+  
+  if (priv)
+    return sexp_format(buffer,
+                      "(private-key(%0s(p%b)(q%b)"
+                      "(g%b)(y%b)(x%b)))",
+                      algorithm_name, pub->p, pub->q,
+                      pub->g, pub->y, priv->x);
+  else
+    return sexp_format(buffer,
+                      "(public-key(%0s(p%b)(q%b)"
+                      "(g%b)(y%b)))",
+                      algorithm_name, pub->p, pub->q,
+                      pub->g, pub->y);
+}
diff --git a/examples/Makefile.in b/examples/Makefile.in
new file mode 100644 (file)
index 0000000..a3b0790
--- /dev/null
@@ -0,0 +1,100 @@
+@SET_MAKE@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+top_srcdir = @top_srcdir@
+
+include ../config.make
+
+PRE_CPPFLAGS = -I.. -I$(top_srcdir)
+PRE_LDFLAGS = -L..
+
+OPENSSL_LIBFLAGS = @OPENSSL_LIBFLAGS@
+BENCH_LIBS = @BENCH_LIBS@
+
+RSA_TARGETS = rsa-keygen$(EXEEXT) rsa-sign$(EXEEXT) \
+             rsa-verify$(EXEEXT) rsa-encrypt$(EXEEXT) rsa-decrypt$(EXEEXT)
+TARGETS = nettle-benchmark$(EXEEXT) eratosthenes$(EXEEXT) @IF_HOGWEED@ $(RSA_TARGETS) next-prime$(EXEEXT) random-prime$(EXEEXT)
+SOURCES = nettle-benchmark.c eratosthenes.c next-prime.c random-prime.c \
+       nettle-openssl.c \
+       io.c read_rsa_key.c getopt.c getopt1.c \
+       rsa-encrypt.c rsa-decrypt.c rsa-keygen.c rsa-sign.c rsa-verify.c
+
+GETOPT_OBJS = getopt.$(OBJEXT) getopt1.$(OBJEXT)
+
+TS_ALL = rsa-sign-test rsa-verify-test rsa-encrypt-test
+
+DISTFILES= $(SOURCES) Makefile.in $(TS_ALL) run-tests setup-env teardown-env \
+       io.h rsa-session.h getopt.h
+
+all: $(TARGETS)
+
+.c.$(OBJEXT):
+       $(COMPILE) -c $< && $(DEP_PROCESS)
+
+# For Solaris and BSD make, we have to use an explicit rule for each executable
+next-prime$(EXEEXT): next-prime.$(OBJEXT) $(GETOPT_OBJS) ../libhogweed.a
+       $(LINK) next-prime.$(OBJEXT) $(GETOPT_OBJS) \
+       -lhogweed -lnettle $(LIBS) -o next-prime$(EXEEXT)
+
+random-prime$(EXEEXT): random-prime.$(OBJEXT) $(GETOPT_OBJS) ../libhogweed.a
+       $(LINK) random-prime.$(OBJEXT) io.$(OBJEXT) $(GETOPT_OBJS) \
+       -lhogweed -lnettle $(LIBS) -o random-prime$(EXEEXT)
+
+rsa-keygen$(EXEEXT): rsa-keygen.$(OBJEXT) $(GETOPT_OBJS)
+       $(LINK) rsa-keygen.$(OBJEXT) io.$(OBJEXT) $(GETOPT_OBJS) \
+       -lhogweed -lnettle $(LIBS) -o rsa-keygen$(EXEEXT)
+
+rsa-sign$(EXEEXT): rsa-sign.$(OBJEXT) read_rsa_key.$(OBJEXT)
+       $(LINK) rsa-sign.$(OBJEXT) io.$(OBJEXT) read_rsa_key.$(OBJEXT) \
+       -lhogweed -lnettle $(LIBS) -o rsa-sign$(EXEEXT)
+
+rsa-verify$(EXEEXT): rsa-verify.$(OBJEXT) read_rsa_key.$(OBJEXT)
+       $(LINK) rsa-verify.$(OBJEXT) io.$(OBJEXT) read_rsa_key.$(OBJEXT) \
+       -lhogweed -lnettle $(LIBS) -o rsa-verify$(EXEEXT)
+
+rsa-encrypt$(EXEEXT): rsa-encrypt.$(OBJEXT) read_rsa_key.$(OBJEXT) $(GETOPT_OBJS)
+       $(LINK) rsa-encrypt.$(OBJEXT) io.$(OBJEXT) read_rsa_key.$(OBJEXT) \
+       $(GETOPT_OBJS) \
+       -lhogweed -lnettle $(LIBS) -o rsa-encrypt$(EXEEXT)
+
+rsa-decrypt$(EXEEXT): rsa-decrypt.$(OBJEXT) read_rsa_key.$(OBJEXT)
+       $(LINK) rsa-decrypt.$(OBJEXT) io.$(OBJEXT) read_rsa_key.$(OBJEXT) \
+       -lhogweed -lnettle $(LIBS) -o rsa-decrypt$(EXEEXT)
+
+eratosthenes$(EXEEXT): eratosthenes.$(OBJEXT) $(GETOPT_OBJS)
+       $(LINK) eratosthenes.$(OBJEXT) $(GETOPT_OBJS) -o eratosthenes$(EXEEXT)
+
+nettle-benchmark$(EXEEXT): nettle-benchmark.$(OBJEXT) nettle-openssl.$(OBJEXT) $(GETOPT_OBJS)
+       $(LINK) nettle-benchmark.$(OBJEXT) nettle-openssl.$(OBJEXT) io.$(OBJEXT) $(GETOPT_OBJS) \
+       -lnettle $(BENCH_LIBS) $(OPENSSL_LIBFLAGS) -o nettle-benchmark$(EXEEXT)
+
+$(TARGETS) : io.$(OBJEXT) ../libnettle.a
+
+
+check: $(TS_ALL)
+       LD_LIBRARY_PATH=../.lib srcdir="$(srcdir)" \
+         "$(srcdir)"/run-tests $(TS_ALL)
+
+Makefile: $(srcdir)/Makefile.in ../config.status
+       cd .. && $(SHELL) ./config.status examples/$@
+
+install uninstall:
+       true
+
+# NOTE: I'd like to use $^, but that's a GNU extension. $? should be
+# more portable, equivalent for phony targets.
+distdir: $(DISTFILES)
+       cp $? $(distdir)
+
+clean:
+       -rm -f $(TARGETS) *.$(OBJEXT)
+
+distclean: clean
+       -rm -f Makefile *.d
+
+tags:
+       etags -o $(srcdir)/TAGS --include $(top_srcdir) $(srcdir)/*.c $(srcdir)/*.h
+
+@DEP_INCLUDE@ $(SOURCES:.c=.$(OBJEXT).d)
diff --git a/examples/eratosthenes.c b/examples/eratosthenes.c
new file mode 100644 (file)
index 0000000..932eebe
--- /dev/null
@@ -0,0 +1,403 @@
+/* eratosthenes.c
+ *
+ * An implementation of the sieve of Eratosthenes, to generate a list of primes.
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2007 Niels Möller
+ *
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "getopt.h"
+
+#ifdef SIZEOF_LONG
+# define BITS_PER_LONG (CHAR_BIT * SIZEOF_LONG)
+# if BITS_PER_LONG > 32
+#  define NEED_HANDLE_LARGE_LONG 1
+# else
+#  define NEED_HANDLE_LARGE_LONG 0
+# endif
+#else
+# define BITS_PER_LONG (CHAR_BIT * sizeof(unsigned long))
+# define NEED_HANDLE_LARGE_LONG 1
+#endif
+
+
+static void
+usage(void)
+{
+  fprintf(stderr, "Usage: erathostenes [OPTIONS] [LIMIT]\n\n"
+         "Options:\n"
+         "      -?         Display this message.\n"
+         "      -b SIZE    Block size.\n"
+         "      -v         Verbose output.\n"
+         "      -s         No output.\n");
+}
+
+static unsigned
+isqrt(unsigned long n)
+{
+  unsigned long x;
+
+  /* FIXME: Better initialization. */
+  if (n < ULONG_MAX)
+    x = n;
+  else
+    /* Must avoid overflow in the first step. */
+    x = n-1;
+
+  for (;;)
+    {
+      unsigned long y = (x + n/x) / 2;
+      if (y >= x)
+       return x;
+
+      x = y;
+    }
+}
+
+/* Size is in bits */
+static unsigned long *
+vector_alloc(unsigned long size)
+{
+  unsigned long end = (size + BITS_PER_LONG - 1) / BITS_PER_LONG;
+  unsigned long *vector = malloc (end * sizeof(long));
+
+  if (!vector)
+    {
+      fprintf(stderr, "Insufficient memory.\n");
+      exit(EXIT_FAILURE);
+    }
+  return vector;
+}
+
+static void
+vector_init(unsigned long *vector, unsigned long size)
+{
+  unsigned long end = (size + BITS_PER_LONG - 1) / BITS_PER_LONG;
+  unsigned long i;
+
+  for (i = 0; i < end; i++)
+    vector[i] = ~0;
+}
+
+static void
+vector_clear_bits (unsigned long *vector, unsigned long step,
+                  unsigned long start, unsigned long size)
+{
+  unsigned long bit;
+
+  for (bit = start; bit < size; bit += step)
+    {
+      unsigned long i = bit / BITS_PER_LONG;
+      unsigned long mask = 1L << (bit % BITS_PER_LONG);
+
+      vector[i] &= ~mask;
+    }
+}
+
+static unsigned
+find_first_one (unsigned long x)
+{  
+  static const unsigned char table[0x101] =
+    {
+     15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     12, 0, 0, 0, 0, 0, 0, 0,11, 0, 0, 0,10, 0, 9, 8,
+      0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
+      4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      7,
+    };
+
+  unsigned i = 0;
+
+  /* Isolate least significant bit */
+  x &= -x;
+
+#if NEED_HANDLE_LARGE_LONG
+#ifndef SIZEOF_LONG
+  /* Can not be tested by the preprocessor. May generate warnings
+     when long is 32 bits. */
+  if (BITS_PER_LONG > 32)
+#endif
+    while (x >= 0x100000000L)
+      {
+       x >>= 32;
+       i += 32;
+      }
+#endif /* NEED_HANDLE_LARGE_LONG */
+
+  if (x >= 0x10000)
+    {
+      x >>= 16;
+      i += 16;
+    }
+  return i + table[128 + (x & 0xff) - (x >> 8)];
+}
+
+/* Returns size if there's no more bits set */
+static unsigned long
+vector_find_next (const unsigned long *vector, unsigned long bit, unsigned long size)
+{
+  unsigned long end = (size + BITS_PER_LONG - 1) / BITS_PER_LONG;
+  unsigned long i = bit / BITS_PER_LONG;
+  unsigned long mask = 1L << (bit % BITS_PER_LONG);
+  unsigned long word;
+
+  if (i >= end)
+    return size;
+
+  for (word = vector[i] & ~(mask - 1); !word; word = vector[i])
+    if (++i >= end)
+      return size;
+
+  /* Next bit is the least significant bit of word */
+  return i * BITS_PER_LONG + find_first_one(word);
+}
+
+/* For benchmarking, define to do nothing (otherwise, most of the time
+   will be spent converting the output to decimal). */
+#define OUTPUT(n) printf("%lu\n", (n))
+
+static long
+atosize(const char *s)
+{
+  char *end;
+  long value = strtol(s, &end, 10);
+
+  if (value <= 0)
+    return 0;
+
+  /* FIXME: Doesn't check for overflow. */
+  switch(*end)
+    {
+    default:
+      return 0;
+    case '\0':
+      break;
+    case 'k': case 'K':
+      value <<= 10;
+      break;
+    case 'M':
+      value <<= 20;
+      break;
+    }
+  return value;
+}
+
+int
+main (int argc, char **argv)
+{
+  /* Generate all primes p <= limit */
+  unsigned long limit;
+  unsigned long root;
+
+  unsigned long limit_nbits;
+
+  /* Represents numbers up to sqrt(limit) */
+  unsigned long sieve_nbits;
+  unsigned long *sieve;
+  /* Block for the rest of the sieving. Size should match the cache,
+     the default value corresponds to 64 KB. */
+  unsigned long block_nbits = 64L << 13;
+  unsigned long block_start_bit;
+  unsigned long *block;
+  
+  unsigned long bit;
+  int silent = 0;
+  int verbose = 0;
+  int c;
+
+  enum { OPT_HELP = 300 };
+  static const struct option options[] =
+    {
+      /* Name, args, flag, val */
+      { "help", no_argument, NULL, OPT_HELP },
+      { "verbose", no_argument, NULL, 'v' },
+      { "block-size", required_argument, NULL, 'b' },
+      { "quiet", required_argument, NULL, 'q' },
+      { NULL, 0, NULL, 0}
+    };
+
+  while ( (c = getopt_long(argc, argv, "svb:", options, NULL)) != -1)
+    switch (c)
+      {
+      case OPT_HELP:
+       usage();
+       return EXIT_SUCCESS;
+      case 'b':
+       block_nbits = CHAR_BIT * atosize(optarg);
+       if (!block_nbits)
+         {
+           usage();
+           return EXIT_FAILURE;
+         }
+       break;
+
+      case 'q':
+       silent = 1;
+       break;
+
+      case 'v':
+       verbose++;
+       break;
+
+      case '?':
+       return EXIT_FAILURE;
+
+      default:
+       abort();
+      }
+
+  argc -= optind;
+  argv += optind;
+
+  if (argc == 0)
+    limit = 1000;
+  else if (argc == 1)
+    {
+      limit = atol(argv[0]);
+      if (limit < 2)
+       return EXIT_SUCCESS;
+    }
+  else
+    {
+      usage();
+      return EXIT_FAILURE;
+    }
+
+  root = isqrt(limit);
+  /* Round down to odd */
+  root = (root - 1) | 1;
+  /* Represents odd numbers from 3 up. */
+  sieve_nbits = (root - 1) / 2;
+  sieve = vector_alloc(sieve_nbits );
+  vector_init(sieve, sieve_nbits);
+
+  if (verbose)
+    fprintf(stderr, "Initial sieve using %lu bits.\n", sieve_nbits);
+      
+  if (!silent)
+    printf("2\n");
+
+  if (limit == 2)
+    return EXIT_SUCCESS;
+
+  for (bit = 0;
+       bit < sieve_nbits;
+       bit = vector_find_next(sieve, bit + 1, sieve_nbits))
+    {
+      unsigned long n = 3 + 2 * bit;
+      /* First bit to clear corresponds to n^2, which is bit
+
+        (n^2 - 3) / 2 = (n + 3) * bit + 3
+      */      
+      unsigned long n2_bit = (n+3)*bit + 3;
+
+      if (!silent)
+       printf("%lu\n", n);
+
+      vector_clear_bits (sieve, n, n2_bit, sieve_nbits);
+    }
+
+  limit_nbits = (limit - 1) / 2;
+
+  if (sieve_nbits + block_nbits > limit_nbits)
+    block_nbits = limit_nbits - sieve_nbits;
+
+  if (verbose)
+    {
+      double storage = block_nbits / 8.0;
+      unsigned shift = 0;
+      const char prefix[] = " KMG";
+
+      while (storage > 1024 && shift < 3)
+       {
+         storage /= 1024;
+         shift++;
+       }
+      fprintf(stderr, "Blockwise sieving using blocks of %lu bits (%.3g %cByte)\n",
+             block_nbits, storage, prefix[shift]);
+    }
+
+  block = vector_alloc(block_nbits);
+
+  for (block_start_bit = bit; block_start_bit < limit_nbits; block_start_bit += block_nbits)
+    {
+      unsigned long block_start;
+      
+      if (block_start_bit + block_nbits > limit_nbits)
+       block_nbits = limit_nbits - block_start_bit;
+
+      vector_init(block, block_nbits);
+
+      block_start = 3 + 2*block_start_bit;
+
+      if (verbose > 1)
+       fprintf(stderr, "Next block, n = %lu\n", block_start);
+
+      /* Sieve */
+      for (bit = 0; bit < sieve_nbits;
+          bit = vector_find_next(sieve, bit + 1, sieve_nbits))
+       {         
+         unsigned long n = 3 + 2 * bit;
+         unsigned long sieve_start_bit = (n + 3) * bit + 3;
+
+         if (sieve_start_bit < block_start_bit)
+           {
+             unsigned long k = (block_start + n - 1) / (2*n);
+             sieve_start_bit = n * k + bit;
+
+             assert(sieve_start_bit < block_start_bit + n);
+           }
+         assert(sieve_start_bit >= block_start_bit);
+
+         vector_clear_bits(block, n, sieve_start_bit - block_start_bit, block_nbits);
+       }
+      for (bit = vector_find_next(block, 0, block_nbits);
+          bit < block_nbits;
+          bit = vector_find_next(block, bit + 1, block_nbits))
+       {
+         unsigned long n = block_start + 2 * bit;
+         if (!silent)
+           printf("%lu\n", n);
+       }
+    }
+  return EXIT_SUCCESS;
+}
diff --git a/examples/getopt.c b/examples/getopt.c
new file mode 100644 (file)
index 0000000..ed32692
--- /dev/null
@@ -0,0 +1,1067 @@
+/* Getopt for GNU.
+   NOTE: getopt is now part of the C library, so if you don't know what
+   "Keep this file name-space clean" means, talk to drepper@gnu.org
+   before changing it!
+   Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
+       Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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, 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.  */
+\f
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+   Ditto for AIX 3.2 and <stdlib.h>.  */
+#ifndef _NO_PROTO
+# define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+   reject `defined (const)'.  */
+# ifndef const
+#  define const
+# endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+# include <gnu-versions.h>
+# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#  define ELIDE_CODE
+# endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+   contain conflicting prototypes for getopt.  */
+# include <stdlib.h>
+# include <unistd.h>
+#endif /* GNU C library.  */
+
+#ifdef VMS
+# include <unixlib.h>
+# if HAVE_STRING_H - 0
+#  include <string.h>
+# endif
+#endif
+
+#ifndef _
+/* This is for other GNU distributions with internationalized messages.  */
+# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
+#  include <libintl.h>
+#  ifndef _
+#   define _(msgid)    gettext (msgid)
+#  endif
+# else
+#  define _(msgid)     (msgid)
+# endif
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+   but it behaves differently for the user, since it allows the user
+   to intersperse the options with the other arguments.
+
+   As `getopt' works, it permutes the elements of ARGV so that,
+   when it is done, all the options precede everything else.  Thus
+   all application programs are extended to handle flexible argument order.
+
+   Setting the environment variable POSIXLY_CORRECT disables permutation.
+   Then the behavior is completely standard.
+
+   GNU application programs can use a third alternative mode in which
+   they can distinguish the relative order of options and other arguments.  */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns -1, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+/* 1003.2 says this must be 1 before any call.  */
+int optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+   causes problems with re-calling getopt as programs generally don't
+   know that. */
+
+int __getopt_initialized;
+
+/* The next char to be scanned in the option-element
+   in which the last option character we returned was found.
+   This allows us to pick up the scan where we left off.
+
+   If this is zero, or a null string, it means resume the scan
+   by advancing to the next ARGV-element.  */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+   REQUIRE_ORDER means don't recognize them as options;
+   stop option processing when the first non-option is seen.
+   This is what Unix does.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-options are at the end.  This allows options
+   to be given in any order, even with programs that were not written to
+   expect this.
+
+   RETURN_IN_ORDER is an option available to programs that were written
+   to expect options and other ARGV-elements in any order and that care about
+   the ordering of the two.  We describe each non-option ARGV-element
+   as if it were the argument of an option with character code 1.
+   Using `-' as the first character of the list of option characters
+   selects this mode of operation.
+
+   The special argument `--' forces an end of option-scanning regardless
+   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+   `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable.  */
+static char *posixly_correct;
+\f
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+   because there are many ways it can cause trouble.
+   On some systems, it contains special magic macros that don't work
+   in GCC.  */
+# include <string.h>
+# define my_index      strchr
+#else
+
+# if HAVE_STRING_H
+#  include <string.h>
+# else
+#  include <strings.h>
+# endif
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+#ifndef getenv
+extern char *getenv ();
+#endif
+
+static char *
+my_index (str, chr)
+     const char *str;
+     int chr;
+{
+  while (*str)
+    {
+      if (*str == chr)
+       return (char *) str;
+      str++;
+    }
+  return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+   If not using GCC, it is ok not to declare it.  */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+   That was relevant to code that was here before.  */
+# if (!defined __STDC__ || !__STDC__) && !defined strlen
+/* gcc with -traditional declares the built-in strlen to return int,
+   and has done so at least since version 2.4.5. -- rms.  */
+extern int strlen (const char *);
+# endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+\f
+/* Handle permutation of arguments.  */
+
+/* Describe the part of ARGV that contains non-options that have
+   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+   `last_nonopt' is the index after the last of them.  */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Bash 2.0 gives us an environment variable containing flags
+   indicating ARGV elements that should not be considered arguments.  */
+
+#ifdef USE_NONOPTION_FLAGS
+/* Defined in getopt_init.c  */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+#endif
+
+static int original_argc;
+static char *const *original_argv;
+
+/* Make sure the environment variable bash 2.0 puts in the environment
+   is valid for the getopt call we must make sure that the ARGV passed
+   to getopt is that one passed to the process.  */
+static void
+__attribute__ ((unused))
+store_args_and_env (int argc, char *const *argv)
+{
+  /* XXX This is no good solution.  We should rather copy the args so
+     that we can compare them later.  But we must not use malloc(3).  */
+  original_argc = argc;
+  original_argv = argv;
+}
+# ifdef text_set_element
+text_set_element (__libc_subinit, store_args_and_env);
+# endif /* text_set_element */
+
+# ifdef USE_NONOPTION_FLAGS
+#  define SWAP_FLAGS(ch1, ch2) \
+  if (nonoption_flags_len > 0)                                               \
+    {                                                                        \
+      char __tmp = __getopt_nonoption_flags[ch1];                            \
+      __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];         \
+      __getopt_nonoption_flags[ch2] = __tmp;                                 \
+    }
+# else
+#  define SWAP_FLAGS(ch1, ch2)
+# endif
+#else  /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [first_nonopt,last_nonopt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [last_nonopt,optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `first_nonopt' and `last_nonopt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.  */
+
+#if defined __STDC__ && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (argv)
+     char **argv;
+{
+  int bottom = first_nonopt;
+  int middle = last_nonopt;
+  int top = optind;
+  char *tem;
+
+  /* Exchange the shorter segment with the far end of the longer segment.
+     That puts the shorter segment into the right place.
+     It leaves the longer segment in the right place overall,
+     but it consists of two parts that need to be swapped next.  */
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+  /* First make sure the handling of the `__getopt_nonoption_flags'
+     string can work normally.  Our top argument must be in the range
+     of the string.  */
+  if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+    {
+      /* We must extend the array.  The user plays games with us and
+        presents new arguments.  */
+      char *new_str = malloc (top + 1);
+      if (new_str == NULL)
+       nonoption_flags_len = nonoption_flags_max_len = 0;
+      else
+       {
+         memset (__mempcpy (new_str, __getopt_nonoption_flags,
+                            nonoption_flags_max_len),
+                 '\0', top + 1 - nonoption_flags_max_len);
+         nonoption_flags_max_len = top + 1;
+         __getopt_nonoption_flags = new_str;
+       }
+    }
+#endif
+
+  while (top > middle && middle > bottom)
+    {
+      if (top - middle > middle - bottom)
+       {
+         /* Bottom segment is the short one.  */
+         int len = middle - bottom;
+         register int i;
+
+         /* Swap it with the top part of the top segment.  */
+         for (i = 0; i < len; i++)
+           {
+             tem = argv[bottom + i];
+             argv[bottom + i] = argv[top - (middle - bottom) + i];
+             argv[top - (middle - bottom) + i] = tem;
+             SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+           }
+         /* Exclude the moved bottom segment from further swapping.  */
+         top -= len;
+       }
+      else
+       {
+         /* Top segment is the short one.  */
+         int len = top - middle;
+         register int i;
+
+         /* Swap it with the bottom part of the bottom segment.  */
+         for (i = 0; i < len; i++)
+           {
+             tem = argv[bottom + i];
+             argv[bottom + i] = argv[middle + i];
+             argv[middle + i] = tem;
+             SWAP_FLAGS (bottom + i, middle + i);
+           }
+         /* Exclude the moved top segment from further swapping.  */
+         bottom += len;
+       }
+    }
+
+  /* Update records for the slots the non-options now occupy.  */
+
+  first_nonopt += (optind - last_nonopt);
+  last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made.  */
+
+#if defined __STDC__ && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  /* Start processing options with ARGV-element 1 (since ARGV-element 0
+     is the program name); the sequence of previously skipped
+     non-option ARGV-elements is empty.  */
+
+  first_nonopt = last_nonopt = optind;
+
+  nextchar = NULL;
+
+  posixly_correct = getenv ("POSIXLY_CORRECT");
+
+  /* Determine how to handle the ordering of options and nonoptions.  */
+
+  if (optstring[0] == '-')
+    {
+      ordering = RETURN_IN_ORDER;
+      ++optstring;
+    }
+  else if (optstring[0] == '+')
+    {
+      ordering = REQUIRE_ORDER;
+      ++optstring;
+    }
+  else if (posixly_correct != NULL)
+    ordering = REQUIRE_ORDER;
+  else
+    ordering = PERMUTE;
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+  if (posixly_correct == NULL
+      && argc == original_argc && argv == original_argv)
+    {
+      if (nonoption_flags_max_len == 0)
+       {
+         if (__getopt_nonoption_flags == NULL
+             || __getopt_nonoption_flags[0] == '\0')
+           nonoption_flags_max_len = -1;
+         else
+           {
+             const char *orig_str = __getopt_nonoption_flags;
+             int len = nonoption_flags_max_len = strlen (orig_str);
+             if (nonoption_flags_max_len < argc)
+               nonoption_flags_max_len = argc;
+             __getopt_nonoption_flags =
+               (char *) malloc (nonoption_flags_max_len);
+             if (__getopt_nonoption_flags == NULL)
+               nonoption_flags_max_len = -1;
+             else
+               memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+                       '\0', nonoption_flags_max_len - len);
+           }
+       }
+      nonoption_flags_len = nonoption_flags_max_len;
+    }
+  else
+    nonoption_flags_len = 0;
+#endif
+
+  return optstring;
+}
+\f
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns -1.
+   Then `optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return '?' after printing an error message.  If you set `opterr' to
+   zero, the error message is suppressed but we still return '?'.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `optarg', otherwise `optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+     const struct option *longopts;
+     int *longind;
+     int long_only;
+{
+  int print_errors = opterr;
+  if (optstring[0] == ':')
+    print_errors = 0;
+
+  if (argc < 1)
+    return -1;
+
+  optarg = NULL;
+
+  if (optind == 0 || !__getopt_initialized)
+    {
+      if (optind == 0)
+       optind = 1;     /* Don't scan ARGV[0], the program name.  */
+      optstring = _getopt_initialize (argc, argv, optstring);
+      __getopt_initialized = 1;
+    }
+
+  /* Test whether ARGV[optind] points to a non-option argument.
+     Either it does not have option syntax, or there is an environment flag
+     from the shell indicating it is not an option.  The later information
+     is only used when the used in the GNU libc.  */
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'              \
+                     || (optind < nonoption_flags_len                        \
+                         && __getopt_nonoption_flags[optind] == '1'))
+#else
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#endif
+
+  if (nextchar == NULL || *nextchar == '\0')
+    {
+      /* Advance to the next ARGV-element.  */
+
+      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+        moved back by the user (who may also have changed the arguments).  */
+      if (last_nonopt > optind)
+       last_nonopt = optind;
+      if (first_nonopt > optind)
+       first_nonopt = optind;
+
+      if (ordering == PERMUTE)
+       {
+         /* If we have just processed some options following some non-options,
+            exchange them so that the options come first.  */
+
+         if (first_nonopt != last_nonopt && last_nonopt != optind)
+           exchange ((char **) argv);
+         else if (last_nonopt != optind)
+           first_nonopt = optind;
+
+         /* Skip any additional non-options
+            and extend the range of non-options previously skipped.  */
+
+         while (optind < argc && NONOPTION_P)
+           optind++;
+         last_nonopt = optind;
+       }
+
+      /* The special ARGV-element `--' means premature end of options.
+        Skip it like a null option,
+        then exchange with previous non-options as if it were an option,
+        then skip everything else like a non-option.  */
+
+      if (optind != argc && !strcmp (argv[optind], "--"))
+       {
+         optind++;
+
+         if (first_nonopt != last_nonopt && last_nonopt != optind)
+           exchange ((char **) argv);
+         else if (first_nonopt == last_nonopt)
+           first_nonopt = optind;
+         last_nonopt = argc;
+
+         optind = argc;
+       }
+
+      /* If we have done all the ARGV-elements, stop the scan
+        and back over any non-options that we skipped and permuted.  */
+
+      if (optind == argc)
+       {
+         /* Set the next-arg-index to point at the non-options
+            that we previously skipped, so the caller will digest them.  */
+         if (first_nonopt != last_nonopt)
+           optind = first_nonopt;
+         return -1;
+       }
+
+      /* If we have come to a non-option and did not permute it,
+        either stop the scan or describe it to the caller and pass it by.  */
+
+      if (NONOPTION_P)
+       {
+         if (ordering == REQUIRE_ORDER)
+           return -1;
+         optarg = argv[optind++];
+         return 1;
+       }
+
+      /* We have found another option-ARGV-element.
+        Skip the initial punctuation.  */
+
+      nextchar = (argv[optind] + 1
+                 + (longopts != NULL && argv[optind][1] == '-'));
+    }
+
+  /* Decode the current option-ARGV-element.  */
+
+  /* Check whether the ARGV-element is a long option.
+
+     If long_only and the ARGV-element has the form "-f", where f is
+     a valid short option, don't consider it an abbreviated form of
+     a long option that starts with f.  Otherwise there would be no
+     way to give the -f short option.
+
+     On the other hand, if there's a long option "fubar" and
+     the ARGV-element is "-fu", do consider that an abbreviation of
+     the long option, just like "--fu", and not "-f" with arg "u".
+
+     This distinction seems to be the most useful approach.  */
+
+  if (longopts != NULL
+      && (argv[optind][1] == '-'
+         || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+    {
+      char *nameend;
+      const struct option *p;
+      const struct option *pfound = NULL;
+      int exact = 0;
+      int ambig = 0;
+      int indfound = -1;
+      int option_index;
+
+      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+       /* Do nothing.  */ ;
+
+      /* Test all long options for either exact match
+        or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name; p++, option_index++)
+       if (!strncmp (p->name, nextchar, nameend - nextchar))
+         {
+           if ((unsigned int) (nameend - nextchar)
+               == (unsigned int) strlen (p->name))
+             {
+               /* Exact match found.  */
+               pfound = p;
+               indfound = option_index;
+               exact = 1;
+               break;
+             }
+           else if (pfound == NULL)
+             {
+               /* First nonexact match found.  */
+               pfound = p;
+               indfound = option_index;
+             }
+           else if (long_only
+                    || pfound->has_arg != p->has_arg
+                    || pfound->flag != p->flag
+                    || pfound->val != p->val)
+             /* Second or later nonexact match found.  */
+             ambig = 1;
+         }
+
+      if (ambig && !exact)
+       {
+         if (print_errors)
+           fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+                    argv[0], argv[optind]);
+         nextchar += strlen (nextchar);
+         optind++;
+         optopt = 0;
+         return '?';
+       }
+
+      if (pfound != NULL)
+       {
+         option_index = indfound;
+         optind++;
+         if (*nameend)
+           {
+             /* Don't test has_arg with >, because some C compilers don't
+                allow it to be used on enums.  */
+             if (pfound->has_arg)
+               optarg = nameend + 1;
+             else
+               {
+                 if (print_errors)
+                   {
+                     if (argv[optind - 1][1] == '-')
+                       /* --option */
+                       fprintf (stderr,
+                                _("%s: option `--%s' doesn't allow an argument\n"),
+                                argv[0], pfound->name);
+                     else
+                       /* +option or -option */
+                       fprintf (stderr,
+                                _("%s: option `%c%s' doesn't allow an argument\n"),
+                                argv[0], argv[optind - 1][0], pfound->name);
+                   }
+
+                 nextchar += strlen (nextchar);
+
+                 optopt = pfound->val;
+                 return '?';
+               }
+           }
+         else if (pfound->has_arg == 1)
+           {
+             if (optind < argc)
+               optarg = argv[optind++];
+             else
+               {
+                 if (print_errors)
+                   fprintf (stderr,
+                          _("%s: option `%s' requires an argument\n"),
+                          argv[0], argv[optind - 1]);
+                 nextchar += strlen (nextchar);
+                 optopt = pfound->val;
+                 return optstring[0] == ':' ? ':' : '?';
+               }
+           }
+         nextchar += strlen (nextchar);
+         if (longind != NULL)
+           *longind = option_index;
+         if (pfound->flag)
+           {
+             *(pfound->flag) = pfound->val;
+             return 0;
+           }
+         return pfound->val;
+       }
+
+      /* Can't find it as a long option.  If this is not getopt_long_only,
+        or the option starts with '--' or is not a valid short
+        option, then it's an error.
+        Otherwise interpret it as a short option.  */
+      if (!long_only || argv[optind][1] == '-'
+         || my_index (optstring, *nextchar) == NULL)
+       {
+         if (print_errors)
+           {
+             if (argv[optind][1] == '-')
+               /* --option */
+               fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+                        argv[0], nextchar);
+             else
+               /* +option or -option */
+               fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+                        argv[0], argv[optind][0], nextchar);
+           }
+         nextchar = (char *) "";
+         optind++;
+         optopt = 0;
+         return '?';
+       }
+    }
+
+  /* Look at and handle the next short option-character.  */
+
+  {
+    char c = *nextchar++;
+    char *temp = my_index (optstring, c);
+
+    /* Increment `optind' when we start to process its last character.  */
+    if (*nextchar == '\0')
+      ++optind;
+
+    if (temp == NULL || c == ':')
+      {
+       if (print_errors)
+         {
+           if (posixly_correct)
+             /* 1003.2 specifies the format of this message.  */
+             fprintf (stderr, _("%s: illegal option -- %c\n"),
+                      argv[0], c);
+           else
+             fprintf (stderr, _("%s: invalid option -- %c\n"),
+                      argv[0], c);
+         }
+       optopt = c;
+       return '?';
+      }
+    /* Convenience. Treat POSIX -W foo same as long option --foo */
+    if (temp[0] == 'W' && temp[1] == ';')
+      {
+       char *nameend;
+       const struct option *p;
+       const struct option *pfound = NULL;
+       int exact = 0;
+       int ambig = 0;
+       int indfound = 0;
+       int option_index;
+
+       /* This is an option that requires an argument.  */
+       if (*nextchar != '\0')
+         {
+           optarg = nextchar;
+           /* If we end this ARGV-element by taking the rest as an arg,
+              we must advance to the next element now.  */
+           optind++;
+         }
+       else if (optind == argc)
+         {
+           if (print_errors)
+             {
+               /* 1003.2 specifies the format of this message.  */
+               fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+                        argv[0], c);
+             }
+           optopt = c;
+           if (optstring[0] == ':')
+             c = ':';
+           else
+             c = '?';
+           return c;
+         }
+       else
+         /* We already incremented `optind' once;
+            increment it again when taking next ARGV-elt as argument.  */
+         optarg = argv[optind++];
+
+       /* optarg is now the argument, see if it's in the
+          table of longopts.  */
+
+       for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+         /* Do nothing.  */ ;
+
+       /* Test all long options for either exact match
+          or abbreviated matches.  */
+       for (p = longopts, option_index = 0; p->name; p++, option_index++)
+         if (!strncmp (p->name, nextchar, nameend - nextchar))
+           {
+             if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+               {
+                 /* Exact match found.  */
+                 pfound = p;
+                 indfound = option_index;
+                 exact = 1;
+                 break;
+               }
+             else if (pfound == NULL)
+               {
+                 /* First nonexact match found.  */
+                 pfound = p;
+                 indfound = option_index;
+               }
+             else
+               /* Second or later nonexact match found.  */
+               ambig = 1;
+           }
+       if (ambig && !exact)
+         {
+           if (print_errors)
+             fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+                      argv[0], argv[optind]);
+           nextchar += strlen (nextchar);
+           optind++;
+           return '?';
+         }
+       if (pfound != NULL)
+         {
+           option_index = indfound;
+           if (*nameend)
+             {
+               /* Don't test has_arg with >, because some C compilers don't
+                  allow it to be used on enums.  */
+               if (pfound->has_arg)
+                 optarg = nameend + 1;
+               else
+                 {
+                   if (print_errors)
+                     fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+                              argv[0], pfound->name);
+
+                   nextchar += strlen (nextchar);
+                   return '?';
+                 }
+             }
+           else if (pfound->has_arg == 1)
+             {
+               if (optind < argc)
+                 optarg = argv[optind++];
+               else
+                 {
+                   if (print_errors)
+                     fprintf (stderr,
+                              _("%s: option `%s' requires an argument\n"),
+                              argv[0], argv[optind - 1]);
+                   nextchar += strlen (nextchar);
+                   return optstring[0] == ':' ? ':' : '?';
+                 }
+             }
+           nextchar += strlen (nextchar);
+           if (longind != NULL)
+             *longind = option_index;
+           if (pfound->flag)
+             {
+               *(pfound->flag) = pfound->val;
+               return 0;
+             }
+           return pfound->val;
+         }
+         nextchar = NULL;
+         return 'W';   /* Let the application handle it.   */
+      }
+    if (temp[1] == ':')
+      {
+       if (temp[2] == ':')
+         {
+           /* This is an option that accepts an argument optionally.  */
+           if (*nextchar != '\0')
+             {
+               optarg = nextchar;
+               optind++;
+             }
+           else
+             optarg = NULL;
+           nextchar = NULL;
+         }
+       else
+         {
+           /* This is an option that requires an argument.  */
+           if (*nextchar != '\0')
+             {
+               optarg = nextchar;
+               /* If we end this ARGV-element by taking the rest as an arg,
+                  we must advance to the next element now.  */
+               optind++;
+             }
+           else if (optind == argc)
+             {
+               if (print_errors)
+                 {
+                   /* 1003.2 specifies the format of this message.  */
+                   fprintf (stderr,
+                            _("%s: option requires an argument -- %c\n"),
+                            argv[0], c);
+                 }
+               optopt = c;
+               if (optstring[0] == ':')
+                 c = ':';
+               else
+                 c = '?';
+             }
+           else
+             /* We already incremented `optind' once;
+                increment it again when taking next ARGV-elt as argument.  */
+             optarg = argv[optind++];
+           nextchar = NULL;
+         }
+      }
+    return c;
+  }
+}
+
+int
+getopt (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  return _getopt_internal (argc, argv, optstring,
+                          (const struct option *) 0,
+                          (int *) 0,
+                          0);
+}
+
+#endif /* Not ELIDE_CODE.  */
+\f
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+   the above definition of `getopt'.  */
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+
+      c = getopt (argc, argv, "abc:d:0123456789");
+      if (c == -1)
+       break;
+
+      switch (c)
+       {
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+         if (digit_optind != 0 && digit_optind != this_option_optind)
+           printf ("digits occur in two different argv-elements.\n");
+         digit_optind = this_option_optind;
+         printf ("option %c\n", c);
+         break;
+
+       case 'a':
+         printf ("option a\n");
+         break;
+
+       case 'b':
+         printf ("option b\n");
+         break;
+
+       case 'c':
+         printf ("option c with value `%s'\n", optarg);
+         break;
+
+       case '?':
+         break;
+
+       default:
+         printf ("?? getopt returned character code 0%o ??\n", c);
+       }
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+       printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/examples/getopt.h b/examples/getopt.h
new file mode 100644 (file)
index 0000000..76cf5ee
--- /dev/null
@@ -0,0 +1,179 @@
+/* Declarations for getopt.
+   Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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, 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.  */
+
+#ifndef _GETOPT_H
+
+#ifndef __need_getopt
+# define _GETOPT_H 1
+#endif
+
+/* If __GNU_LIBRARY__ is not already defined, either we are being used
+   standalone, or this is the first header included in the source file.
+   If we are being used with glibc, we need to include <features.h>, but
+   that does not exist if we are standalone.  So: if __GNU_LIBRARY__ is
+   not defined, include <ctype.h>, which will pull in <features.h> for us
+   if it's from glibc.  (Why ctype.h?  It's guaranteed to exist and it
+   doesn't flood the namespace with stuff the way some other headers do.)  */
+#if !defined __GNU_LIBRARY__
+# include <ctype.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns -1, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int optopt;
+
+#ifndef __need_getopt
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument         (or 0) if the option does not take an argument,
+   required_argument   (or 1) if the option requires an argument,
+   optional_argument   (or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+# if (defined __STDC__ && __STDC__) || defined __cplusplus
+  const char *name;
+# else
+  char *name;
+# endif
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+# define no_argument           0
+# define required_argument     1
+# define optional_argument     2
+#endif /* need getopt */
+
+
+/* Get definitions and prototypes for functions to process the
+   arguments in ARGV (ARGC of them, minus the program name) for
+   options given in OPTS.
+
+   Return the option character from OPTS just read.  Return -1 when
+   there are no more options.  For unrecognized options, or options
+   missing arguments, `optopt' is set to the option letter, and '?' is
+   returned.
+
+   The OPTS string is a list of characters which are recognized option
+   letters, optionally followed by colons, specifying that that letter
+   takes an argument, to be placed in `optarg'.
+
+   If a letter in OPTS is followed by two colons, its argument is
+   optional.  This behavior is specific to the GNU `getopt'.
+
+   The argument `--' causes premature termination of argument
+   scanning, explicitly telling `getopt' that there are no more
+   options.
+
+   If OPTS begins with `--', then non-option arguments are treated as
+   arguments to the option '\0'.  This behavior is specific to the GNU
+   `getopt'.  */
+
+#if (defined __STDC__ && __STDC__) || defined __cplusplus
+# ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+   differences in the consts, in stdlib.h.  To avoid compilation
+   errors, only prototype getopt for the GNU C library.  */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+# else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+# endif /* __GNU_LIBRARY__ */
+
+# ifndef __need_getopt
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+                       const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+                            const char *shortopts,
+                            const struct option *longopts, int *longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _getopt_internal (int argc, char *const *argv,
+                            const char *shortopts,
+                            const struct option *longopts, int *longind,
+                            int long_only);
+# endif
+#else /* not __STDC__ */
+extern int getopt ();
+# ifndef __need_getopt
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+# endif
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Make sure we later can get all the definitions and declarations.  */
+#undef __need_getopt
+
+#endif /* getopt.h */
diff --git a/examples/getopt1.c b/examples/getopt1.c
new file mode 100644 (file)
index 0000000..62c55cf
--- /dev/null
@@ -0,0 +1,187 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+   Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
+     Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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, 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.  */
+\f
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "getopt.h"
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+   reject `defined (const)'.  */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#endif
+
+#ifndef        NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+   If an option that starts with '-' (not '--') doesn't match a long option,
+   but does match a short option, it is parsed as a short option
+   instead.  */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif /* Not ELIDE_CODE.  */
+\f
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+      int option_index = 0;
+      static struct option long_options[] =
+      {
+       {"add", 1, 0, 0},
+       {"append", 0, 0, 0},
+       {"delete", 1, 0, 0},
+       {"verbose", 0, 0, 0},
+       {"create", 0, 0, 0},
+       {"file", 1, 0, 0},
+       {0, 0, 0, 0}
+      };
+
+      c = getopt_long (argc, argv, "abc:d:0123456789",
+                      long_options, &option_index);
+      if (c == -1)
+       break;
+
+      switch (c)
+       {
+       case 0:
+         printf ("option %s", long_options[option_index].name);
+         if (optarg)
+           printf (" with arg %s", optarg);
+         printf ("\n");
+         break;
+
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+         if (digit_optind != 0 && digit_optind != this_option_optind)
+           printf ("digits occur in two different argv-elements.\n");
+         digit_optind = this_option_optind;
+         printf ("option %c\n", c);
+         break;
+
+       case 'a':
+         printf ("option a\n");
+         break;
+
+       case 'b':
+         printf ("option b\n");
+         break;
+
+       case 'c':
+         printf ("option c with value `%s'\n", optarg);
+         break;
+
+       case 'd':
+         printf ("option d with value `%s'\n", optarg);
+         break;
+
+       case '?':
+         break;
+
+       default:
+         printf ("?? getopt returned character code 0%o ??\n", c);
+       }
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+       printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/examples/io.c b/examples/io.c
new file mode 100644 (file)
index 0000000..c24546f
--- /dev/null
@@ -0,0 +1,194 @@
+/* io.c
+ *
+ * Miscellaneous functions used by the example programs.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+/* For errno and strerror */
+#include <errno.h>
+#include <string.h>
+
+#include "io.h"
+
+#define RANDOM_DEVICE "/dev/urandom"
+#define BUFSIZE 1000
+
+int quiet_flag = 0;
+
+void *
+xalloc(size_t size)
+{
+  void *p = malloc(size);
+  if (!p)
+    {
+      fprintf(stderr, "Virtual memory exhausted.\n");
+      abort();
+    }
+
+  return p;
+}
+
+void
+werror(const char *format, ...)
+{
+  if (!quiet_flag)
+    {
+      va_list args;
+      va_start(args, format);
+      vfprintf(stderr, format, args);
+      va_end(args);
+    }
+}
+
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+
+unsigned
+read_file(const char *name, unsigned max_size, char **contents)
+{
+  unsigned size;
+  unsigned done;
+  char *buffer;
+  FILE *f;
+    
+  f = fopen(name, "rb");
+  if (!f)
+    {
+      werror("Opening `%s' failed: %s\n", name, strerror(errno));
+      return 0;
+    }
+  buffer = NULL;
+
+  if (max_size && max_size < 100)
+    size = max_size;
+  else
+    size = 100;
+
+  /* FIXME: The use of feof and ferror in this loop is a bit confused
+     (but I think it is still correct). We should check the return
+     value of fread, and call feof and/or ferror when we get a short
+     item count. */    
+
+  for (done = 0;
+       (!max_size || done < max_size) && !feof(f);
+       size *= 2)
+    {
+      char *p;
+
+      if (max_size && size > max_size)
+       size = max_size;
+
+      /* Space for terminating NUL */
+      p = realloc(buffer, size + 1);
+
+      if (!p)
+       {
+       fail:
+         fclose(f);
+         free(buffer);
+         *contents = NULL;
+         return 0;
+       }
+
+      buffer = p;
+      done += fread(buffer + done, 1, size - done, f);
+
+      if (ferror(f))
+       goto fail;
+    }
+  
+  fclose(f);
+
+  /* NUL-terminate the data. */
+  buffer[done] = '\0';
+  *contents = buffer;
+  
+  return done;
+}
+
+int
+write_file(const char *name, unsigned size, const char *buffer)
+{
+  FILE *f = fopen(name, "wb");
+  unsigned res;
+  
+  if (!f)
+    return 0;
+
+  res = fwrite(buffer, 1, size, f);
+  
+  if (res < size)
+    res = 0;
+
+  return fclose(f) == 0 && res > 0;
+}
+
+int
+write_string(FILE *f, unsigned size, const char *buffer)
+{
+  size_t res = fwrite(buffer, 1, size, f);
+
+  return res == size;
+}
+
+int
+simple_random(struct yarrow256_ctx *ctx, const char *name)
+{
+  unsigned length;
+  char *buffer;
+
+  if (name)
+    length = read_file(name, 0, &buffer);
+  else
+    length = read_file(RANDOM_DEVICE, 20, &buffer);
+  
+  if (!length)
+    return 0;
+
+  yarrow256_seed(ctx, length, buffer);
+
+  free(buffer);
+
+  return 1;
+}
+
+int
+hash_file(const struct nettle_hash *hash, void *ctx, FILE *f)
+{
+  for (;;)
+    {
+      char buffer[BUFSIZE];
+      size_t res = fread(buffer, 1, sizeof(buffer), f);
+      if (ferror(f))
+       return 0;
+      
+      hash->update(ctx, res, buffer);
+      if (feof(f))
+       return 1;
+    }
+}
diff --git a/examples/io.h b/examples/io.h
new file mode 100644 (file)
index 0000000..e85dc5f
--- /dev/null
@@ -0,0 +1,73 @@
+/* io.c
+ *
+ * Miscellaneous functions used by the example programs.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_EXAMPLES_IO_H_INCLUDED
+#define NETTLE_EXAMPLES_IO_H_INCLUDED
+
+#include "nettle-meta.h"
+#include "yarrow.h"
+
+#include <stdio.h>
+
+extern int quiet_flag;
+
+void *
+xalloc(size_t size);
+
+void
+werror(const char *format, ...)
+#if __GNUC___
+     __attribute__((__format__ (__printf__,1, 2)))
+#endif
+     ;
+
+/* If size is > 0, read at most that many bytes. If size == 0,
+ * read until EOF. Allocates the buffer dynamically. */
+unsigned
+read_file(const char *name, unsigned size, char **buffer);
+
+int
+write_file(const char *name, unsigned size, const char *buffer);
+
+int
+write_string(FILE *f, unsigned size, const char *buffer);
+
+int
+simple_random(struct yarrow256_ctx *ctx, const char *name);
+
+int
+hash_file(const struct nettle_hash *hash, void *ctx, FILE *f);
+
+#if WITH_HOGWEED
+struct rsa_public_key;
+struct rsa_private_key;
+
+int
+read_rsa_key(const char *name,
+            struct rsa_public_key *pub,
+            struct rsa_private_key *priv);
+#endif /* WITH_HOGWEED */
+
+#endif /* NETTLE_EXAMPLES_IO_H_INCLUDED */
diff --git a/examples/nettle-benchmark.c b/examples/nettle-benchmark.c
new file mode 100644 (file)
index 0000000..221033e
--- /dev/null
@@ -0,0 +1,696 @@
+/* nettle-benchmark.c
+ *
+ * Tries the performance of the various algorithms.
+ *
+ */
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <math.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <time.h>
+
+#include "aes.h"
+#include "arcfour.h"
+#include "blowfish.h"
+#include "cast128.h"
+#include "cbc.h"
+#include "ctr.h"
+#include "des.h"
+#include "gcm.h"
+#include "memxor.h"
+#include "serpent.h"
+#include "sha.h"
+#include "twofish.h"
+
+#include "nettle-meta.h"
+#include "nettle-internal.h"
+
+#include "getopt.h"
+
+static double frequency = 0.0;
+
+/* Process BENCH_BLOCK bytes at a time, for BENCH_INTERVAL seconds. */
+#define BENCH_BLOCK 10240
+#define BENCH_INTERVAL 0.1
+
+/* FIXME: Proper configure test for rdtsc? */
+#ifndef WITH_CYCLE_COUNTER
+# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+#  define WITH_CYCLE_COUNTER 1
+# else
+#  define WITH_CYCLE_COUNTER 0
+# endif
+#endif
+
+#if WITH_CYCLE_COUNTER
+# if defined(__i386__)
+#define GET_CYCLE_COUNTER(hi, lo)              \
+  __asm__("xorl %%eax,%%eax\n"                 \
+         "movl %%ebx, %%edi\n"                 \
+         "cpuid\n"                             \
+         "rdtsc\n"                             \
+         "movl %%edi, %%ebx\n"                 \
+         : "=a" (lo), "=d" (hi)                \
+         : /* No inputs. */                    \
+         : "%edi", "%ecx", "cc")
+# elif defined(__x86_64__)
+#define GET_CYCLE_COUNTER(hi, lo)              \
+  __asm__("xorl %%eax,%%eax\n"                 \
+         "mov %%rbx, %%r10\n"                  \
+         "cpuid\n"                             \
+         "rdtsc\n"                             \
+         "mov %%r10, %%rbx\n"                  \
+         : "=a" (lo), "=d" (hi)                \
+         : /* No inputs. */                    \
+         : "%r10", "%rcx", "cc")
+# endif
+#define BENCH_ITERATIONS 10
+#endif
+
+static void
+die(const char *format, ...)
+{
+  va_list args;
+  va_start(args, format);
+  vfprintf(stderr, format, args);
+  va_end(args);
+
+  exit(EXIT_FAILURE);
+}
+
+static double overhead = 0.0; 
+
+#if HAVE_CLOCK_GETTIME && defined CLOCK_PROCESS_CPUTIME_ID
+#define TRY_CLOCK_GETTIME 1
+struct timespec cgt_start;
+
+static int
+cgt_works_p(void)
+{
+  struct timespec now;
+  return clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &now) == 0;
+}
+
+static void
+cgt_time_start(void)
+{
+  if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cgt_start) < 0)
+    die("clock_gettime failed: %s\n", strerror(errno));
+}
+
+static double
+cgt_time_end(void)
+{
+    struct timespec end;
+    if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end) < 0)
+      die("clock_gettime failed: %s\n", strerror(errno));
+
+    return end.tv_sec - cgt_start.tv_sec
+      + 1e-9 * (end.tv_nsec - cgt_start.tv_nsec);
+}
+
+static void (*time_start)(void);
+static double (*time_end)(void);
+
+#else /* !HAVE_CLOCK_GETTIME */
+#define TRY_CLOCK_GETTIME 0
+#define time_start clock_time_start
+#define time_end clock_time_end
+#endif /* !HAVE_CLOCK_GETTIME */
+
+static clock_t clock_start;
+
+static void
+clock_time_start(void)
+{
+  clock_start = clock();
+}
+
+static double
+clock_time_end(void)
+{
+  return (double) (clock() - (clock_start)) / CLOCKS_PER_SEC;
+}
+
+/* Returns second per function call */
+static double
+time_function(void (*f)(void *arg), void *arg)
+{
+  unsigned ncalls;
+  double elapsed;
+
+  for (ncalls = 10 ;;)
+    {
+      unsigned i;
+
+      time_start();
+      for (i = 0; i < ncalls; i++)
+       f(arg);
+      elapsed = time_end();
+      if (elapsed > BENCH_INTERVAL)
+       break;
+      else if (elapsed < BENCH_INTERVAL / 10)
+       ncalls *= 10;
+      else
+       ncalls *= 2;
+    }
+  return elapsed / ncalls - overhead;
+}
+
+static void
+bench_nothing(void *arg UNUSED)
+{
+  return;
+}
+
+struct bench_memxor_info
+{
+  uint8_t *dst;
+  const uint8_t *src;
+  const uint8_t *other;  
+};
+
+static void
+bench_memxor(void *arg)
+{
+  struct bench_memxor_info *info = arg;
+  memxor (info->dst, info->src, BENCH_BLOCK);
+}
+
+static void
+bench_memxor3(void *arg)
+{
+  struct bench_memxor_info *info = arg;
+  memxor3 (info->dst, info->src, info->other, BENCH_BLOCK);
+}
+
+struct bench_hash_info
+{
+  void *ctx;
+  nettle_hash_update_func *update;
+  const uint8_t *data;
+};
+
+static void
+bench_hash(void *arg)
+{
+  struct bench_hash_info *info = arg;
+  info->update(info->ctx, BENCH_BLOCK, info->data);
+}
+
+struct bench_cipher_info
+{
+  void *ctx;
+  nettle_crypt_func *crypt;
+  uint8_t *data;
+};
+
+static void
+bench_cipher(void *arg)
+{
+  struct bench_cipher_info *info = arg;
+  info->crypt(info->ctx, BENCH_BLOCK, info->data, info->data);
+}
+
+struct bench_cbc_info
+{
+  void *ctx;
+  nettle_crypt_func *crypt;
+  uint8_t *data;
+  
+  unsigned block_size;
+  uint8_t *iv;
+};
+
+static void
+bench_cbc_encrypt(void *arg)
+{
+  struct bench_cbc_info *info = arg;
+  cbc_encrypt(info->ctx, info->crypt,
+             info->block_size, info->iv,
+             BENCH_BLOCK, info->data, info->data);
+}
+
+static void
+bench_cbc_decrypt(void *arg)
+{
+  struct bench_cbc_info *info = arg;
+  cbc_decrypt(info->ctx, info->crypt,
+             info->block_size, info->iv,
+             BENCH_BLOCK, info->data, info->data);
+}
+
+static void
+bench_ctr(void *arg)
+{
+  struct bench_cbc_info *info = arg;
+  ctr_crypt(info->ctx, info->crypt,
+           info->block_size, info->iv,
+           BENCH_BLOCK, info->data, info->data);
+}
+
+/* Set data[i] = floor(sqrt(i)) */
+static void
+init_data(uint8_t *data)
+{
+  unsigned i,j;
+  for (i = j = 0; i<BENCH_BLOCK;  i++)
+    {
+      if (j*j < i)
+       j++;
+      data[i] = j;
+    }
+}
+
+static void
+init_key(unsigned length,
+         uint8_t *key)
+{
+  unsigned i;
+  for (i = 0; i<length; i++)
+    key[i] = i;
+}
+
+static void
+header(void)
+{
+  printf("%18s %11s Mbyte/s%s\n",
+        "Algorithm", "mode", 
+        frequency > 0.0 ? " cycles/byte cycles/block" : "");  
+}
+
+static void
+display(const char *name, const char *mode, unsigned block_size,
+       double time)
+{
+  printf("%18s %11s %7.2f",
+        name, mode,
+        BENCH_BLOCK / (time * 1048576.0));
+  if (frequency > 0.0)
+    {
+      printf(" %11.2f", time * frequency / BENCH_BLOCK);
+      if (block_size > 0)
+       printf(" %12.2f", time * frequency * block_size / BENCH_BLOCK);
+    }
+  printf("\n");
+}
+
+static void *
+xalloc(size_t size)
+{
+  void *p = malloc(size);
+  if (!p)
+    die("Virtual memory exhausted.\n");
+
+  return p;
+}
+
+static void
+time_overhead(void)
+{
+  overhead = time_function(bench_nothing, NULL);
+  printf("benchmark call overhead: %7f us", overhead * 1e6);
+  if (frequency > 0.0)
+    printf("%7.2f cycles\n", overhead * frequency);
+  printf("\n");  
+}
+
+
+
+static void
+time_memxor(void)
+{
+  struct bench_memxor_info info;
+  uint8_t src[BENCH_BLOCK + sizeof(long)];
+  uint8_t other[BENCH_BLOCK + sizeof(long)];
+  uint8_t dst[BENCH_BLOCK];
+
+  info.src = src;
+  info.dst = dst;
+
+  display ("memxor", "aligned", sizeof(unsigned long),
+          time_function(bench_memxor, &info));
+  info.src = src + 1;
+  display ("memxor", "unaligned", sizeof(unsigned long),
+          time_function(bench_memxor, &info));
+
+  info.src = src;
+  info.other = other;
+  display ("memxor3", "aligned", sizeof(unsigned long),
+          time_function(bench_memxor3, &info));
+
+  info.other = other + 1;
+  display ("memxor3", "unaligned01", sizeof(unsigned long),
+          time_function(bench_memxor3, &info));
+  info.src = src + 1;
+  display ("memxor3", "unaligned11", sizeof(unsigned long),
+          time_function(bench_memxor3, &info));
+  info.other = other + 2;
+  display ("memxor3", "unaligned12", sizeof(unsigned long),
+          time_function(bench_memxor3, &info));  
+}
+
+static void
+time_hash(const struct nettle_hash *hash)
+{
+  static uint8_t data[BENCH_BLOCK];
+  struct bench_hash_info info;
+
+  info.ctx = xalloc(hash->context_size); 
+  info.update = hash->update;
+  info.data = data;
+
+  init_data(data);
+  hash->init(info.ctx);
+
+  display(hash->name, "update", hash->block_size,
+         time_function(bench_hash, &info));
+
+  free(info.ctx);
+}
+
+static void
+time_gcm(void)
+{
+  static uint8_t data[BENCH_BLOCK];
+  struct bench_hash_info hinfo;
+  struct bench_cipher_info cinfo;
+  struct gcm_aes_ctx ctx;
+
+  uint8_t key[16];
+  uint8_t iv[GCM_IV_SIZE];
+
+  gcm_aes_set_key(&ctx, sizeof(key), key);
+  gcm_aes_set_iv(&ctx, sizeof(iv), iv);
+
+  hinfo.ctx = &ctx;
+  hinfo.update = (nettle_hash_update_func *) gcm_aes_update;
+  hinfo.data = data;
+  
+  display("gcm-aes", "update", GCM_BLOCK_SIZE,
+         time_function(bench_hash, &hinfo));
+  
+  cinfo.ctx = &ctx;
+  cinfo.crypt = (nettle_crypt_func *) gcm_aes_encrypt;
+  cinfo.data = data;
+
+  display("gcm-aes", "encrypt", GCM_BLOCK_SIZE,
+         time_function(bench_cipher, &cinfo));
+
+  cinfo.crypt = (nettle_crypt_func *) gcm_aes_decrypt;
+
+  display("gcm-aes", "decrypt", GCM_BLOCK_SIZE,
+         time_function(bench_cipher, &cinfo));
+}
+
+static void
+time_cipher(const struct nettle_cipher *cipher)
+{
+  void *ctx = xalloc(cipher->context_size);
+  uint8_t *key = xalloc(cipher->key_size);
+
+  static uint8_t data[BENCH_BLOCK];
+
+  printf("\n");
+  
+  init_data(data);
+
+  {
+    /* Decent initializers are a GNU extension, so don't use it here. */
+    struct bench_cipher_info info;
+    info.ctx = ctx;
+    info.crypt = cipher->encrypt;
+    info.data = data;
+    
+    init_key(cipher->key_size, key);
+    cipher->set_encrypt_key(ctx, cipher->key_size, key);
+
+    display(cipher->name, "ECB encrypt", cipher->block_size,
+           time_function(bench_cipher, &info));
+  }
+  
+  {
+    struct bench_cipher_info info;
+    info.ctx = ctx;
+    info.crypt = cipher->decrypt;
+    info.data = data;
+    
+    init_key(cipher->key_size, key);
+    cipher->set_decrypt_key(ctx, cipher->key_size, key);
+
+    display(cipher->name, "ECB decrypt", cipher->block_size,
+           time_function(bench_cipher, &info));
+  }
+
+  /* Don't use nettle cbc to benchmark openssl ciphers */
+  if (cipher->block_size && cipher->name[0] != 'o')
+    {
+      uint8_t *iv = xalloc(cipher->block_size);
+      
+      /* Do CBC mode */
+      {
+        struct bench_cbc_info info;
+       info.ctx = ctx;
+       info.crypt = cipher->encrypt;
+       info.data = data;
+       info.block_size = cipher->block_size;
+       info.iv = iv;
+    
+        memset(iv, 0, sizeof(iv));
+    
+        cipher->set_encrypt_key(ctx, cipher->key_size, key);
+
+       display(cipher->name, "CBC encrypt", cipher->block_size,
+               time_function(bench_cbc_encrypt, &info));
+      }
+
+      {
+        struct bench_cbc_info info;
+       info.ctx = ctx;
+       info.crypt = cipher->decrypt;
+       info.data = data;
+       info.block_size = cipher->block_size;
+       info.iv = iv;
+    
+        memset(iv, 0, sizeof(iv));
+
+        cipher->set_decrypt_key(ctx, cipher->key_size, key);
+
+       display(cipher->name, "CBC decrypt", cipher->block_size,
+               time_function(bench_cbc_decrypt, &info));
+      }
+
+      /* Do CTR mode */
+      {
+        struct bench_cbc_info info;
+       info.ctx = ctx;
+       info.crypt = cipher->encrypt;
+       info.data = data;
+       info.block_size = cipher->block_size;
+       info.iv = iv;
+    
+        memset(iv, 0, sizeof(iv));
+    
+        cipher->set_encrypt_key(ctx, cipher->key_size, key);
+
+       display(cipher->name, "CTR", cipher->block_size,
+               time_function(bench_ctr, &info));       
+      }
+      
+      free(iv);
+    }
+  free(ctx);
+  free(key);
+}
+
+static int
+compare_double(const void *ap, const void *bp)
+{
+  double a = *(const double *) ap;
+  double b = *(const double *) bp;
+  if (a < b)
+    return -1;
+  else if (a > b)
+    return 1;
+  else
+    return 0;
+}
+
+/* Try to get accurate cycle times for assembler functions. */
+static void
+bench_sha1_compress(void)
+{
+#if WITH_CYCLE_COUNTER
+  uint32_t state[_SHA1_DIGEST_LENGTH];
+  uint8_t data[BENCH_ITERATIONS * SHA1_DATA_SIZE];
+  uint32_t start_lo, start_hi, end_lo, end_hi;
+
+  double count[5];
+  
+  uint8_t *p;
+  unsigned i, j;
+
+  for (j = 0; j < 5; j++)
+    {
+      i = 0;
+      p = data;
+      GET_CYCLE_COUNTER(start_hi, start_lo);
+      for (; i < BENCH_ITERATIONS; i++, p += SHA1_DATA_SIZE)
+       _nettle_sha1_compress(state, p);
+
+      GET_CYCLE_COUNTER(end_hi, end_lo);
+
+      end_hi -= (start_hi + (start_lo > end_lo));
+      end_lo -= start_lo;
+
+      count[j] = ldexp(end_hi, 32) + end_lo;
+    }
+
+  qsort(count, 5, sizeof(double), compare_double);
+  printf("sha1_compress: %.2f cycles\n\n", count[2] / BENCH_ITERATIONS);  
+#endif
+}
+
+#if WITH_OPENSSL
+# define OPENSSL(x) x,
+#else
+# define OPENSSL(x)
+#endif
+
+int
+main(int argc, char **argv)
+{
+  unsigned i;
+  int c;
+  const char *alg;
+
+  const struct nettle_hash *hashes[] =
+    {
+      &nettle_md2, &nettle_md4, &nettle_md5,
+      OPENSSL(&nettle_openssl_md5)
+      &nettle_sha1, OPENSSL(&nettle_openssl_sha1)
+      &nettle_sha224, &nettle_sha256,
+      &nettle_sha384, &nettle_sha512,
+      &nettle_ripemd160,
+      NULL
+    };
+
+  const struct nettle_cipher *ciphers[] =
+    {
+      &nettle_aes128, &nettle_aes192, &nettle_aes256,
+      OPENSSL(&nettle_openssl_aes128)
+      OPENSSL(&nettle_openssl_aes192)
+      OPENSSL(&nettle_openssl_aes256)
+      &nettle_arcfour128, OPENSSL(&nettle_openssl_arcfour128)
+      &nettle_blowfish128, OPENSSL(&nettle_openssl_blowfish128)
+      &nettle_camellia128, &nettle_camellia192, &nettle_camellia256,
+      &nettle_cast128, OPENSSL(&nettle_openssl_cast128)
+      &nettle_des, OPENSSL(&nettle_openssl_des)
+      &nettle_des3,
+      &nettle_serpent256,
+      &nettle_twofish128, &nettle_twofish192, &nettle_twofish256,
+      NULL
+    };
+
+  enum { OPT_HELP = 300 };
+  static const struct option options[] =
+    {
+      /* Name, args, flag, val */
+      { "help", no_argument, NULL, OPT_HELP },
+      { "clock-frequency", required_argument, NULL, 'f' },
+      { NULL, 0, NULL, 0 }
+    };
+  
+  while ( (c = getopt_long(argc, argv, "f:", options, NULL)) != -1)
+    switch (c)
+      {
+      case 'f':
+       frequency = atof(optarg);
+       if (frequency > 0.0)
+         break;
+
+      case OPT_HELP:
+       printf("Usage: nettle-benchmark [-f clock frequency] [alg]\n");
+       return EXIT_SUCCESS;
+
+      case '?':
+       return EXIT_FAILURE;
+
+      default:
+       abort();
+    }
+
+  alg = argv[optind];
+
+  /* Choose timing function */
+#if TRY_CLOCK_GETTIME
+  if (cgt_works_p())
+    {
+      time_start = cgt_time_start;
+      time_end = cgt_time_end;
+    }
+  else
+    {
+      fprintf(stderr, "clock_gettime not working, falling back to clock\n");
+      time_start = clock_time_start;
+      time_end = clock_time_end;
+    }
+#endif
+  bench_sha1_compress();
+
+  time_overhead();
+
+  header();
+
+  if (!alg || strstr ("memxor", alg))
+    {
+      time_memxor();
+      printf("\n");
+    }
+  
+  for (i = 0; hashes[i]; i++)
+    if (!alg || strstr(hashes[i]->name, alg))
+      time_hash(hashes[i]);
+
+  for (i = 0; ciphers[i]; i++)
+    if (!alg || strstr(ciphers[i]->name, alg))
+      time_cipher(ciphers[i]);
+
+  if (!alg || strstr ("gcm", alg))
+    {
+      printf("\n");
+      time_gcm();
+    }
+
+  return 0;
+}
diff --git a/examples/nettle-openssl.c b/examples/nettle-openssl.c
new file mode 100644 (file)
index 0000000..5f5f2b1
--- /dev/null
@@ -0,0 +1,372 @@
+/* nettle-openssl.c
+ *
+ * Glue that's used only by the benchmark, and subject to change.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+/* Openssl glue, for comparative benchmarking only */
+
+#if WITH_OPENSSL
+
+/* No ancient ssleay compatibility */
+#define NCOMPAT
+#define OPENSSL_DISABLE_OLD_DES_SUPPORT
+
+#include <assert.h>
+
+#include <openssl/aes.h>
+#include <openssl/blowfish.h>
+#include <openssl/des.h>
+#include <openssl/cast.h>
+#include <openssl/rc4.h>
+
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+
+#include "nettle-internal.h"
+
+
+/* AES */
+static nettle_set_key_func openssl_aes_set_encrypt_key;
+static void
+openssl_aes_set_encrypt_key(void *ctx, unsigned length, const uint8_t *key)
+{
+  AES_set_encrypt_key(key, length * 8, ctx);
+}
+
+static nettle_set_key_func openssl_aes_set_decrypt_key;
+static void
+openssl_aes_set_decrypt_key(void *ctx, unsigned length, const uint8_t *key)
+{
+  AES_set_decrypt_key(key, length * 8, ctx);
+}
+
+static nettle_crypt_func openssl_aes_encrypt;
+static void
+openssl_aes_encrypt(void *ctx, unsigned length,
+                   uint8_t *dst, const uint8_t *src)
+{
+  assert (!(length % AES_BLOCK_SIZE));
+  while (length)
+    {
+      AES_ecb_encrypt(src, dst, ctx, AES_ENCRYPT);
+      length -= AES_BLOCK_SIZE;
+      dst += AES_BLOCK_SIZE;
+      src += AES_BLOCK_SIZE;
+    }
+}
+
+static nettle_crypt_func openssl_aes_decrypt;
+static void
+openssl_aes_decrypt(void *ctx, unsigned length,
+                   uint8_t *dst, const uint8_t *src)
+{
+  assert (!(length % AES_BLOCK_SIZE));
+  while (length)
+    {
+      AES_ecb_encrypt(src, dst, ctx, AES_DECRYPT);
+      length -= AES_BLOCK_SIZE;
+      dst += AES_BLOCK_SIZE;
+      src += AES_BLOCK_SIZE;
+    }
+}
+
+const struct nettle_cipher
+nettle_openssl_aes128 = {
+  "openssl aes128", sizeof(AES_KEY),
+  16, 16,
+  openssl_aes_set_encrypt_key, openssl_aes_set_decrypt_key,
+  openssl_aes_encrypt, openssl_aes_decrypt
+};
+
+const struct nettle_cipher
+nettle_openssl_aes192 = {
+  "openssl aes192", sizeof(AES_KEY),
+  /* Claim no block size, so that the benchmark doesn't try CBC mode
+   * (as openssl cipher + nettle cbc is somewhat pointless to
+   * benchmark). */
+  16, 24,
+  openssl_aes_set_encrypt_key, openssl_aes_set_decrypt_key,
+  openssl_aes_encrypt, openssl_aes_decrypt
+};
+
+const struct nettle_cipher
+nettle_openssl_aes256 = {
+  "openssl aes256", sizeof(AES_KEY),
+  /* Claim no block size, so that the benchmark doesn't try CBC mode
+   * (as openssl cipher + nettle cbc is somewhat pointless to
+   * benchmark). */
+  16, 32,
+  openssl_aes_set_encrypt_key, openssl_aes_set_decrypt_key,
+  openssl_aes_encrypt, openssl_aes_decrypt
+};
+
+/* Arcfour */
+static nettle_set_key_func openssl_arcfour_set_key;
+static void
+openssl_arcfour_set_key(void *ctx, unsigned length, const uint8_t *key)
+{
+  RC4_set_key(ctx, length, key);
+}
+
+static nettle_crypt_func openssl_arcfour_crypt;
+static void
+openssl_arcfour_crypt(void *ctx, unsigned length,
+                     uint8_t *dst, const uint8_t *src)
+{
+  RC4(ctx, length, src, dst);
+}
+
+const struct nettle_cipher
+nettle_openssl_arcfour128 = {
+  "openssl arcfour128", sizeof(RC4_KEY),
+  0, 16,
+  openssl_arcfour_set_key, openssl_arcfour_set_key,
+  openssl_arcfour_crypt, openssl_arcfour_crypt
+};
+
+/* Blowfish */
+static nettle_set_key_func openssl_bf_set_key;
+static void
+openssl_bf_set_key(void *ctx, unsigned length, const uint8_t *key)
+{
+  BF_set_key(ctx, length, key);
+}
+
+static nettle_crypt_func openssl_bf_encrypt;
+static void
+openssl_bf_encrypt(void *ctx, unsigned length,
+                  uint8_t *dst, const uint8_t *src)
+{
+  assert (!(length % BF_BLOCK));
+  while (length)
+    {
+      BF_ecb_encrypt(src, dst, ctx, BF_ENCRYPT);
+      length -= BF_BLOCK;
+      dst += BF_BLOCK;
+      src += BF_BLOCK;
+    }
+}
+
+static nettle_crypt_func openssl_bf_decrypt;
+static void
+openssl_bf_decrypt(void *ctx, unsigned length,
+                  uint8_t *dst, const uint8_t *src)
+{
+  assert (!(length % BF_BLOCK));
+  while (length)
+    {
+      BF_ecb_encrypt(src, dst, ctx, BF_DECRYPT);
+      length -= BF_BLOCK;
+      dst += BF_BLOCK;
+      src += BF_BLOCK;
+    }
+}
+
+const struct nettle_cipher
+nettle_openssl_blowfish128 = {
+  "openssl bf128", sizeof(BF_KEY),
+  8, 16,
+  openssl_bf_set_key, openssl_bf_set_key,
+  openssl_bf_encrypt, openssl_bf_decrypt
+};
+
+
+/* DES */
+static nettle_set_key_func openssl_des_set_key;
+static void
+openssl_des_set_key(void *ctx, unsigned length, const uint8_t *key)
+{
+  assert(length == 8);  
+  /* Not sure what "unchecked" means. We want to ignore parity bits,
+     but it would still make sense to check for weak keys. */
+  /* Explicit cast used as I don't want to care about openssl's broken
+     array typedefs DES_cblock and const_DES_cblock. */
+  DES_set_key_unchecked( (void *) key, ctx);
+}
+
+#define DES_BLOCK_SIZE 8
+
+static nettle_crypt_func openssl_des_encrypt;
+static void
+openssl_des_encrypt(void *ctx, unsigned length,
+                   uint8_t *dst, const uint8_t *src)
+{
+  assert (!(length % DES_BLOCK_SIZE));
+  while (length)
+    {
+      DES_ecb_encrypt((void *) src, (void *) dst, ctx, DES_ENCRYPT);
+      length -= DES_BLOCK_SIZE;
+      dst += DES_BLOCK_SIZE;
+      src += DES_BLOCK_SIZE;
+    }
+}
+
+static nettle_crypt_func openssl_des_decrypt;
+static void
+openssl_des_decrypt(void *ctx, unsigned length,
+                   uint8_t *dst, const uint8_t *src)
+{
+  assert (!(length % DES_BLOCK_SIZE));
+  while (length)
+    {
+      DES_ecb_encrypt((void *) src, (void *) dst, ctx, DES_DECRYPT);
+      length -= DES_BLOCK_SIZE;
+      dst += DES_BLOCK_SIZE;
+      src += DES_BLOCK_SIZE;
+    }
+}
+
+const struct nettle_cipher
+nettle_openssl_des = {
+  "openssl des", sizeof(DES_key_schedule),
+  8, 8,
+  openssl_des_set_key, openssl_des_set_key,
+  openssl_des_encrypt, openssl_des_decrypt
+};
+
+
+/* Cast128 */
+static nettle_set_key_func openssl_cast_set_key;
+static void
+openssl_cast_set_key(void *ctx, unsigned length, const uint8_t *key)
+{
+  CAST_set_key(ctx, length, key);
+}
+
+static nettle_crypt_func openssl_cast_encrypt;
+static void
+openssl_cast_encrypt(void *ctx, unsigned length,
+                    uint8_t *dst, const uint8_t *src)
+{
+  assert (!(length % CAST_BLOCK));
+  while (length)
+    {
+      CAST_ecb_encrypt(src, dst, ctx, CAST_ENCRYPT);
+      length -= CAST_BLOCK;
+      dst += CAST_BLOCK;
+      src += CAST_BLOCK;
+    }
+}
+
+static nettle_crypt_func openssl_cast_decrypt;
+static void
+openssl_cast_decrypt(void *ctx, unsigned length,
+                    uint8_t *dst, const uint8_t *src)
+{
+  assert (!(length % CAST_BLOCK));
+  while (length)
+    {
+      CAST_ecb_encrypt(src, dst, ctx, CAST_DECRYPT);
+      length -= CAST_BLOCK;
+      dst += CAST_BLOCK;
+      src += CAST_BLOCK;
+    }
+}
+
+const struct nettle_cipher
+nettle_openssl_cast128 = {
+  "openssl cast128", sizeof(CAST_KEY),
+  8, CAST_KEY_LENGTH,
+  openssl_cast_set_key, openssl_cast_set_key,
+  openssl_cast_encrypt, openssl_cast_decrypt
+};
+
+/* Hash functions */
+
+/* md5 */
+static nettle_hash_init_func openssl_md5_init;
+static void
+openssl_md5_init(void *ctx)
+{
+  MD5_Init(ctx);
+}
+
+static nettle_hash_update_func openssl_md5_update;
+static void
+openssl_md5_update(void *ctx,
+                   unsigned length,
+                   const uint8_t *src)
+{
+  MD5_Update(ctx, src, length);
+}
+
+static nettle_hash_digest_func openssl_md5_digest;
+static void
+openssl_md5_digest(void *ctx,
+                   unsigned length, uint8_t *dst)
+{
+  assert(length == SHA_DIGEST_LENGTH);
+  MD5_Final(dst, ctx);
+  MD5_Init(ctx);
+}
+
+const struct nettle_hash
+nettle_openssl_md5 = {
+  "openssl md5", sizeof(SHA_CTX),
+  SHA_DIGEST_LENGTH, SHA_CBLOCK,
+  openssl_md5_init,
+  openssl_md5_update,
+  openssl_md5_digest
+};
+
+/* sha1 */
+static nettle_hash_init_func openssl_sha1_init;
+static void
+openssl_sha1_init(void *ctx)
+{
+  SHA1_Init(ctx);
+}
+
+static nettle_hash_update_func openssl_sha1_update;
+static void
+openssl_sha1_update(void *ctx,
+                   unsigned length,
+                   const uint8_t *src)
+{
+  SHA1_Update(ctx, src, length);
+}
+
+static nettle_hash_digest_func openssl_sha1_digest;
+static void
+openssl_sha1_digest(void *ctx,
+                   unsigned length, uint8_t *dst)
+{
+  assert(length == SHA_DIGEST_LENGTH);
+  SHA1_Final(dst, ctx);
+  SHA1_Init(ctx);
+}
+
+const struct nettle_hash
+nettle_openssl_sha1 = {
+  "openssl sha1", sizeof(SHA_CTX),
+  SHA_DIGEST_LENGTH, SHA_CBLOCK,
+  openssl_sha1_init,
+  openssl_sha1_update,
+  openssl_sha1_digest
+};
+  
+#endif /* WITH_OPENSSL */
diff --git a/examples/next-prime.c b/examples/next-prime.c
new file mode 100644 (file)
index 0000000..889c84a
--- /dev/null
@@ -0,0 +1,161 @@
+/* next-prime.c
+ *
+ * Command line tool for prime search.
+ *
+ */
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2007 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "bignum.h"
+
+#include "getopt.h"
+
+static void
+usage(void)
+{
+  fprintf(stderr, "Usage: next-prime [OPTIONS] number\n\n"
+         "Options:\n"
+         "      --help         Display this message.\n"
+         "  -v, --verbose      Display timing information.\n"
+         "      --factorial    Use factorial of input number.\n"
+         "  -s  --sieve-limit  Number of primes to use for sieving.\n");
+}
+
+int
+main(int argc, char **argv)
+{
+  mpz_t n;
+  mpz_t p;
+
+  int c;
+  int verbose = 0;  
+  int factorial = 0;
+  int prime_limit = 200;
+
+  clock_t start;
+  clock_t end;
+  
+  enum { OPT_HELP = 300 };
+
+  static const struct option options[] =
+    {
+      /* Name, args, flag, val */
+      { "help", no_argument, NULL, OPT_HELP },
+      { "verbose", no_argument, NULL, 'v' },
+      { "factorial", no_argument, NULL, 'f' },
+      { "sieve-limit", required_argument, NULL, 's' },
+      { NULL, 0, NULL, 0}
+    };
+
+  while ( (c = getopt_long(argc, argv, "vs:", options, NULL)) != -1)
+    switch (c)
+      {
+      case 'v':
+       verbose = 1;
+       break;
+      case OPT_HELP:
+       usage();
+       return EXIT_SUCCESS;
+      case 'f':
+       factorial = 1;
+       break;
+      case 's':
+       prime_limit = atoi(optarg);
+       if (prime_limit < 0)
+         {
+           usage();
+           return EXIT_FAILURE;
+         }
+       break;
+      case '?':
+       return EXIT_FAILURE;
+      default:
+       abort();
+       
+      }
+
+  argc -= optind;
+  argv += optind;
+
+  if (argc != 1)
+    {
+      usage();
+      return EXIT_FAILURE;
+    }
+
+  mpz_init(n);
+
+  if (factorial)
+    {
+      long arg;
+      char *end;
+      arg = strtol(argv[0], &end, 0);
+      if (*end || arg < 0)
+       {
+         fprintf(stderr, "Invalid number.\n");
+         return EXIT_FAILURE;
+       }
+      mpz_fac_ui(n, arg);
+    }
+  else if (mpz_set_str(n, argv[0], 0))
+    {
+      fprintf(stderr, "Invalid number.\n");
+      return EXIT_FAILURE;
+    }
+
+  if (mpz_cmp_ui(n, 2) <= 0)
+    {
+      printf("2\n");
+      return EXIT_SUCCESS;
+    }
+
+  mpz_init(p);
+
+  start = clock();
+  nettle_next_prime(p, n, 25, prime_limit, NULL, NULL);
+  end = clock();
+  
+  mpz_out_str(stdout, 10, p);
+  printf("\n");
+
+  if (verbose)
+    {
+      mpz_t d;
+      
+      mpz_init(d);
+      mpz_sub(d, p, n);
+
+      /* Avoid using gmp_fprintf, to stay compatible with gmp-3.1. */
+      fprintf(stderr, "bit size: %lu, diff: ", (unsigned long) mpz_sizeinbase(p, 2));
+      mpz_out_str(stderr, 10, d);
+      fprintf(stderr, ", total time: %.3g s\n",
+             (double)(end - start) / CLOCKS_PER_SEC);
+    }
+  return EXIT_SUCCESS;
+}
diff --git a/examples/random-prime.c b/examples/random-prime.c
new file mode 100644 (file)
index 0000000..a87a541
--- /dev/null
@@ -0,0 +1,146 @@
+/* random-prime.c
+ *
+ * Command line tool for prime generation.
+ *
+ */
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "bignum.h"
+#include "yarrow.h"
+
+#include "io.h"
+
+#include "getopt.h"
+
+static void
+usage(void)
+{
+  fprintf(stderr, "Usage: random-prime [OPTIONS] bits\n\n"
+         "Options:\n"
+         "      --help         Display this message.\n"
+         "  -v, --verbose      Display timing information.\n"
+         "  -r, --random FILE  Random data to use for seeding.\n");
+}
+
+int
+main(int argc, char **argv)
+{
+  long bits;
+  mpz_t p;
+  struct yarrow256_ctx yarrow;
+
+  int verbose = 0;  
+  const char *random_file = NULL;
+
+  int c;
+  char *arg_end;
+
+  clock_t start;
+  clock_t end;
+  
+  enum { OPT_HELP = 300 };
+  static const struct option options[] =
+    {
+      /* Name, args, flag, val */
+      { "help", no_argument, NULL, OPT_HELP },
+      { "verbose", no_argument, NULL, 'v' },
+      { "random", required_argument, NULL, 'r' },
+      { NULL, 0, NULL, 0}
+    };
+
+  while ( (c = getopt_long(argc, argv, "vr:", options, NULL)) != -1)
+    switch (c)
+      {
+      case 'v':
+       verbose = 1;
+       break;
+      case 'r':
+       random_file = optarg;
+       break;
+      case OPT_HELP:
+       usage();
+       return EXIT_SUCCESS;
+      case '?':
+       return EXIT_FAILURE;
+      default:
+       abort();
+      }
+
+  argc -= optind;
+  argv += optind;
+
+  if (argc != 1)
+    {
+      usage();
+      return EXIT_FAILURE;
+    }
+
+  bits = strtol(argv[0], &arg_end, 0);
+  if (*arg_end || bits < 0)
+    {
+      fprintf(stderr, "Invalid number.\n");
+      return EXIT_FAILURE;
+    }
+
+  if (bits < 3)
+    {
+      fprintf(stderr, "Bitsize must be at least 3.\n");
+      return EXIT_FAILURE;
+    }
+
+  /* NOTE: No sources */
+  yarrow256_init(&yarrow, 0, NULL);
+
+  /* Read some data to seed the generator */
+  if (!simple_random(&yarrow, random_file))
+    {
+      werror("Initialization of randomness generator failed.\n");
+      return EXIT_FAILURE;
+    }
+  
+  mpz_init(p);
+
+  start = clock();
+
+  nettle_random_prime(p, bits, 0,
+                     &yarrow, (nettle_random_func *) yarrow256_random,
+                     NULL, NULL);
+
+  end = clock();
+
+  mpz_out_str(stdout, 10, p);
+  printf("\n");
+
+  if (verbose)
+    fprintf(stderr, "time: %.3g s\n",
+           (double)(end - start) / CLOCKS_PER_SEC);
+
+  return EXIT_SUCCESS;
+}
diff --git a/examples/read_rsa_key.c b/examples/read_rsa_key.c
new file mode 100644 (file)
index 0000000..1d092e7
--- /dev/null
@@ -0,0 +1,50 @@
+/* Used by the rsa example programs. */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002, 2007 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+
+#include "io.h"
+#include "rsa.h"
+
+/* Split out from io.c, since it depends on hogweed. */
+int
+read_rsa_key(const char *name,
+            struct rsa_public_key *pub,
+            struct rsa_private_key *priv)
+{
+  unsigned length;
+  char *buffer;
+  int res;
+  
+  length = read_file(name, 0, &buffer);
+  if (!length)
+    return 0;
+
+  res = rsa_keypair_from_sexp(pub, priv, 0, length, buffer);
+  free(buffer);
+
+  return res;
+}
diff --git a/examples/rsa-decrypt.c b/examples/rsa-decrypt.c
new file mode 100644 (file)
index 0000000..5e0ee79
--- /dev/null
@@ -0,0 +1,243 @@
+/* rsa-decrypt.c
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/* string.h must be included before gmp.h */
+#include "aes.h"
+#include "bignum.h"
+#include "buffer.h"
+#include "cbc.h"
+#include "hmac.h"
+#include "macros.h"
+#include "rsa.h"
+#include "yarrow.h"
+
+#include "io.h"
+#include "rsa-session.h"
+
+void
+rsa_session_set_decrypt_key(struct rsa_session *ctx,
+                           const struct rsa_session_info *key)
+{
+  const uint8_t *aes_key = SESSION_AES_KEY(key);
+  const uint8_t *iv = SESSION_IV(key);
+  const uint8_t *hmac_key = SESSION_HMAC_KEY(key);
+  
+  aes_set_decrypt_key(&ctx->aes.ctx, AES_KEY_SIZE, aes_key);
+  CBC_SET_IV(&ctx->aes, iv);
+  hmac_sha1_set_key(&ctx->hmac, SHA1_DIGEST_SIZE, hmac_key);
+}
+
+static int
+read_uint32(FILE *f, uint32_t *n)
+{
+  uint8_t buf[4];
+  if (fread(buf, 1, sizeof(buf), f) != sizeof(buf))
+    return 0;
+
+  *n = READ_UINT32(buf);
+  return 1;
+}
+
+static int
+read_version(FILE *f)
+{
+  uint32_t version;
+  return read_uint32(f, &version) && version == RSA_VERSION;
+}
+
+static int
+read_bignum(FILE *f, mpz_t x)
+{
+  uint32_t size;
+  if (read_uint32(f, &size)
+      && size < 1000)
+    {
+      uint8_t *p = xalloc(size);
+      if (fread(p, 1, size, f) != size)
+       {
+         free(p);
+         return 0;
+       }
+
+      nettle_mpz_set_str_256_u(x, size, p);
+      free(p);
+
+      return 1;
+    }
+  return 0;
+}
+
+struct process_ctx
+{
+  struct CBC_CTX(struct aes_ctx, AES_BLOCK_SIZE) aes;
+  struct hmac_sha1_ctx hmac;
+  struct yarrow256_ctx yarrow;
+};
+
+#define BUF_SIZE (100 * AES_BLOCK_SIZE)
+
+/* Trailing data that needs special processing */
+#define BUF_FINAL (AES_BLOCK_SIZE + SHA1_DIGEST_SIZE)
+
+static int
+process_file(struct rsa_session *ctx,
+            FILE *in, FILE *out)
+{
+  uint8_t buffer[BUF_SIZE + BUF_FINAL];
+  uint8_t digest[SHA1_DIGEST_SIZE];
+  size_t size;
+  unsigned padding;
+
+  size = fread(buffer, 1, BUF_FINAL, in);
+  if (size < BUF_FINAL || ferror(in))
+    {
+      werror("Reading input failed: %s\n", strerror(errno));
+      return 0;
+    }
+
+  do
+    {
+      size = fread(buffer + BUF_FINAL, 1, BUF_SIZE, in);
+
+      if (ferror(in))
+       {
+         werror("Reading input failed: %s\n", strerror(errno));
+         return 0;
+       }
+
+      if (size % AES_BLOCK_SIZE != 0)
+       {
+         werror("Unexpected EOF on input.\n");
+         return 0;
+       }
+
+      if (size)
+       {
+         CBC_DECRYPT(&ctx->aes, aes_decrypt, size, buffer, buffer);
+         hmac_sha1_update(&ctx->hmac, size, buffer);
+         if (!write_string(out, size, buffer))
+           {
+             werror("Writing output failed: %s\n", strerror(errno));
+             return 0;
+           }
+         memmove(buffer, buffer + size, BUF_FINAL);
+       }
+    }
+  while (size == BUF_SIZE);
+
+  /* Decrypt final block */
+  CBC_DECRYPT(&ctx->aes, aes_decrypt, AES_BLOCK_SIZE, buffer, buffer);
+  padding = buffer[AES_BLOCK_SIZE - 1];
+  if (padding > AES_BLOCK_SIZE)
+    {
+      werror("Decryption failed: Invalid padding.\n");
+      return 0;
+    }
+
+  if (padding < AES_BLOCK_SIZE)
+    {
+      unsigned leftover = AES_BLOCK_SIZE - padding;
+      hmac_sha1_update(&ctx->hmac, leftover, buffer);
+      if (!write_string(out, leftover, buffer))
+       {
+         werror("Writing output failed: %s\n", strerror(errno));
+         return 0;
+       }
+    }
+  hmac_sha1_digest(&ctx->hmac, SHA1_DIGEST_SIZE, digest);
+  if (memcmp(digest, buffer + AES_BLOCK_SIZE, SHA1_DIGEST_SIZE) != 0)
+    {
+      werror("Decryption failed: Invalid mac.\n");
+      return 0;
+    }
+  
+  return 1;
+}
+
+int
+main(int argc, char **argv)
+{
+  struct rsa_private_key key;
+  struct rsa_session ctx;
+  struct rsa_session_info session;
+
+  unsigned length;
+  mpz_t x;
+
+  mpz_init(x);
+  
+  if (argc != 2)
+    {
+      werror("Usage: rsa-decrypt PRIVATE-KEY < ciphertext\n");
+      return EXIT_FAILURE;
+    }
+
+  rsa_private_key_init(&key);
+  
+  if (!read_rsa_key(argv[1], NULL, &key))
+    {
+      werror("Invalid key\n");
+      return EXIT_FAILURE;
+    }
+
+  if (!read_version(stdin))
+    {
+      werror("Bad version number in input file.\n");
+      return EXIT_FAILURE;
+    }
+
+  if (!read_bignum(stdin, x))
+    {
+      werror("Bad rsa header in input file.\n");
+      return EXIT_FAILURE;
+    }
+
+  length = sizeof(session.key);
+  if (!rsa_decrypt(&key, &length, session.key, x) || length != sizeof(session.key))
+    {
+      werror("Failed to decrypt rsa header in input file.\n");
+      return EXIT_FAILURE;      
+    }
+  mpz_clear(x);
+  
+  rsa_session_set_decrypt_key(&ctx, &session);
+
+  if (!process_file(&ctx,
+                   stdin, stdout))
+    return EXIT_FAILURE;
+  
+  rsa_private_key_clear(&key);
+
+  return EXIT_SUCCESS;
+}
diff --git a/examples/rsa-encrypt-test b/examples/rsa-encrypt-test
new file mode 100755 (executable)
index 0000000..08b7a44
--- /dev/null
@@ -0,0 +1,27 @@
+#! /bin/sh
+
+if [ -z "$srcdir" ] ; then
+  srcdir=`pwd`
+fi
+
+data="$srcdir/nettle-benchmark.c"
+
+if [ -x rsa-encrypt ] ; then
+  if ./rsa-encrypt -r rsa-decrypt testkey.pub < "$data" > testciphertext ; then
+    :
+  else
+    exit 1
+  fi
+  if ./rsa-decrypt testkey < testciphertext > testcleartext ; then
+    :
+  else
+    exit 1
+  fi
+  if cmp "$data" testcleartext ; then
+    exit 0
+  else
+    exit 1
+  fi
+else
+  exit 77
+fi
diff --git a/examples/rsa-encrypt.c b/examples/rsa-encrypt.c
new file mode 100644 (file)
index 0000000..2bb556a
--- /dev/null
@@ -0,0 +1,237 @@
+/* rsa-encrypt.c
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+   
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/* string.h must be included before gmp.h */
+#include "bignum.h"
+#include "buffer.h"
+#include "macros.h"
+#include "rsa.h"
+#include "yarrow.h"
+
+#include "io.h"
+#include "rsa-session.h"
+
+#include "getopt.h"
+
+void
+rsa_session_set_encrypt_key(struct rsa_session *ctx,
+                           const struct rsa_session_info *key)
+{
+  const uint8_t *aes_key = SESSION_AES_KEY(key);
+  const uint8_t *iv = SESSION_IV(key);
+  const uint8_t *hmac_key = SESSION_HMAC_KEY(key);
+  
+  aes_set_encrypt_key(&ctx->aes.ctx, AES_KEY_SIZE, aes_key);
+  CBC_SET_IV(&ctx->aes, iv);
+  hmac_sha1_set_key(&ctx->hmac, SHA1_DIGEST_SIZE, hmac_key);
+}
+
+static int
+write_uint32(FILE *f, uint32_t n)
+{
+  uint8_t buffer[4];
+  WRITE_UINT32(buffer, n);
+
+  return write_string(f, sizeof(buffer), buffer);
+}
+
+static int
+write_version(FILE *f)
+{
+  return write_uint32(f, 1);
+}
+
+static int
+write_bignum(FILE *f, mpz_t x)
+{
+  unsigned size = nettle_mpz_sizeinbase_256_u(x);
+  uint8_t *p;
+  int res;
+  
+  if (!write_uint32(f, size))
+    return 0;
+  
+  p = xalloc(size);
+  nettle_mpz_get_str_256(size, p, x);
+
+  res = write_string(f, size, p);
+  free(p);
+  return res;
+}
+
+static int
+process_file(struct rsa_session *ctx,
+            FILE *in, FILE *out)
+{
+  uint8_t buffer[AES_BLOCK_SIZE * 100];
+  unsigned leftover;
+  unsigned padding;
+
+  padding = leftover = 0;
+
+  for (;;)
+    {
+      size_t size = fread(buffer, 1, sizeof(buffer), in);
+      if (ferror(in))
+       {
+         werror("Reading input failed: %s\n", strerror(errno));
+         return 0;
+       }
+
+      hmac_sha1_update(&ctx->hmac, size, buffer);
+      if (size < sizeof(buffer))
+       {
+         /* Setting padding != ends the loop */
+         leftover = size % AES_BLOCK_SIZE;
+         padding = AES_BLOCK_SIZE - leftover;
+         size -= leftover;
+
+         if (!size)
+           break;
+       }
+
+      CBC_ENCRYPT(&ctx->aes, aes_encrypt, size, buffer, buffer);
+      if (!write_string(out, size, buffer))
+       {
+         werror("Writing output failed: %s\n", strerror(errno));
+         return 0;
+       }
+
+      if (padding)
+       {
+         if (leftover)
+           memcpy(buffer, buffer + size, leftover);
+
+         break;
+       }
+    }
+  if (padding > 1)
+    yarrow256_random(&ctx->yarrow, padding - 1, buffer + leftover);
+
+  buffer[AES_BLOCK_SIZE - 1] = padding;
+  CBC_ENCRYPT(&ctx->aes, aes_encrypt, AES_BLOCK_SIZE, buffer, buffer);
+  hmac_sha1_digest(&ctx->hmac, SHA1_DIGEST_SIZE, buffer + AES_BLOCK_SIZE);
+
+  if (!write_string(out, AES_BLOCK_SIZE + SHA1_DIGEST_SIZE, buffer))
+    {
+      werror("Writing output failed: %s\n", strerror(errno));
+      return 0;
+    }
+
+  return 1;
+}
+
+int
+main(int argc, char **argv)
+{
+  struct rsa_session ctx;
+  struct rsa_session_info info;
+  
+  struct rsa_public_key key;
+  mpz_t x;
+  
+  int c;
+  const char *random_name = NULL;
+
+  /* FIXME: --help option. */
+  while ( (c = getopt(argc, argv, "o:r:")) != -1)
+    switch (c)
+      {
+      case 'r':
+       random_name = optarg;
+       break;
+       
+      case '?':
+       return EXIT_FAILURE;
+
+      default:
+       abort();
+      }
+
+  argv += optind;
+  argc -= optind;
+
+  if (argc != 1)
+    {
+      werror("Usage: rsa-encrypt [-r random-file] PUBLIC-KEY < cleartext\n");
+      return EXIT_FAILURE;
+    }
+
+  rsa_public_key_init(&key);
+  
+  if (!read_rsa_key(argv[0], &key, NULL))
+    {
+      werror("Invalid key\n");
+      return EXIT_FAILURE;
+    }
+
+  /* NOTE: No sources */
+  yarrow256_init(&ctx.yarrow, 0, NULL);
+  
+  /* Read some data to seed the generator */
+  if (!simple_random(&ctx.yarrow, random_name))
+    {
+      werror("Initialization of randomness generator failed.\n");
+      return EXIT_FAILURE;
+    }
+
+  WRITE_UINT32(SESSION_VERSION(&info), RSA_VERSION);
+  
+  yarrow256_random(&ctx.yarrow, sizeof(info.key) - 4, info.key + 4);
+
+  rsa_session_set_encrypt_key(&ctx, &info);
+  
+  write_version(stdout);
+  
+  mpz_init(x);
+
+  if (!rsa_encrypt(&key,
+                  &ctx.yarrow, (nettle_random_func *) yarrow256_random,
+                  sizeof(info.key), info.key, 
+                  x))
+    {
+      werror("RSA encryption failed.\n");
+      return EXIT_FAILURE;
+    }
+
+  write_bignum(stdout, x);
+  
+  if (!process_file(&ctx,
+                   stdin, stdout))
+    return EXIT_FAILURE;
+  
+  rsa_public_key_clear(&key);
+
+  return EXIT_SUCCESS;
+}
diff --git a/examples/rsa-keygen.c b/examples/rsa-keygen.c
new file mode 100644 (file)
index 0000000..e2b2f56
--- /dev/null
@@ -0,0 +1,164 @@
+/* rsa-keygen.c
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "buffer.h"
+#include "rsa.h"
+#include "sexp.h"
+#include "yarrow.h"
+
+#include "io.h"
+
+#include "getopt.h"
+
+#define KEYSIZE 900
+#define ESIZE 30
+
+static void
+progress(void *ctx, int c)
+{
+  (void) ctx;
+  fputc(c, stderr);
+}
+
+int
+main(int argc, char **argv)
+{
+  struct yarrow256_ctx yarrow;
+  struct rsa_public_key pub;
+  struct rsa_private_key priv;
+
+  int c;
+  char *pub_name = NULL;
+  const char *priv_name = NULL;
+  const char *random_name = NULL;
+  
+  struct nettle_buffer pub_buffer;
+  struct nettle_buffer priv_buffer;
+
+  enum { OPT_HELP = 300 };
+  static const struct option options[] =
+    {
+      /* Name, args, flag, val */
+      { "help", no_argument, NULL, OPT_HELP },
+      { "random", required_argument, NULL, 'r' },
+      { NULL, 0, NULL, 0}
+    };
+  
+  while ( (c = getopt_long(argc, argv, "o:r:", options, NULL)) != -1)
+    switch (c)
+      {
+      case 'o':
+       priv_name = optarg;
+       break;
+
+      case 'r':
+       random_name = optarg;
+       break;
+
+      case OPT_HELP:
+       printf("FIXME: Usage information.\n");
+       return EXIT_SUCCESS;
+
+      case '?':
+       return EXIT_FAILURE;
+
+      default:
+       abort();
+      }
+
+  if (!priv_name)
+    {
+      werror("No filename provided.\n");
+      return EXIT_FAILURE;
+    }
+
+  pub_name = xalloc(strlen(priv_name) + 5);  
+  sprintf(pub_name, "%s.pub", priv_name);
+
+  /* NOTE: No sources */
+  yarrow256_init(&yarrow, 0, NULL);
+
+  /* Read some data to seed the generator */
+  if (!simple_random(&yarrow, random_name))
+    {
+      werror("Initialization of randomness generator failed.\n");
+      return EXIT_FAILURE;
+    }
+
+  rsa_public_key_init(&pub);
+  rsa_private_key_init(&priv);
+
+  if (!rsa_generate_keypair
+      (&pub, &priv,
+       (void *) &yarrow, (nettle_random_func *) yarrow256_random,
+       NULL, progress,
+       KEYSIZE, ESIZE))
+    {
+      werror("Key generation failed.\n");
+      return EXIT_FAILURE;
+    }
+
+  nettle_buffer_init(&priv_buffer);
+  nettle_buffer_init(&pub_buffer);
+  
+  if (!rsa_keypair_to_sexp(&pub_buffer, "rsa-pkcs1-sha1", &pub, NULL))
+    {
+      werror("Formatting public key failed.\n");
+      return EXIT_FAILURE;
+    }
+
+  if (!rsa_keypair_to_sexp(&priv_buffer, "rsa-pkcs1-sha1", &pub, &priv))
+    {
+      werror("Formatting private key failed.\n");
+      return EXIT_FAILURE;
+    }
+  
+  if (!write_file(pub_name, pub_buffer.size, pub_buffer.contents))
+    {
+      werror("Failed to write public key: %s\n",
+             strerror(errno));
+      return EXIT_FAILURE;
+    }
+
+  /* NOTE: This doesn't set up paranoid access restrictions on the
+   * private key file, like a serious key generation tool would do. */
+  if (!write_file(priv_name, priv_buffer.size, priv_buffer.contents))
+    {
+      werror("Failed to write private key: %s\n",
+             strerror(errno));
+      return EXIT_FAILURE;
+    }
+
+  return EXIT_SUCCESS;
+}
diff --git a/examples/rsa-session.h b/examples/rsa-session.h
new file mode 100644 (file)
index 0000000..44b85ec
--- /dev/null
@@ -0,0 +1,66 @@
+/* Session key definitions for the rsa-encrypt and rsa-decrypt programs.
+ */
+
+#ifndef NETTLE_EXAMPLES_RSA_SESSION_H_INCLUDED
+#define NETTLE_EXAMPLES_RSA_SESSION_H_INCLUDED
+
+#include "aes.h"
+#include "cbc.h"
+#include "hmac.h"
+
+#define RSA_VERSION 1
+
+/* Encryption program using the following file format:
+
+     uint32_t version = 1;
+     uint32_t nsize;
+     uint8_t x[nsize];
+     uint8_t encrypted[n];
+     uint8_t hmac[SHA1_DIGEST_SIZE];
+
+   where x is the data
+
+     uint32_t version = 1;
+     uint8_t aes_key[AES_KEY_SIZE];
+     uint8_t iv[AES_BLOCK_SIZE];
+     uint8_t hmac_key[SHA1_DIGEST_SIZE];
+
+   of size (4 + AES_KEY_SIZE + AES_BLOCK_SIZE + SHA1_DIGEST_SIZE) = 72
+   bytes, encrypted using rsa-pkcs1.
+
+   The cleartext input is encrypted using aes-cbc. The final block is
+   padded as
+
+     | data | random octets | padding length |
+
+   where the last octet is the padding length, a number between 1 and
+   AES_BLOCK_SIZE (inclusive).
+*/
+
+struct rsa_session
+{
+  struct CBC_CTX(struct aes_ctx, AES_BLOCK_SIZE) aes;
+  struct hmac_sha1_ctx hmac;
+  struct yarrow256_ctx yarrow;
+};
+
+struct rsa_session_info
+{
+  /* Version followed by aes key, iv and mac key */
+  uint8_t key[4 + AES_KEY_SIZE + AES_BLOCK_SIZE + SHA1_DIGEST_SIZE];
+};
+
+#define SESSION_VERSION(s) ((s)->key)
+#define SESSION_AES_KEY(s) ((s)->key + 4)
+#define SESSION_IV(s) ((s)->key + 4 + AES_KEY_SIZE)
+#define SESSION_HMAC_KEY(s) ((s)->key + 4 + AES_KEY_SIZE + AES_BLOCK_SIZE)
+
+void
+rsa_session_set_encrypt_key(struct rsa_session *ctx,
+                           const struct rsa_session_info *key);
+
+void
+rsa_session_set_decrypt_key(struct rsa_session *ctx,
+                           const struct rsa_session_info *key);
+
+#endif /* NETTLE_EXAMPLES_RSA_SESSION_H_INCLUDED */
diff --git a/examples/rsa-sign-test b/examples/rsa-sign-test
new file mode 100755 (executable)
index 0000000..1621226
--- /dev/null
@@ -0,0 +1,17 @@
+#! /bin/sh
+
+if [ -z "$srcdir" ] ; then
+  srcdir=`pwd`
+fi
+
+data="$srcdir/nettle-benchmark.c"
+
+if [ -x rsa-sign ] ; then
+  if ./rsa-sign testkey < "$data" > testsignature ; then
+    exit 0;
+  else
+    exit 1
+  fi
+else
+  exit 77
+fi
diff --git a/examples/rsa-sign.c b/examples/rsa-sign.c
new file mode 100644 (file)
index 0000000..c480761
--- /dev/null
@@ -0,0 +1,87 @@
+/* rsa-sign.c
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/* string.h must be included before gmp.h */
+#include "rsa.h"
+#include "io.h"
+
+int
+main(int argc, char **argv)
+{
+  struct rsa_private_key key;
+  struct sha1_ctx hash;
+  mpz_t s;
+  
+  if (argc != 2)
+    {
+      werror("Usage: rsa-sign PRIVATE-KEY < file\n");
+      return EXIT_FAILURE;
+    }
+
+  rsa_private_key_init(&key);
+  
+  if (!read_rsa_key(argv[1], NULL, &key))
+    {
+      werror("Invalid key\n");
+      return EXIT_FAILURE;
+    }
+
+  sha1_init(&hash);
+  if (!hash_file(&nettle_sha1, &hash, stdin))
+    {
+      werror("Failed reading stdin: %s\n",
+             strerror(errno));
+      return 0;
+    }
+
+  mpz_init(s);
+  if (!rsa_sha1_sign(&key, &hash, s))
+    {
+      werror("RSA key too small\n");
+      return 0;
+    }
+
+  if (!mpz_out_str(stdout, 16, s))
+    {
+      werror("Failed writing signature: %s\n",
+             strerror(errno));
+      return 0;
+    }
+
+  putchar('\n');
+  
+  mpz_clear(s);
+  rsa_private_key_clear(&key);
+
+  return EXIT_SUCCESS;
+}
diff --git a/examples/rsa-verify-test b/examples/rsa-verify-test
new file mode 100755 (executable)
index 0000000..765b61f
--- /dev/null
@@ -0,0 +1,29 @@
+#! /bin/sh
+
+if [ -z "$srcdir" ] ; then
+  srcdir=`pwd`
+fi
+
+data="$srcdir/nettle-benchmark.c"
+
+if [ -x rsa-verify ] ; then
+  ./rsa-sign testkey < "$data" > testsignature \
+    && ./rsa-verify testkey.pub testsignature < "$data" \
+    || exit 1;
+  
+  # Try modifying the data
+  sed s/128/129/ < "$data" >testdata
+
+  if ./rsa-verify testkey.pub testsignature < testdata 2>/dev/null; then
+    exit 1
+  fi
+  
+  # Try modifying the signature
+  sed s/1/2/ <testsignature > testsignature2
+  if ./rsa-verify testkey.pub testsignature2 < "$data" 2>/dev/null; then
+    exit 1;
+  fi
+  exit 0
+else
+  exit 77
+fi
diff --git a/examples/rsa-verify.c b/examples/rsa-verify.c
new file mode 100644 (file)
index 0000000..8781812
--- /dev/null
@@ -0,0 +1,102 @@
+/* rsa-verify.c
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "rsa.h"
+#include "io.h"
+
+static int
+read_signature(const char *name, mpz_t s)
+{
+  char *buffer;
+  unsigned length;
+  int res;
+  
+  length = read_file(name, 0, &buffer);
+  if (!length)
+    return 0;
+
+  res = (mpz_set_str(s, buffer, 16) == 0);
+  free(buffer);
+
+  return res;
+}
+
+int
+main(int argc, char **argv)
+{
+  struct rsa_public_key key;
+  struct sha1_ctx hash;
+  mpz_t s;
+  
+  if (argc != 3)
+    {
+      werror("Usage: rsa-verify PUBLIC-KEY SIGNATURE-FILE < FILE\n");
+      return EXIT_FAILURE;
+    }
+
+  rsa_public_key_init(&key);
+  
+  if (!read_rsa_key(argv[1], &key, NULL))
+    {
+      werror("Invalid key\n");
+      return EXIT_FAILURE;
+    }
+
+  mpz_init(s);
+
+  if (!read_signature(argv[2], s))
+    {
+      werror("Failed to read signature file `%s'\n",
+             argv[2]);
+      return EXIT_FAILURE;
+    }
+  
+  sha1_init(&hash);
+  if (!hash_file(&nettle_sha1, &hash, stdin))
+    {
+      werror("Failed reading stdin: %s\n",
+             strerror(errno));
+      return 0;
+    }
+
+  if (!rsa_sha1_verify(&key, &hash, s))
+    {
+      werror("Invalid signature!\n");
+      return EXIT_FAILURE;
+    }
+    
+  mpz_clear(s);
+  rsa_public_key_clear(&key);
+
+  return EXIT_SUCCESS;
+}
diff --git a/examples/run-tests b/examples/run-tests
new file mode 100755 (executable)
index 0000000..f240599
--- /dev/null
@@ -0,0 +1,104 @@
+#! /bin/sh
+
+failed=0
+all=0
+
+debug='no'
+testflags=''
+
+if [ -z "$srcdir" ] ; then
+  srcdir=`pwd`
+fi
+
+export srcdir
+
+# When used in make rules, we sometimes get the filenames VPATH
+# expanded, but usually not. 
+find_program () {
+    case "$1" in
+       */*)
+         echo "$1"
+         ;;
+       *)
+         if [ -x "$1" ] ; then
+             echo "./$1"
+         else
+             echo "$srcdir/$1"
+         fi
+         ;;
+    esac
+}
+
+env_program () {
+  if [ -x "$1" ] ; then
+    if "$1"; then : ; else
+      echo FAIL: $1
+      exit 1
+    fi
+  fi
+}
+
+test_program () {
+  testname=`basename "$1" .exe`
+  testname=`basename "$testname" -test`
+  "$1" $testflags
+  case "$?" in
+      0)
+       echo PASS: $testname
+       all=`expr $all + 1`
+       ;;
+      77)
+       echo SKIP: $testname
+      ;;
+      *)
+       echo FAIL: $testname
+       failed=`expr $failed + 1`
+       all=`expr $all + 1`
+       ;;
+  esac
+}
+
+env_program `find_program setup-env`
+
+while test $# != 0
+do
+  case "$1" in
+  --debug)
+    debug=yes
+    ;;
+  -v)
+    testflags='-v'
+    ;;
+  -*)
+    echo >&2 'Unknown option `'"$1'" 
+    exit 1
+    ;;
+  *)
+    break
+    ;;
+  esac
+  shift
+done
+  
+if [ $# -eq 0 ] ; then
+  for f in *-test; do test_program "./$f"; done
+else
+  for f in "$@" ; do test_program `find_program "$f"`; done
+fi
+
+if [ $failed -eq 0 ] ; then
+  banner="All $all tests passed"
+else
+  banner="$failed of $all tests failed"
+fi
+dashes=`echo "$banner" | sed s/./=/g`
+echo "$dashes"
+echo "$banner"
+echo "$dashes"
+
+if [ "x$debug" = xno ] ; then
+  env_program `find_program teardown-env`
+fi
+
+[ "$failed" -eq 0 ]
+
diff --git a/examples/setup-env b/examples/setup-env
new file mode 100755 (executable)
index 0000000..7588d6f
--- /dev/null
@@ -0,0 +1,7 @@
+#! /bin/sh
+
+set -e
+
+if [ -x rsa-keygen ] ; then
+  ./rsa-keygen -r rsa-decrypt -o testkey || exit 1
+fi
diff --git a/examples/teardown-env b/examples/teardown-env
new file mode 100755 (executable)
index 0000000..ce1a157
--- /dev/null
@@ -0,0 +1,6 @@
+#! /bin/sh
+
+rm -rf testkey testkey.pub testsignature testsignature2 testdata \
+    testciphertext testcleartext
+
+
diff --git a/gcm-aes.c b/gcm-aes.c
new file mode 100644 (file)
index 0000000..ada5dfc
--- /dev/null
+++ b/gcm-aes.c
@@ -0,0 +1,71 @@
+/* gcm_aes.c
+ *
+ * Galois counter mode using AES as the underlying cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2011 Niels Möller
+ *
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "gcm.h"
+
+void
+gcm_aes_set_key(struct gcm_aes_ctx *ctx, unsigned length, const uint8_t *key)
+{
+  GCM_SET_KEY(ctx, aes_set_encrypt_key, aes_encrypt, length, key);
+}
+
+void
+gcm_aes_set_iv(struct gcm_aes_ctx *ctx,
+              unsigned length, const uint8_t *iv)
+{
+  GCM_SET_IV(ctx, length, iv);
+}
+
+void
+gcm_aes_update(struct gcm_aes_ctx *ctx, unsigned length, const uint8_t *data)
+{
+  GCM_UPDATE(ctx, length, data);
+}
+
+void
+gcm_aes_encrypt(struct gcm_aes_ctx *ctx,
+               unsigned length, uint8_t *dst, const uint8_t *src)
+{
+  GCM_ENCRYPT(ctx, aes_encrypt, length, dst, src);
+}
+
+void
+gcm_aes_decrypt(struct gcm_aes_ctx *ctx,
+               unsigned length, uint8_t *dst, const uint8_t *src)
+{
+  GCM_DECRYPT(ctx, aes_encrypt, length, dst, src);
+}
+
+void
+gcm_aes_digest(struct gcm_aes_ctx *ctx,
+              unsigned length, uint8_t *digest)
+{
+  GCM_DIGEST(ctx, aes_encrypt, length, digest);
+  
+}
diff --git a/gcm.c b/gcm.c
new file mode 100644 (file)
index 0000000..7b2e605
--- /dev/null
+++ b/gcm.c
@@ -0,0 +1,503 @@
+/* gcm.h
+ *
+ * Galois counter mode, specified by NIST,
+ * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
+ *
+ * See also the gcm paper at
+ * http://www.cryptobarn.com/papers/gcm-spec.pdf.
+ */
+
+/* NOTE: Tentative interface, subject to change. No effort will be
+   made to avoid incompatible changes. */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2011 Niels Möller
+ * Copyright (C) 2011 Katholieke Universiteit Leuven
+ * 
+ * Contributed by Nikos Mavrogiannopoulos
+ *
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gcm.h"
+
+#include "memxor.h"
+#include "nettle-internal.h"
+#include "macros.h"
+
+#define GHASH_POLYNOMIAL 0xE1UL
+
+static void
+gcm_gf_add (union gcm_block *r, const union gcm_block *x, const union gcm_block *y)
+{
+  r->w[0] = x->w[0] ^ y->w[0];
+  r->w[1] = x->w[1] ^ y->w[1];
+#if SIZEOF_LONG == 4
+  r->w[2] = x->w[2] ^ y->w[2];
+  r->w[3] = x->w[3] ^ y->w[3];
+#endif      
+}
+/* Multiplication by 010...0; a big-endian shift right. If the bit
+   shifted out is one, the defining polynomial is added to cancel it
+   out. r == x is allowed. */
+static void
+gcm_gf_shift (union gcm_block *r, const union gcm_block *x)
+{
+  long mask;
+
+  /* Shift uses big-endian representation. */
+#if WORDS_BIGENDIAN
+# if SIZEOF_LONG == 4
+  mask = - (x->w[3] & 1);
+  r->w[3] = (x->w[3] >> 1) | ((x->w[2] & 1) << 31);
+  r->w[2] = (x->w[2] >> 1) | ((x->w[1] & 1) << 31);
+  r->w[1] = (x->w[1] >> 1) | ((x->w[0] & 1) << 31);
+  r->w[0] = (x->w[0] >> 1) ^ (mask & (GHASH_POLYNOMIAL << 24)); 
+# elif SIZEOF_LONG == 8
+  mask = - (x->w[1] & 1);
+  r->w[1] = (x->w[1] >> 1) | ((x->w[0] & 1) << 63);
+  r->w[0] = (x->w[0] >> 1) ^ (mask & (GHASH_POLYNOMIAL << 56));
+# else
+#  error Unsupported word size. */
+#endif
+#else /* ! WORDS_BIGENDIAN */
+# if SIZEOF_LONG == 4
+#define RSHIFT_WORD(x) \
+  ((((x) & 0xfefefefeUL) >> 1) \
+   | (((x) & 0x00010101) << 15))
+  mask = - ((x->w[3] >> 24) & 1);
+  r->w[3] = RSHIFT_WORD(x->w[3]) | ((x->w[2] >> 17) & 0x80);
+  r->w[2] = RSHIFT_WORD(x->w[2]) | ((x->w[1] >> 17) & 0x80);
+  r->w[1] = RSHIFT_WORD(x->w[1]) | ((x->w[0] >> 17) & 0x80);
+  r->w[0] = RSHIFT_WORD(x->w[0]) ^ (mask & GHASH_POLYNOMIAL);
+# elif SIZEOF_LONG == 8
+#define RSHIFT_WORD(x) \
+  ((((x) & 0xfefefefefefefefeUL) >> 1) \
+   | (((x) & 0x0001010101010101UL) << 15))
+  mask = - ((x->w[1] >> 56) & 1);
+  r->w[1] = RSHIFT_WORD(x->w[1]) | ((x->w[0] >> 49) & 0x80);
+  r->w[0] = RSHIFT_WORD(x->w[0]) ^ (mask & GHASH_POLYNOMIAL);
+# else
+#  error Unsupported word size. */
+# endif
+# undef RSHIFT_WORD
+#endif /* ! WORDS_BIGENDIAN */
+}
+
+#if GCM_TABLE_BITS == 0
+/* Sets x <- x * y mod r, using the plain bitwise algorithm from the
+   specification. y may be shorter than a full block, missing bytes
+   are assumed zero. */
+static void
+gcm_gf_mul (union gcm_block *x, const union gcm_block *y)
+{
+  union gcm_block V;
+  union gcm_block Z;
+  unsigned i;
+
+  memcpy(V.b, x, sizeof(V));
+  memset(Z.b, 0, sizeof(Z));
+
+  for (i = 0; i < GCM_BLOCK_SIZE; i++)
+    {
+      uint8_t b = y->b[i];
+      unsigned j;
+      for (j = 0; j < 8; j++, b <<= 1)
+       {
+         if (b & 0x80)
+           gcm_gf_add(&Z, &Z, &V);
+         
+         gcm_gf_shift(&V, &V);
+       }
+    }
+  memcpy (x->b, Z.b, sizeof(Z));
+}
+#else /* GCM_TABLE_BITS != 0 */
+
+# if WORDS_BIGENDIAN
+#  define W(left,right) (0x##left##right)
+# else
+#  define W(left,right) (0x##right##left)
+# endif
+
+# if GCM_TABLE_BITS == 4
+static const uint16_t
+shift_table[0x10] = {
+  W(00,00),W(1c,20),W(38,40),W(24,60),W(70,80),W(6c,a0),W(48,c0),W(54,e0),
+  W(e1,00),W(fd,20),W(d9,40),W(c5,60),W(91,80),W(8d,a0),W(a9,c0),W(b5,e0),
+};
+
+static void
+gcm_gf_shift_4(union gcm_block *x)
+{
+  unsigned long *w = x->w;
+  unsigned long reduce;
+
+  /* Shift uses big-endian representation. */
+#if WORDS_BIGENDIAN
+# if SIZEOF_LONG == 4
+  reduce = shift_table[w[3] & 0xf];
+  w[3] = (w[3] >> 4) | ((w[2] & 0xf) << 28);
+  w[2] = (w[2] >> 4) | ((w[1] & 0xf) << 28);
+  w[1] = (w[1] >> 4) | ((w[0] & 0xf) << 28);
+  w[0] = (w[0] >> 4) ^ (reduce << 16);
+# elif SIZEOF_LONG == 8
+  reduce = shift_table[w[1] & 0xf];
+  w[1] = (w[1] >> 4) | ((w[0] & 0xf) << 60);
+  w[0] = (w[0] >> 4) ^ (reduce << 48);
+# else
+#  error Unsupported word size. */
+#endif
+#else /* ! WORDS_BIGENDIAN */
+# if SIZEOF_LONG == 4
+#define RSHIFT_WORD(x) \
+  ((((x) & 0xf0f0f0f0UL) >> 4)                 \
+   | (((x) & 0x000f0f0f) << 12))
+  reduce = shift_table[(w[3] >> 24) & 0xf];
+  w[3] = RSHIFT_WORD(w[3]) | ((w[2] >> 20) & 0xf0);
+  w[2] = RSHIFT_WORD(w[2]) | ((w[1] >> 20) & 0xf0);
+  w[1] = RSHIFT_WORD(w[1]) | ((w[0] >> 20) & 0xf0);
+  w[0] = RSHIFT_WORD(w[0]) ^ reduce;
+# elif SIZEOF_LONG == 8
+#define RSHIFT_WORD(x) \
+  ((((x) & 0xf0f0f0f0f0f0f0f0UL) >> 4) \
+   | (((x) & 0x000f0f0f0f0f0f0fUL) << 12))
+  reduce = shift_table[(w[1] >> 56) & 0xf];
+  w[1] = RSHIFT_WORD(w[1]) | ((w[0] >> 52) & 0xf0);
+  w[0] = RSHIFT_WORD(w[0]) ^ reduce;
+# else
+#  error Unsupported word size. */
+# endif
+# undef RSHIFT_WORD
+#endif /* ! WORDS_BIGENDIAN */
+}
+
+static void
+gcm_gf_mul (union gcm_block *x, const union gcm_block *table)
+{
+  union gcm_block Z;
+  unsigned i;
+
+  memset(Z.b, 0, sizeof(Z));
+
+  for (i = GCM_BLOCK_SIZE; i-- > 0;)
+    {
+      uint8_t b = x->b[i];
+
+      gcm_gf_shift_4(&Z);
+      gcm_gf_add(&Z, &Z, &table[b & 0xf]);
+      gcm_gf_shift_4(&Z);
+      gcm_gf_add(&Z, &Z, &table[b >> 4]);
+    }
+  memcpy (x->b, Z.b, sizeof(Z));
+}
+# elif GCM_TABLE_BITS == 8
+static const uint16_t
+shift_table[0x100] = {
+  W(00,00),W(01,c2),W(03,84),W(02,46),W(07,08),W(06,ca),W(04,8c),W(05,4e),
+  W(0e,10),W(0f,d2),W(0d,94),W(0c,56),W(09,18),W(08,da),W(0a,9c),W(0b,5e),
+  W(1c,20),W(1d,e2),W(1f,a4),W(1e,66),W(1b,28),W(1a,ea),W(18,ac),W(19,6e),
+  W(12,30),W(13,f2),W(11,b4),W(10,76),W(15,38),W(14,fa),W(16,bc),W(17,7e),
+  W(38,40),W(39,82),W(3b,c4),W(3a,06),W(3f,48),W(3e,8a),W(3c,cc),W(3d,0e),
+  W(36,50),W(37,92),W(35,d4),W(34,16),W(31,58),W(30,9a),W(32,dc),W(33,1e),
+  W(24,60),W(25,a2),W(27,e4),W(26,26),W(23,68),W(22,aa),W(20,ec),W(21,2e),
+  W(2a,70),W(2b,b2),W(29,f4),W(28,36),W(2d,78),W(2c,ba),W(2e,fc),W(2f,3e),
+  W(70,80),W(71,42),W(73,04),W(72,c6),W(77,88),W(76,4a),W(74,0c),W(75,ce),
+  W(7e,90),W(7f,52),W(7d,14),W(7c,d6),W(79,98),W(78,5a),W(7a,1c),W(7b,de),
+  W(6c,a0),W(6d,62),W(6f,24),W(6e,e6),W(6b,a8),W(6a,6a),W(68,2c),W(69,ee),
+  W(62,b0),W(63,72),W(61,34),W(60,f6),W(65,b8),W(64,7a),W(66,3c),W(67,fe),
+  W(48,c0),W(49,02),W(4b,44),W(4a,86),W(4f,c8),W(4e,0a),W(4c,4c),W(4d,8e),
+  W(46,d0),W(47,12),W(45,54),W(44,96),W(41,d8),W(40,1a),W(42,5c),W(43,9e),
+  W(54,e0),W(55,22),W(57,64),W(56,a6),W(53,e8),W(52,2a),W(50,6c),W(51,ae),
+  W(5a,f0),W(5b,32),W(59,74),W(58,b6),W(5d,f8),W(5c,3a),W(5e,7c),W(5f,be),
+  W(e1,00),W(e0,c2),W(e2,84),W(e3,46),W(e6,08),W(e7,ca),W(e5,8c),W(e4,4e),
+  W(ef,10),W(ee,d2),W(ec,94),W(ed,56),W(e8,18),W(e9,da),W(eb,9c),W(ea,5e),
+  W(fd,20),W(fc,e2),W(fe,a4),W(ff,66),W(fa,28),W(fb,ea),W(f9,ac),W(f8,6e),
+  W(f3,30),W(f2,f2),W(f0,b4),W(f1,76),W(f4,38),W(f5,fa),W(f7,bc),W(f6,7e),
+  W(d9,40),W(d8,82),W(da,c4),W(db,06),W(de,48),W(df,8a),W(dd,cc),W(dc,0e),
+  W(d7,50),W(d6,92),W(d4,d4),W(d5,16),W(d0,58),W(d1,9a),W(d3,dc),W(d2,1e),
+  W(c5,60),W(c4,a2),W(c6,e4),W(c7,26),W(c2,68),W(c3,aa),W(c1,ec),W(c0,2e),
+  W(cb,70),W(ca,b2),W(c8,f4),W(c9,36),W(cc,78),W(cd,ba),W(cf,fc),W(ce,3e),
+  W(91,80),W(90,42),W(92,04),W(93,c6),W(96,88),W(97,4a),W(95,0c),W(94,ce),
+  W(9f,90),W(9e,52),W(9c,14),W(9d,d6),W(98,98),W(99,5a),W(9b,1c),W(9a,de),
+  W(8d,a0),W(8c,62),W(8e,24),W(8f,e6),W(8a,a8),W(8b,6a),W(89,2c),W(88,ee),
+  W(83,b0),W(82,72),W(80,34),W(81,f6),W(84,b8),W(85,7a),W(87,3c),W(86,fe),
+  W(a9,c0),W(a8,02),W(aa,44),W(ab,86),W(ae,c8),W(af,0a),W(ad,4c),W(ac,8e),
+  W(a7,d0),W(a6,12),W(a4,54),W(a5,96),W(a0,d8),W(a1,1a),W(a3,5c),W(a2,9e),
+  W(b5,e0),W(b4,22),W(b6,64),W(b7,a6),W(b2,e8),W(b3,2a),W(b1,6c),W(b0,ae),
+  W(bb,f0),W(ba,32),W(b8,74),W(b9,b6),W(bc,f8),W(bd,3a),W(bf,7c),W(be,be),
+};
+
+static void
+gcm_gf_shift_8(union gcm_block *x)
+{
+  unsigned long *w = x->w;
+  unsigned long reduce;
+
+  /* Shift uses big-endian representation. */
+#if WORDS_BIGENDIAN
+# if SIZEOF_LONG == 4
+  reduce = shift_table[w[3] & 0xff];
+  w[3] = (w[3] >> 8) | ((w[2] & 0xff) << 24);
+  w[2] = (w[2] >> 8) | ((w[1] & 0xff) << 24);
+  w[1] = (w[1] >> 8) | ((w[0] & 0xff) << 24);
+  w[0] = (w[0] >> 8) ^ (reduce << 16);
+# elif SIZEOF_LONG == 8
+  reduce = shift_table[w[1] & 0xff];
+  w[1] = (w[1] >> 8) | ((w[0] & 0xff) << 56);
+  w[0] = (w[0] >> 8) ^ (reduce << 48);
+# else
+#  error Unsupported word size. */
+#endif
+#else /* ! WORDS_BIGENDIAN */
+# if SIZEOF_LONG == 4
+  reduce = shift_table[(w[3] >> 24) & 0xff];
+  w[3] = (w[3] << 8) | (w[2] >> 24);
+  w[2] = (w[2] << 8) | (w[1] >> 24);
+  w[1] = (w[1] << 8) | (w[0] >> 24);
+  w[0] = (w[0] << 8) ^ reduce;
+# elif SIZEOF_LONG == 8
+  reduce = shift_table[(w[1] >> 56) & 0xff];
+  w[1] = (w[1] << 8) | (w[0] >> 56);
+  w[0] = (w[0] << 8) ^ reduce;
+# else
+#  error Unsupported word size. */
+# endif
+#endif /* ! WORDS_BIGENDIAN */
+}
+
+static void
+gcm_gf_mul (union gcm_block *x, const union gcm_block *table)
+{
+  union gcm_block Z;
+  unsigned i;
+
+  memcpy(Z.b, table[x->b[GCM_BLOCK_SIZE-1]].b, GCM_BLOCK_SIZE);
+
+  for (i = GCM_BLOCK_SIZE-2; i > 0; i--)
+    {
+      gcm_gf_shift_8(&Z);
+      gcm_gf_add(&Z, &Z, &table[x->b[i]]);
+    }
+  gcm_gf_shift_8(&Z);
+  gcm_gf_add(x, &Z, &table[x->b[0]]);
+}
+
+# else /* GCM_TABLE_BITS != 8 */
+#  error Unsupported table size. 
+# endif /* GCM_TABLE_BITS != 8 */
+
+#undef W
+
+#endif /* GCM_TABLE_BITS */
+
+/* Increment the rightmost 32 bits. */
+#define INC32(block) INCREMENT(4, (block.b) + GCM_BLOCK_SIZE - 4)
+
+/* Initialization of GCM.
+ * @ctx: The context of GCM
+ * @cipher: The context of the underlying block cipher
+ * @f: The underlying cipher encryption function
+ */
+void
+gcm_set_key(struct gcm_key *key,
+           void *cipher, nettle_crypt_func f)
+{
+  /* Middle element if GCM_TABLE_BITS > 0, otherwise the first
+     element */
+  unsigned i = (1<<GCM_TABLE_BITS)/2;
+
+  /* H */  
+  memset(key->h[0].b, 0, GCM_BLOCK_SIZE);
+  f (cipher, GCM_BLOCK_SIZE, key->h[i].b, key->h[0].b);
+  
+#if GCM_TABLE_BITS
+  /* Algorithm 3 from the gcm paper. First do powers of two, then do
+     the rest by adding. */
+  while (i /= 2)
+    gcm_gf_shift(&key->h[i], &key->h[2*i]);
+  for (i = 2; i < 1<<GCM_TABLE_BITS; i *= 2)
+    {
+      unsigned j;
+      for (j = 1; j < i; j++)
+       gcm_gf_add(&key->h[i+j], &key->h[i],&key->h[j]);
+    }
+#endif
+}
+
+static void
+gcm_hash(const struct gcm_key *key, union gcm_block *x,
+        unsigned length, const uint8_t *data)
+{
+  for (; length >= GCM_BLOCK_SIZE;
+       length -= GCM_BLOCK_SIZE, data += GCM_BLOCK_SIZE)
+    {
+      memxor (x->b, data, GCM_BLOCK_SIZE);
+      gcm_gf_mul (x, key->h);
+    }
+  if (length > 0)
+    {
+      memxor (x->b, data, length);
+      gcm_gf_mul (x, key->h);
+    }
+}
+
+static void
+gcm_hash_sizes(const struct gcm_key *key, union gcm_block *x,
+              uint64_t auth_size, uint64_t data_size)
+{
+  uint8_t buffer[GCM_BLOCK_SIZE];
+
+  data_size *= 8;
+  auth_size *= 8;
+
+  WRITE_UINT64 (buffer, auth_size);
+  WRITE_UINT64 (buffer + 8, data_size);
+
+  gcm_hash(key, x, GCM_BLOCK_SIZE, buffer);
+}
+
+/*
+ * @length: The size of the iv (fixed for now to GCM_NONCE_SIZE)
+ * @iv: The iv
+ */
+void
+gcm_set_iv(struct gcm_ctx *ctx, const struct gcm_key *key,
+          unsigned length, const uint8_t *iv)
+{
+  if (length == GCM_IV_SIZE)
+    {
+      memcpy (ctx->iv.b, iv, GCM_BLOCK_SIZE - 4);
+      ctx->iv.b[GCM_BLOCK_SIZE - 4] = 0;
+      ctx->iv.b[GCM_BLOCK_SIZE - 3] = 0;
+      ctx->iv.b[GCM_BLOCK_SIZE - 2] = 0;
+      ctx->iv.b[GCM_BLOCK_SIZE - 1] = 1;
+    }
+  else
+    {
+      memset(ctx->iv.b, 0, GCM_BLOCK_SIZE);
+      gcm_hash(key, &ctx->iv, length, iv);
+      gcm_hash_sizes(key, &ctx->iv, 0, length);
+    }
+
+  memcpy (ctx->ctr.b, ctx->iv.b, GCM_BLOCK_SIZE);
+  INC32 (ctx->ctr);
+
+  /* Reset the rest of the message-dependent state. */
+  memset(ctx->x.b, 0, sizeof(ctx->x));
+  ctx->auth_size = ctx->data_size = 0;
+}
+
+void
+gcm_update(struct gcm_ctx *ctx, const struct gcm_key *key,
+          unsigned length, const uint8_t *data)
+{
+  assert(ctx->auth_size % GCM_BLOCK_SIZE == 0);
+  assert(ctx->data_size == 0);
+
+  gcm_hash(key, &ctx->x, length, data);
+
+  ctx->auth_size += length;
+}
+
+static void
+gcm_crypt(struct gcm_ctx *ctx, void *cipher, nettle_crypt_func *f,
+         unsigned length, uint8_t *dst, const uint8_t *src)
+{
+  uint8_t buffer[GCM_BLOCK_SIZE];
+
+  if (src != dst)
+    {
+      for (; length >= GCM_BLOCK_SIZE;
+           (length -= GCM_BLOCK_SIZE,
+           src += GCM_BLOCK_SIZE, dst += GCM_BLOCK_SIZE))
+        {
+          f (cipher, GCM_BLOCK_SIZE, dst, ctx->ctr.b);
+          memxor (dst, src, GCM_BLOCK_SIZE);
+          INC32 (ctx->ctr);
+        }
+    }
+  else
+    {
+      for (; length >= GCM_BLOCK_SIZE;
+           (length -= GCM_BLOCK_SIZE,
+           src += GCM_BLOCK_SIZE, dst += GCM_BLOCK_SIZE))
+        {
+          f (cipher, GCM_BLOCK_SIZE, buffer, ctx->ctr.b);
+          memxor3 (dst, src, buffer, GCM_BLOCK_SIZE);
+          INC32 (ctx->ctr);
+        }
+    }
+  if (length > 0)
+    {
+      /* A final partial block */
+      f (cipher, GCM_BLOCK_SIZE, buffer, ctx->ctr.b);
+      memxor3 (dst, src, buffer, length);
+      INC32 (ctx->ctr);
+    }
+}
+
+void
+gcm_encrypt (struct gcm_ctx *ctx, const struct gcm_key *key,
+            void *cipher, nettle_crypt_func *f,
+            unsigned length, uint8_t *dst, const uint8_t *src)
+{
+  assert(ctx->data_size % GCM_BLOCK_SIZE == 0);
+
+  gcm_crypt(ctx, cipher, f, length, dst, src);
+  gcm_hash(key, &ctx->x, length, dst);
+
+  ctx->data_size += length;
+}
+
+void
+gcm_decrypt(struct gcm_ctx *ctx, const struct gcm_key *key,
+           void *cipher, nettle_crypt_func *f,
+           unsigned length, uint8_t *dst, const uint8_t *src)
+{
+  assert(ctx->data_size % GCM_BLOCK_SIZE == 0);
+
+  gcm_hash(key, &ctx->x, length, src);
+  gcm_crypt(ctx, cipher, f, length, dst, src);
+
+  ctx->data_size += length;
+}
+
+void
+gcm_digest(struct gcm_ctx *ctx, const struct gcm_key *key,
+          void *cipher, nettle_crypt_func *f,
+          unsigned length, uint8_t *digest)
+{
+  uint8_t buffer[GCM_BLOCK_SIZE];
+
+  assert (length <= GCM_BLOCK_SIZE);
+
+  gcm_hash_sizes(key, &ctx->x, ctx->auth_size, ctx->data_size);
+
+  f (cipher, GCM_BLOCK_SIZE, buffer, ctx->iv.b);
+  memxor3 (digest, ctx->x.b, buffer, length);
+
+  return;
+}
diff --git a/gcm.h b/gcm.h
new file mode 100644 (file)
index 0000000..e0f7fe2
--- /dev/null
+++ b/gcm.h
@@ -0,0 +1,186 @@
+/* gcm.h
+ *
+ * Galois counter mode, specified by NIST,
+ * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
+ *
+ */
+
+/* NOTE: Tentative interface, subject to change. No effort will be
+   made to avoid incompatible changes. */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2011 Niels Möller
+ * Copyright (C) 2011 Katholieke Universiteit Leuven
+ * 
+ * Contributed by Nikos Mavrogiannopoulos
+ *
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_GCM_H_INCLUDED
+#define NETTLE_GCM_H_INCLUDED
+
+#include "aes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define gcm_set_key nettle_gcm_set_key
+#define gcm_set_iv nettle_gcm_set_iv
+#define gcm_update nettle_gcm_update
+#define gcm_encrypt nettle_gcm_encrypt
+#define gcm_decrypt nettle_gcm_decrypt
+#define gcm_digest nettle_gcm_digest
+
+#define gcm_aes_set_key nettle_gcm_aes_set_key
+#define gcm_aes_set_iv nettle_gcm_aes_set_iv
+#define gcm_aes_update nettle_gcm_aes_update
+#define gcm_aes_encrypt nettle_gcm_aes_encrypt
+#define gcm_aes_decrypt nettle_gcm_aes_decrypt
+#define gcm_aes_digest nettle_gcm_aes_digest
+
+#define GCM_BLOCK_SIZE 16
+#define GCM_IV_SIZE (GCM_BLOCK_SIZE - 4)
+
+#define GCM_TABLE_BITS 8
+
+/* To make sure that we have proper alignment. */
+union gcm_block
+{
+  uint8_t b[GCM_BLOCK_SIZE];
+  unsigned long w[GCM_BLOCK_SIZE / sizeof(unsigned long)];
+};
+
+/* Hashing subkey */
+struct gcm_key
+{
+  union gcm_block h[1 << GCM_TABLE_BITS];
+};
+  
+/* Per-message state, depending on the iv */
+struct gcm_ctx {
+  /* Original counter block */
+  union gcm_block iv;
+  /* Updated for each block. */
+  union gcm_block ctr;
+  /* Hashing state */
+  union gcm_block x;
+  uint64_t auth_size;
+  uint64_t data_size;
+};
+
+/* FIXME: Should use const for the cipher context. Then needs const for
+   nettle_crypt_func, which also rules out using that abstraction for
+   arcfour. */
+void
+gcm_set_key(struct gcm_key *key,
+           void *cipher, nettle_crypt_func *f);
+
+void
+gcm_set_iv(struct gcm_ctx *ctx, const struct gcm_key *key,
+          unsigned length, const uint8_t *iv);
+
+void
+gcm_update(struct gcm_ctx *ctx, const struct gcm_key *key,
+          unsigned length, const uint8_t *data);
+
+void
+gcm_encrypt(struct gcm_ctx *ctx, const struct gcm_key *key,
+           void *cipher, nettle_crypt_func *f,
+           unsigned length, uint8_t *dst, const uint8_t *src);
+
+void
+gcm_decrypt(struct gcm_ctx *ctx, const struct gcm_key *key,
+           void *cipher, nettle_crypt_func *f,
+           unsigned length, uint8_t *dst, const uint8_t *src);
+
+void
+gcm_digest(struct gcm_ctx *ctx, const struct gcm_key *key,
+          void *cipher, nettle_crypt_func *f,
+          unsigned length, uint8_t *digest);
+
+/* Convenience macrology (not sure how useful it is) */
+
+/* All-in-one context, with cipher, hash subkey, and message state. */
+#define GCM_CTX(type) \
+{ type cipher; struct gcm_key key; struct gcm_ctx gcm; }
+
+/* NOTE: Avoid using NULL, as we don't include anything defining it. */
+#define GCM_SET_KEY(ctx, set_key, encrypt, length, data)       \
+  do {                                                         \
+    (set_key)(&(ctx)->cipher, (length), (data));               \
+    if (0) (encrypt)(&(ctx)->cipher, 0, (void *)0, (void *)0); \
+    gcm_set_key(&(ctx)->key, &(ctx)->cipher,                   \
+               (nettle_crypt_func *) (encrypt));               \
+  } while (0)
+
+#define GCM_SET_IV(ctx, length, data)                          \
+  gcm_set_iv(&(ctx)->gcm, &(ctx)->key, (length), (data))
+
+#define GCM_UPDATE(ctx, length, data)                  \
+  gcm_update(&(ctx)->gcm, &(ctx)->key, (length), (data))
+
+#define GCM_ENCRYPT(ctx, encrypt, length, dst, src)                    \
+  (0 ? (encrypt)(&(ctx)->cipher, 0, (void *)0, (void *)0)              \
+     : gcm_encrypt(&(ctx)->gcm, &(ctx)->key, &(ctx)->cipher,           \
+                  (nettle_crypt_func *) (encrypt),                     \
+                  (length), (dst), (src)))
+
+#define GCM_DECRYPT(ctx, encrypt, length, dst, src)                    \
+  (0 ? (encrypt)(&(ctx)->cipher, 0, (void *)0, (void *)0)              \
+     : gcm_decrypt(&(ctx)->gcm,  &(ctx)->key, &(ctx)->cipher,          \
+                  (nettle_crypt_func *) (encrypt),                     \
+                  (length), (dst), (src)))
+
+#define GCM_DIGEST(ctx, encrypt, length, digest)                       \
+  (0 ? (encrypt)(&(ctx)->cipher, 0, (void *)0, (void *)0)              \
+     : gcm_digest(&(ctx)->gcm, &(ctx)->key, &(ctx)->cipher,            \
+                 (nettle_crypt_func *) (encrypt),                      \
+                 (length), (digest)))
+
+struct gcm_aes_ctx GCM_CTX(struct aes_ctx);
+
+void
+gcm_aes_set_key(struct gcm_aes_ctx *ctx,
+               unsigned length, const uint8_t *key);
+
+void
+gcm_aes_set_iv(struct gcm_aes_ctx *ctx,
+              unsigned length, const uint8_t *iv);
+
+void
+gcm_aes_update(struct gcm_aes_ctx *ctx,
+              unsigned length, const uint8_t *data);
+
+void
+gcm_aes_encrypt(struct gcm_aes_ctx *ctx,
+               unsigned length, uint8_t *dst, const uint8_t *src);
+
+void
+gcm_aes_decrypt(struct gcm_aes_ctx *ctx,
+               unsigned length, uint8_t *dst, const uint8_t *src);
+
+void
+gcm_aes_digest(struct gcm_aes_ctx *ctx, unsigned length, uint8_t *digest);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_GCM_H_INCLUDED */
diff --git a/gcmdata.c b/gcmdata.c
new file mode 100644 (file)
index 0000000..0658443
--- /dev/null
+++ b/gcmdata.c
@@ -0,0 +1,80 @@
+/* gcmdata.c
+ *
+ * Galois counter mode, specified by NIST,
+ * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
+ *
+ */
+
+/* Generation of fixed multiplication tables. */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2011 Niels Möller
+ *
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define GHASH_POLYNOMIAL 0xE1
+
+
+/* When x is shifted out over the block edge, add multiples of the
+   defining polynomial to eliminate each bit. */
+static unsigned
+reduce(unsigned x)
+{
+  unsigned p = GHASH_POLYNOMIAL << 1;
+  unsigned y = 0;
+  for (; x; x >>= 1, p <<= 1)
+    if (x & 1)
+      y ^= p;
+  return y;
+}
+
+int
+main(int argc UNUSED, char **argv UNUSED)
+{
+  unsigned i;
+  printf("4-bit table:\n");
+  
+  for (i = 0; i<16; i++)
+    {
+      unsigned x;
+      if (i && !(i%8))
+       printf("\n");
+
+      x = reduce(i << 4);
+      printf("W(%02x,%02x),", x >> 8, x & 0xff);
+    }
+  printf("\n\n");
+  printf("8-bit table:\n");
+  for (i = 0; i<256; i++)
+    {
+      unsigned x;
+      if (i && !(i%8))
+       printf("\n");
+
+      x = reduce(i);
+      printf("W(%02x,%02x),", x >> 8, x & 0xff);
+    }
+  printf("\n");
+  return EXIT_SUCCESS;
+}
diff --git a/hmac-md5.c b/hmac-md5.c
new file mode 100644 (file)
index 0000000..99ce1f9
--- /dev/null
@@ -0,0 +1,51 @@
+/* hmac-md5.c
+ *
+ * HMAC-MD5 message authentication code.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "hmac.h"
+
+void
+hmac_md5_set_key(struct hmac_md5_ctx *ctx,
+                unsigned key_length, const uint8_t *key)
+{
+  HMAC_SET_KEY(ctx, &nettle_md5, key_length, key);
+}
+
+void
+hmac_md5_update(struct hmac_md5_ctx *ctx,
+               unsigned length, const uint8_t *data)
+{
+  md5_update(&ctx->state, length, data);
+}
+
+void
+hmac_md5_digest(struct hmac_md5_ctx *ctx,
+               unsigned length, uint8_t *digest)
+{
+  HMAC_DIGEST(ctx, &nettle_md5, length, digest);
+}
diff --git a/hmac-ripemd160.c b/hmac-ripemd160.c
new file mode 100644 (file)
index 0000000..3fa8e78
--- /dev/null
@@ -0,0 +1,51 @@
+/* hmac-ripemd160.c
+ *
+ * HMAC-RIPEMD160 message authentication code.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2011 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "hmac.h"
+
+void
+hmac_ripemd160_set_key(struct hmac_ripemd160_ctx *ctx,
+                      unsigned key_length, const uint8_t *key)
+{
+  HMAC_SET_KEY(ctx, &nettle_ripemd160, key_length, key);
+}
+
+void
+hmac_ripemd160_update(struct hmac_ripemd160_ctx *ctx,
+                     unsigned length, const uint8_t *data)
+{
+  ripemd160_update(&ctx->state, length, data);
+}
+
+void
+hmac_ripemd160_digest(struct hmac_ripemd160_ctx *ctx,
+                     unsigned length, uint8_t *digest)
+{
+  HMAC_DIGEST(ctx, &nettle_ripemd160, length, digest);
+}
diff --git a/hmac-sha1.c b/hmac-sha1.c
new file mode 100644 (file)
index 0000000..64c079e
--- /dev/null
@@ -0,0 +1,51 @@
+/* hmac-sha1.c
+ *
+ * HMAC-SHA1 message authentication code.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "hmac.h"
+
+void
+hmac_sha1_set_key(struct hmac_sha1_ctx *ctx,
+                 unsigned key_length, const uint8_t *key)
+{
+  HMAC_SET_KEY(ctx, &nettle_sha1, key_length, key);
+}
+
+void
+hmac_sha1_update(struct hmac_sha1_ctx *ctx,
+                unsigned length, const uint8_t *data)
+{
+  sha1_update(&ctx->state, length, data);
+}
+
+void
+hmac_sha1_digest(struct hmac_sha1_ctx *ctx,
+                unsigned length, uint8_t *digest)
+{
+  HMAC_DIGEST(ctx, &nettle_sha1, length, digest);
+}
diff --git a/hmac-sha224.c b/hmac-sha224.c
new file mode 100644 (file)
index 0000000..580509e
--- /dev/null
@@ -0,0 +1,44 @@
+/* hmac-sha224.c
+ *
+ * HMAC-SHA224 message authentication code.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2003, 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "hmac.h"
+
+void
+hmac_sha224_set_key(struct hmac_sha224_ctx *ctx,
+                   unsigned key_length, const uint8_t *key)
+{
+  HMAC_SET_KEY(ctx, &nettle_sha224, key_length, key);
+}
+
+void
+hmac_sha224_digest(struct hmac_sha224_ctx *ctx,
+                  unsigned length, uint8_t *digest)
+{
+  HMAC_DIGEST(ctx, &nettle_sha224, length, digest);
+}
diff --git a/hmac-sha256.c b/hmac-sha256.c
new file mode 100644 (file)
index 0000000..9ead853
--- /dev/null
@@ -0,0 +1,51 @@
+/* hmac-sha256.c
+ *
+ * HMAC-SHA256 message authentication code.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "hmac.h"
+
+void
+hmac_sha256_set_key(struct hmac_sha256_ctx *ctx,
+                   unsigned key_length, const uint8_t *key)
+{
+  HMAC_SET_KEY(ctx, &nettle_sha256, key_length, key);
+}
+
+void
+hmac_sha256_update(struct hmac_sha256_ctx *ctx,
+                  unsigned length, const uint8_t *data)
+{
+  sha256_update(&ctx->state, length, data);
+}
+
+void
+hmac_sha256_digest(struct hmac_sha256_ctx *ctx,
+                  unsigned length, uint8_t *digest)
+{
+  HMAC_DIGEST(ctx, &nettle_sha256, length, digest);
+}
diff --git a/hmac-sha384.c b/hmac-sha384.c
new file mode 100644 (file)
index 0000000..f39705f
--- /dev/null
@@ -0,0 +1,44 @@
+/* hmac-sha384.c
+ *
+ * HMAC-SHA384 message authentication code.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2003, 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "hmac.h"
+
+void
+hmac_sha384_set_key(struct hmac_sha512_ctx *ctx,
+                   unsigned key_length, const uint8_t *key)
+{
+  HMAC_SET_KEY(ctx, &nettle_sha384, key_length, key);
+}
+
+void
+hmac_sha384_digest(struct hmac_sha512_ctx *ctx,
+                  unsigned length, uint8_t *digest)
+{
+  HMAC_DIGEST(ctx, &nettle_sha384, length, digest);
+}
diff --git a/hmac-sha512.c b/hmac-sha512.c
new file mode 100644 (file)
index 0000000..c09e9f5
--- /dev/null
@@ -0,0 +1,51 @@
+/* hmac-sha512.c
+ *
+ * HMAC-SHA512 message authentication code.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2003, 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "hmac.h"
+
+void
+hmac_sha512_set_key(struct hmac_sha512_ctx *ctx,
+                   unsigned key_length, const uint8_t *key)
+{
+  HMAC_SET_KEY(ctx, &nettle_sha512, key_length, key);
+}
+
+void
+hmac_sha512_update(struct hmac_sha512_ctx *ctx,
+                  unsigned length, const uint8_t *data)
+{
+  sha512_update(&ctx->state, length, data);
+}
+
+void
+hmac_sha512_digest(struct hmac_sha512_ctx *ctx,
+                  unsigned length, uint8_t *digest)
+{
+  HMAC_DIGEST(ctx, &nettle_sha512, length, digest);
+}
diff --git a/hmac.c b/hmac.c
new file mode 100644 (file)
index 0000000..dc77e94
--- /dev/null
+++ b/hmac.c
@@ -0,0 +1,109 @@
+/* hmac.c
+ *
+ * HMAC message authentication code (RFC-2104).
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+/* Needed for alloca on freebsd */
+#include <stdlib.h>
+#include <string.h>
+
+#include "hmac.h"
+
+#include "memxor.h"
+#include "nettle-internal.h"
+
+#define IPAD 0x36
+#define OPAD 0x5c
+
+void
+hmac_set_key(void *outer, void *inner, void *state,
+            const struct nettle_hash *hash,
+            unsigned key_length, const uint8_t *key)
+{
+  TMP_DECL(pad, uint8_t, NETTLE_MAX_HASH_BLOCK_SIZE);
+  TMP_ALLOC(pad, hash->block_size);
+  
+  hash->init(outer);
+  hash->init(inner);
+
+  if (key_length > hash->block_size)
+    {
+      /* Reduce key to the algorithm's hash size. Use the area pointed
+       * to by state for the temporary state. */
+
+      TMP_DECL(digest, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE);
+      TMP_ALLOC(digest, hash->digest_size);
+
+      hash->init(state);
+      hash->update(state, key_length, key);
+      hash->digest(state, hash->digest_size, digest);
+
+      key = digest;
+      key_length = hash->digest_size;
+    }
+
+  assert(key_length <= hash->block_size);
+  
+  memset(pad, OPAD, hash->block_size);
+  memxor(pad, key, key_length);
+
+  hash->update(outer, hash->block_size, pad);
+
+  memset(pad, IPAD, hash->block_size);
+  memxor(pad, key, key_length);
+
+  hash->update(inner, hash->block_size, pad);
+
+  memcpy(state, inner, hash->context_size);
+}
+
+void
+hmac_update(void *state,
+           const struct nettle_hash *hash,
+           unsigned length, const uint8_t *data)
+{
+  hash->update(state, length, data);
+}
+
+void
+hmac_digest(const void *outer, const void *inner, void *state,
+           const struct nettle_hash *hash,         
+           unsigned length, uint8_t *dst)
+{
+  TMP_DECL(digest, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE);
+  TMP_ALLOC(digest, hash->digest_size);
+
+  hash->digest(state, hash->digest_size, digest);
+
+  memcpy(state, outer, hash->context_size);
+
+  hash->update(state, hash->digest_size, digest);
+  hash->digest(state, length, dst);
+
+  memcpy(state, inner, hash->context_size);
+}
diff --git a/hmac.h b/hmac.h
new file mode 100644 (file)
index 0000000..ea6cef2
--- /dev/null
+++ b/hmac.h
@@ -0,0 +1,201 @@
+/* hmac.h
+ *
+ * HMAC message authentication code (RFC-2104).
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_HMAC_H_INCLUDED
+#define NETTLE_HMAC_H_INCLUDED
+
+#include "nettle-meta.h"
+
+#include "md5.h"
+#include "ripemd160.h"
+#include "sha.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Namespace mangling */
+#define hmac_set_key nettle_hmac_set_key
+#define hmac_update nettle_hmac_update
+#define hmac_digest nettle_hmac_digest
+#define hmac_md5_set_key nettle_hmac_md5_set_key
+#define hmac_md5_update nettle_hmac_md5_update
+#define hmac_md5_digest nettle_hmac_md5_digest
+#define hmac_ripemd160_set_key nettle_hmac_ripemd160_set_key
+#define hmac_ripemd160_update nettle_hmac_ripemd160_update
+#define hmac_ripemd160_digest nettle_hmac_ripemd160_digest
+#define hmac_sha1_set_key nettle_hmac_sha1_set_key
+#define hmac_sha1_update nettle_hmac_sha1_update
+#define hmac_sha1_digest nettle_hmac_sha1_digest
+#define hmac_sha224_set_key nettle_hmac_sha224_set_key
+#define hmac_sha224_digest nettle_hmac_sha224_digest
+#define hmac_sha256_set_key nettle_hmac_sha256_set_key
+#define hmac_sha256_update nettle_hmac_sha256_update
+#define hmac_sha256_digest nettle_hmac_sha256_digest
+#define hmac_sha384_set_key nettle_hmac_sha384_set_key
+#define hmac_sha384_digest nettle_hmac_sha384_digest
+#define hmac_sha512_set_key nettle_hmac_sha512_set_key
+#define hmac_sha512_update nettle_hmac_sha512_update
+#define hmac_sha512_digest nettle_hmac_sha512_digest
+
+void
+hmac_set_key(void *outer, void *inner, void *state,
+            const struct nettle_hash *hash,
+            unsigned length, const uint8_t *key);
+
+/* This function is not strictly needed, it's s just the same as the
+ * hash update function. */
+void
+hmac_update(void *state,
+           const struct nettle_hash *hash,
+           unsigned length, const uint8_t *data);
+
+void
+hmac_digest(const void *outer, const void *inner, void *state,
+           const struct nettle_hash *hash,
+           unsigned length, uint8_t *digest);
+
+
+#define HMAC_CTX(type) \
+{ type outer; type inner; type state; }
+
+#define HMAC_SET_KEY(ctx, hash, length, key)                   \
+  hmac_set_key( &(ctx)->outer, &(ctx)->inner, &(ctx)->state,   \
+                (hash), (length), (key) )
+
+#define HMAC_DIGEST(ctx, hash, length, digest)                 \
+  hmac_digest( &(ctx)->outer, &(ctx)->inner, &(ctx)->state,    \
+               (hash), (length), (digest) )
+
+/* HMAC using specific hash functions */
+
+/* hmac-md5 */
+struct hmac_md5_ctx HMAC_CTX(struct md5_ctx);
+
+void
+hmac_md5_set_key(struct hmac_md5_ctx *ctx,
+                unsigned key_length, const uint8_t *key);
+
+void
+hmac_md5_update(struct hmac_md5_ctx *ctx,
+               unsigned length, const uint8_t *data);
+
+void
+hmac_md5_digest(struct hmac_md5_ctx *ctx,
+               unsigned length, uint8_t *digest);
+
+
+/* hmac-ripemd160 */
+struct hmac_ripemd160_ctx HMAC_CTX(struct ripemd160_ctx);
+
+void
+hmac_ripemd160_set_key(struct hmac_ripemd160_ctx *ctx,
+                      unsigned key_length, const uint8_t *key);
+
+void
+hmac_ripemd160_update(struct hmac_ripemd160_ctx *ctx,
+                     unsigned length, const uint8_t *data);
+
+void
+hmac_ripemd160_digest(struct hmac_ripemd160_ctx *ctx,
+                     unsigned length, uint8_t *digest);
+
+
+/* hmac-sha1 */
+struct hmac_sha1_ctx HMAC_CTX(struct sha1_ctx);
+
+void
+hmac_sha1_set_key(struct hmac_sha1_ctx *ctx,
+                 unsigned key_length, const uint8_t *key);
+
+void
+hmac_sha1_update(struct hmac_sha1_ctx *ctx,
+                unsigned length, const uint8_t *data);
+
+void
+hmac_sha1_digest(struct hmac_sha1_ctx *ctx,
+                unsigned length, uint8_t *digest);
+
+/* hmac-sha256 */
+struct hmac_sha256_ctx HMAC_CTX(struct sha256_ctx);
+
+void
+hmac_sha256_set_key(struct hmac_sha256_ctx *ctx,
+                   unsigned key_length, const uint8_t *key);
+
+void
+hmac_sha256_update(struct hmac_sha256_ctx *ctx,
+                  unsigned length, const uint8_t *data);
+
+void
+hmac_sha256_digest(struct hmac_sha256_ctx *ctx,
+                  unsigned length, uint8_t *digest);
+
+/* hmac-sha224 */
+#define hmac_sha224_ctx hmac_sha256_ctx
+
+void
+hmac_sha224_set_key(struct hmac_sha224_ctx *ctx,
+                   unsigned key_length, const uint8_t *key);
+
+#define hmac_sha224_update nettle_hmac_sha256_update
+
+void
+hmac_sha224_digest(struct hmac_sha224_ctx *ctx,
+                  unsigned length, uint8_t *digest);
+
+/* hmac-sha512 */
+struct hmac_sha512_ctx HMAC_CTX(struct sha512_ctx);
+
+void
+hmac_sha512_set_key(struct hmac_sha512_ctx *ctx,
+                   unsigned key_length, const uint8_t *key);
+
+void
+hmac_sha512_update(struct hmac_sha512_ctx *ctx,
+                  unsigned length, const uint8_t *data);
+
+void
+hmac_sha512_digest(struct hmac_sha512_ctx *ctx,
+                  unsigned length, uint8_t *digest);
+
+/* hmac-sha384 */
+#define hmac_sha384_ctx hmac_sha512_ctx
+
+void
+hmac_sha384_set_key(struct hmac_sha512_ctx *ctx,
+                   unsigned key_length, const uint8_t *key);
+
+#define hmac_sha384_update nettle_hmac_sha512_update
+
+void
+hmac_sha384_digest(struct hmac_sha512_ctx *ctx,
+                  unsigned length, uint8_t *digest);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_HMAC_H_INCLUDED */
diff --git a/hogweed.pc.in b/hogweed.pc.in
new file mode 100644 (file)
index 0000000..457f5f2
--- /dev/null
@@ -0,0 +1,18 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+# Uses Requires.private and Libs.private, under the assumption that
+# when using shared libraries, the ELF dependencies from libhogweed.so
+# to nettle and gmp work.
+
+Name: Hogweed
+Description: Nettle low-level cryptographic library (public-key algorithms)
+URL: http://www.lysator.liu.se/~nisse/nettle
+Version: @PACKAGE_VERSION@
+Requires.private: nettle
+Libs: -L${libdir} -lhogweed
+Libs.private: -lgmp
+Cflags: -I${includedir}
+
diff --git a/install-sh b/install-sh
new file mode 100755 (executable)
index 0000000..4fbbae7
--- /dev/null
@@ -0,0 +1,507 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2006-10-14.15
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# 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.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+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-}"
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+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}"
+
+posix_glob=
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chmodcmd=$chmodprog
+chowncmd=
+chgrpcmd=
+stripcmd=
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=
+dst=
+dir_arg=
+dstarg=
+no_target_directory=
+
+usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+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.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) shift
+        continue;;
+
+    -d) dir_arg=true
+        shift
+        continue;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+        shift
+        shift
+        continue;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+        shift
+        shift
+       case $mode in
+         *' '* | *'    '* | *'
+'*       | *'*'* | *'?'* | *'['*)
+           echo "$0: invalid mode: $mode" >&2
+           exit 1;;
+       esac
+        continue;;
+
+    -o) chowncmd="$chownprog $2"
+        shift
+        shift
+        continue;;
+
+    -s) stripcmd=$stripprog
+        shift
+        continue;;
+
+    -t) dstarg=$2
+       shift
+       shift
+       continue;;
+
+    -T) no_target_directory=true
+       shift
+       continue;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --)        shift
+       break;;
+
+    -*)        echo "$0: invalid option: $1" >&2
+       exit 1;;
+
+    *)  break;;
+  esac
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dstarg"; 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
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dstarg"
+      shift # fnord
+    fi
+    shift # arg
+    dstarg=$arg
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  trap '(exit $?); exit' 1 2 13 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+       u_plus_rw=
+      else
+       u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+       u_plus_rw=
+      else
+       u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src ;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dstarg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dstarg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst ;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+       echo "$0: $dstarg: Is a directory" >&2
+       exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+       (dirname "$dst") 2>/dev/null ||
+       expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+            X"$dst" : 'X\(//\)[^/]' \| \
+            X"$dst" : 'X\(//\)$' \| \
+            X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+       echo X"$dst" |
+           sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+                  s//\1/
+                  q
+                }
+                /^X\(\/\/\)[^/].*/{
+                  s//\1/
+                  q
+                }
+                /^X\(\/\/\)$/{
+                  s//\1/
+                  q
+                }
+                /^X\(\/\).*/{
+                  s//\1/
+                  q
+                }
+                s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+       # Create intermediate dirs using mode 755 as modified by the umask.
+       # This is like FreeBSD 'install' as of 1997-10-28.
+       umask=`umask`
+       case $stripcmd.$umask in
+         # Optimize common cases.
+         *[2367][2367]) mkdir_umask=$umask;;
+         .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+         *[0-7])
+           mkdir_umask=`expr $umask + 22 \
+             - $umask % 100 % 40 + $umask % 20 \
+             - $umask % 10 % 4 + $umask % 2
+           `;;
+         *) mkdir_umask=$umask,go-w;;
+       esac
+
+       # With -d, create the new directory with the user-specified mode.
+       # Otherwise, rely on $mkdir_umask.
+       if test -n "$dir_arg"; then
+         mkdir_mode=-m$mode
+       else
+         mkdir_mode=
+       fi
+
+       posix_mkdir=false
+       case $umask in
+         *[123567][0-7][0-7])
+           # POSIX mkdir -p sets u+wx bits regardless of umask, which
+           # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+           ;;
+         *)
+           tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+           trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+           if (umask $mkdir_umask &&
+               exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+           then
+             if test -z "$dir_arg" || {
+                  # Check for POSIX incompatibilities with -m.
+                  # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+                  # other-writeable bit of parent directory when it shouldn't.
+                  # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+                  ls_ld_tmpdir=`ls -ld "$tmpdir"`
+                  case $ls_ld_tmpdir in
+                    d????-?r-*) different_mode=700;;
+                    d????-?--*) different_mode=755;;
+                    *) false;;
+                  esac &&
+                  $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+                    ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+                    test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+                  }
+                }
+             then posix_mkdir=:
+             fi
+             rmdir "$tmpdir/d" "$tmpdir"
+           else
+             # Remove any dirs left behind by ancient mkdir implementations.
+             rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+           fi
+           trap '' 0;;
+       esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+       umask $mkdir_umask &&
+       $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+       /*) prefix=/ ;;
+       -*) prefix=./ ;;
+       *)  prefix= ;;
+      esac
+
+      case $posix_glob in
+        '')
+         if (set -f) 2>/dev/null; then
+           posix_glob=true
+         else
+           posix_glob=false
+         fi ;;
+      esac
+
+      oIFS=$IFS
+      IFS=/
+      $posix_glob && set -f
+      set fnord $dstdir
+      shift
+      $posix_glob && set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+       test -z "$d" && continue
+
+       prefix=$prefix$d
+       if test -d "$prefix"; then
+         prefixes=
+       else
+         if $posix_mkdir; then
+           (umask=$mkdir_umask &&
+            $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+           # Don't fail if two instances are running concurrently.
+           test -d "$prefix" || exit 1
+         else
+           case $prefix in
+             *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+             *) qprefix=$prefix;;
+           esac
+           prefixes="$prefixes '$qprefix'"
+         fi
+       fi
+       prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+       # Don't fail if two instances are running concurrently.
+       (umask $mkdir_umask &&
+        eval "\$doit_exec \$mkdirprog $prefixes") ||
+         test -d "$dstdir" || exit 1
+       obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # 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
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/keymap.h b/keymap.h
new file mode 100644 (file)
index 0000000..5600c32
--- /dev/null
+++ b/keymap.h
@@ -0,0 +1,138 @@
+/* automagically made - do not fuss with this */
+
+ 0x02080008, 0x02082000, 0x00002008, 0x00000000,
+ 0x02002000, 0x00080008, 0x02080000, 0x02082008,
+ 0x00000008, 0x02000000, 0x00082000, 0x00002008,
+ 0x00082008, 0x02002008, 0x02000008, 0x02080000,
+ 0x00002000, 0x00082008, 0x00080008, 0x02002000,
+ 0x02082008, 0x02000008, 0x00000000, 0x00082000,
+ 0x02000000, 0x00080000, 0x02002008, 0x02080008,
+ 0x00080000, 0x00002000, 0x02082000, 0x00000008,
+ 0x00080000, 0x00002000, 0x02000008, 0x02082008,
+ 0x00002008, 0x02000000, 0x00000000, 0x00082000,
+ 0x02080008, 0x02002008, 0x02002000, 0x00080008,
+ 0x02082000, 0x00000008, 0x00080008, 0x02002000,
+ 0x02082008, 0x00080000, 0x02080000, 0x02000008,
+ 0x00082000, 0x00002008, 0x02002008, 0x02080000,
+ 0x00000008, 0x02082000, 0x00082008, 0x00000000,
+ 0x02000000, 0x02080008, 0x00002000, 0x00082008,
+
+ 0x08000004, 0x00020004, 0x00000000, 0x08020200,
+ 0x00020004, 0x00000200, 0x08000204, 0x00020000,
+ 0x00000204, 0x08020204, 0x00020200, 0x08000000,
+ 0x08000200, 0x08000004, 0x08020000, 0x00020204,
+ 0x00020000, 0x08000204, 0x08020004, 0x00000000,
+ 0x00000200, 0x00000004, 0x08020200, 0x08020004,
+ 0x08020204, 0x08020000, 0x08000000, 0x00000204,
+ 0x00000004, 0x00020200, 0x00020204, 0x08000200,
+ 0x00000204, 0x08000000, 0x08000200, 0x00020204,
+ 0x08020200, 0x00020004, 0x00000000, 0x08000200,
+ 0x08000000, 0x00000200, 0x08020004, 0x00020000,
+ 0x00020004, 0x08020204, 0x00020200, 0x00000004,
+ 0x08020204, 0x00020200, 0x00020000, 0x08000204,
+ 0x08000004, 0x08020000, 0x00020204, 0x00000000,
+ 0x00000200, 0x08000004, 0x08000204, 0x08020200,
+ 0x08020000, 0x00000204, 0x00000004, 0x08020004,
+
+ 0x80040100, 0x01000100, 0x80000000, 0x81040100,
+ 0x00000000, 0x01040000, 0x81000100, 0x80040000,
+ 0x01040100, 0x81000000, 0x01000000, 0x80000100,
+ 0x81000000, 0x80040100, 0x00040000, 0x01000000,
+ 0x81040000, 0x00040100, 0x00000100, 0x80000000,
+ 0x00040100, 0x81000100, 0x01040000, 0x00000100,
+ 0x80000100, 0x00000000, 0x80040000, 0x01040100,
+ 0x01000100, 0x81040000, 0x81040100, 0x00040000,
+ 0x81040000, 0x80000100, 0x00040000, 0x81000000,
+ 0x00040100, 0x01000100, 0x80000000, 0x01040000,
+ 0x81000100, 0x00000000, 0x00000100, 0x80040000,
+ 0x00000000, 0x81040000, 0x01040100, 0x00000100,
+ 0x01000000, 0x81040100, 0x80040100, 0x00040000,
+ 0x81040100, 0x80000000, 0x01000100, 0x80040100,
+ 0x80040000, 0x00040100, 0x01040000, 0x81000100,
+ 0x80000100, 0x01000000, 0x81000000, 0x01040100,
+
+ 0x04010801, 0x00000000, 0x00010800, 0x04010000,
+ 0x04000001, 0x00000801, 0x04000800, 0x00010800,
+ 0x00000800, 0x04010001, 0x00000001, 0x04000800,
+ 0x00010001, 0x04010800, 0x04010000, 0x00000001,
+ 0x00010000, 0x04000801, 0x04010001, 0x00000800,
+ 0x00010801, 0x04000000, 0x00000000, 0x00010001,
+ 0x04000801, 0x00010801, 0x04010800, 0x04000001,
+ 0x04000000, 0x00010000, 0x00000801, 0x04010801,
+ 0x00010001, 0x04010800, 0x04000800, 0x00010801,
+ 0x04010801, 0x00010001, 0x04000001, 0x00000000,
+ 0x04000000, 0x00000801, 0x00010000, 0x04010001,
+ 0x00000800, 0x04000000, 0x00010801, 0x04000801,
+ 0x04010800, 0x00000800, 0x00000000, 0x04000001,
+ 0x00000001, 0x04010801, 0x00010800, 0x04010000,
+ 0x04010001, 0x00010000, 0x00000801, 0x04000800,
+ 0x04000801, 0x00000001, 0x04010000, 0x00010800,
+
+ 0x00000400, 0x00000020, 0x00100020, 0x40100000,
+ 0x40100420, 0x40000400, 0x00000420, 0x00000000,
+ 0x00100000, 0x40100020, 0x40000020, 0x00100400,
+ 0x40000000, 0x00100420, 0x00100400, 0x40000020,
+ 0x40100020, 0x00000400, 0x40000400, 0x40100420,
+ 0x00000000, 0x00100020, 0x40100000, 0x00000420,
+ 0x40100400, 0x40000420, 0x00100420, 0x40000000,
+ 0x40000420, 0x40100400, 0x00000020, 0x00100000,
+ 0x40000420, 0x00100400, 0x40100400, 0x40000020,
+ 0x00000400, 0x00000020, 0x00100000, 0x40100400,
+ 0x40100020, 0x40000420, 0x00000420, 0x00000000,
+ 0x00000020, 0x40100000, 0x40000000, 0x00100020,
+ 0x00000000, 0x40100020, 0x00100020, 0x00000420,
+ 0x40000020, 0x00000400, 0x40100420, 0x00100000,
+ 0x00100420, 0x40000000, 0x40000400, 0x40100420,
+ 0x40100000, 0x00100420, 0x00100400, 0x40000400,
+
+ 0x00800000, 0x00001000, 0x00000040, 0x00801042,
+ 0x00801002, 0x00800040, 0x00001042, 0x00801000,
+ 0x00001000, 0x00000002, 0x00800002, 0x00001040,
+ 0x00800042, 0x00801002, 0x00801040, 0x00000000,
+ 0x00001040, 0x00800000, 0x00001002, 0x00000042,
+ 0x00800040, 0x00001042, 0x00000000, 0x00800002,
+ 0x00000002, 0x00800042, 0x00801042, 0x00001002,
+ 0x00801000, 0x00000040, 0x00000042, 0x00801040,
+ 0x00801040, 0x00800042, 0x00001002, 0x00801000,
+ 0x00001000, 0x00000002, 0x00800002, 0x00800040,
+ 0x00800000, 0x00001040, 0x00801042, 0x00000000,
+ 0x00001042, 0x00800000, 0x00000040, 0x00001002,
+ 0x00800042, 0x00000040, 0x00000000, 0x00801042,
+ 0x00801002, 0x00801040, 0x00000042, 0x00001000,
+ 0x00001040, 0x00801002, 0x00800040, 0x00000042,
+ 0x00000002, 0x00001042, 0x00801000, 0x00800002,
+
+ 0x10400000, 0x00404010, 0x00000010, 0x10400010,
+ 0x10004000, 0x00400000, 0x10400010, 0x00004010,
+ 0x00400010, 0x00004000, 0x00404000, 0x10000000,
+ 0x10404010, 0x10000010, 0x10000000, 0x10404000,
+ 0x00000000, 0x10004000, 0x00404010, 0x00000010,
+ 0x10000010, 0x10404010, 0x00004000, 0x10400000,
+ 0x10404000, 0x00400010, 0x10004010, 0x00404000,
+ 0x00004010, 0x00000000, 0x00400000, 0x10004010,
+ 0x00404010, 0x00000010, 0x10000000, 0x00004000,
+ 0x10000010, 0x10004000, 0x00404000, 0x10400010,
+ 0x00000000, 0x00404010, 0x00004010, 0x10404000,
+ 0x10004000, 0x00400000, 0x10404010, 0x10000000,
+ 0x10004010, 0x10400000, 0x00400000, 0x10404010,
+ 0x00004000, 0x00400010, 0x10400010, 0x00004010,
+ 0x00400010, 0x00000000, 0x10404000, 0x10000010,
+ 0x10400000, 0x10004010, 0x00000010, 0x00404000,
+
+ 0x00208080, 0x00008000, 0x20200000, 0x20208080,
+ 0x00200000, 0x20008080, 0x20008000, 0x20200000,
+ 0x20008080, 0x00208080, 0x00208000, 0x20000080,
+ 0x20200080, 0x00200000, 0x00000000, 0x20008000,
+ 0x00008000, 0x20000000, 0x00200080, 0x00008080,
+ 0x20208080, 0x00208000, 0x20000080, 0x00200080,
+ 0x20000000, 0x00000080, 0x00008080, 0x20208000,
+ 0x00000080, 0x20200080, 0x20208000, 0x00000000,
+ 0x00000000, 0x20208080, 0x00200080, 0x20008000,
+ 0x00208080, 0x00008000, 0x20000080, 0x00200080,
+ 0x20208000, 0x00000080, 0x00008080, 0x20200000,
+ 0x20008080, 0x20000000, 0x20200000, 0x00208000,
+ 0x20208080, 0x00008080, 0x00208000, 0x20200080,
+ 0x00200000, 0x20000080, 0x20008000, 0x00000000,
+ 0x00008000, 0x00200000, 0x20200080, 0x00208080,
+ 0x20000000, 0x20208000, 0x00000080, 0x20008080,
+
diff --git a/knuth-lfib.c b/knuth-lfib.c
new file mode 100644 (file)
index 0000000..e12688c
--- /dev/null
@@ -0,0 +1,162 @@
+/* knuth-lfib.c
+ *
+ * A "lagged fibonacci" pseudorandomness generator.
+ *
+ * Described in Knuth, TAOCP, 3.6
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *
+ * Includes code copied verbatim from Knuth's TAOCP.
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* NOTE: This generator is totally inappropriate for cryptographic
+ * applications. It is useful for generating deterministic but
+ * random-looking test data, and is used by the Nettle testsuite. */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "knuth-lfib.h"
+
+#include "macros.h"
+
+#define KK _KNUTH_LFIB_KK
+#define LL 37
+#define MM (1UL << 30)
+#define TT 70
+
+void
+knuth_lfib_init(struct knuth_lfib_ctx *ctx, uint32_t seed)
+{
+  uint32_t t,j;
+  uint32_t x[2*KK - 1];
+  uint32_t ss = (seed + 2) & (MM-2);
+
+  for (j = 0; j<KK; j++)
+    {
+      x[j] = ss;
+      ss <<= 1;  if (ss >= MM) ss -= (MM-2);
+    }
+  for (;j< 2*KK-1; j++)
+    x[j] = 0;
+
+  x[1]++;
+
+  ss = seed & (MM-1);
+  for (t = TT-1; t; )
+    {
+      for (j = KK-1; j>0; j--)
+        x[j+j] = x[j];
+      for (j = 2*KK-2; j > KK-LL; j-= 2)
+        x[2*KK-1-j] = x[j] & ~1;
+      for (j = 2*KK-2; j>=KK; j--)
+        if (x[j] & 1)
+          {
+            x[j-(KK-LL)] = (x[j - (KK-LL)] - x[j]) & (MM-1);
+            x[j-KK] = (x[j-KK] - x[j]) & (MM-1);
+          }
+      if (ss & 1)
+        {
+          for (j=KK; j>0; j--)
+            x[j] = x[j-1];
+          x[0] = x[KK];
+          if (x[KK] & 1)
+            x[LL] = (x[LL] - x[KK]) & (MM-1);
+        }
+      if (ss)
+        ss >>= 1;
+      else
+        t--;
+    }
+  for (j=0; j<LL; j++)
+    ctx->x[j+KK-LL] = x[j];
+  for (; j<KK; j++)
+    ctx->x[j-LL] = x[j];
+
+  ctx->index = 0;
+}     
+
+/* Get's a single number in the range 0 ... 2^30-1 */
+uint32_t
+knuth_lfib_get(struct knuth_lfib_ctx *ctx)
+{
+  uint32_t value;
+  assert(ctx->index < KK);
+  
+  value = ctx->x[ctx->index];
+  ctx->x[ctx->index] -= ctx->x[(ctx->index + KK - LL) % KK];
+  ctx->x[ctx->index] &= (MM-1);
+  
+  ctx->index = (ctx->index + 1) % KK;
+
+  return value;
+} 
+
+/* NOTE: Not at all optimized. */
+void
+knuth_lfib_get_array(struct knuth_lfib_ctx *ctx,
+                    unsigned n, uint32_t *a)
+{
+  unsigned i;
+  
+  for (i = 0; i<n; i++)
+    a[i] = knuth_lfib_get(ctx);
+}
+
+/* NOTE: Not at all optimized. */
+void
+knuth_lfib_random(struct knuth_lfib_ctx *ctx,
+                 unsigned n, uint8_t *dst)
+{
+  /* Use 24 bits from each number, xoring together some of the
+     bits. */
+  
+  for (; n >= 3; n-=3, dst += 3)
+    {
+      uint32_t value = knuth_lfib_get(ctx);
+
+      /* Xor the most significant octet (containing 6 significant bits)
+       * into the lower octet. */
+      value ^= (value >> 24);
+
+      WRITE_UINT24(dst, value);
+    }
+  if (n)
+    {
+      /* We need one or two octets more */
+      uint32_t value = knuth_lfib_get(ctx);
+      switch (n)
+       {
+       case 1:
+         *dst++ = value & 0xff;
+         break;
+       case 2:
+         WRITE_UINT16(dst, value);
+         break;
+       default:
+         abort();
+       }
+    }
+}
diff --git a/knuth-lfib.h b/knuth-lfib.h
new file mode 100644 (file)
index 0000000..b52393e
--- /dev/null
@@ -0,0 +1,75 @@
+/* knuth-lfib.h
+ *
+ * A "lagged fibonacci" pseudorandomness generator.
+ *
+ * Described in Knuth, TAOCP, 3.6
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* NOTE: This generator is totally inappropriate for cryptographic
+ * applications. It is useful for generating deterministic but
+ * random-looking test data, and is used by the Nettle testsuite. */
+#ifndef NETTLE_KNUTH_LFIB_H_INCLUDED
+#define NETTLE_KNUTH_LFIB_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Namespace mangling */
+#define knuth_lfib_init nettle_knuth_lfib_init
+#define knuth_lfib_get nettle_knuth_lfib_get
+#define knuth_lfib_get_array nettle_knuth_lfib_get_array
+#define knuth_lfib_random nettle_knuth_lfib_random
+
+#define _KNUTH_LFIB_KK 100
+
+struct knuth_lfib_ctx
+{
+  uint32_t x[_KNUTH_LFIB_KK];
+  unsigned index;
+};
+
+void
+knuth_lfib_init(struct knuth_lfib_ctx *ctx, uint32_t seed);
+
+/* Get's a single number in the range 0 ... 2^30-1 */
+uint32_t
+knuth_lfib_get(struct knuth_lfib_ctx *ctx);
+
+/* Get an array of numbers */
+void
+knuth_lfib_get_array(struct knuth_lfib_ctx *ctx,
+                    unsigned n, uint32_t *a);
+
+/* Get an array of octets. */
+void
+knuth_lfib_random(struct knuth_lfib_ctx *ctx,
+                 unsigned n, uint8_t *dst);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_KNUTH_LFIB_H_INCLUDED */
diff --git a/macros.h b/macros.h
new file mode 100644 (file)
index 0000000..6b06007
--- /dev/null
+++ b/macros.h
@@ -0,0 +1,214 @@
+/* macros.h
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_MACROS_H_INCLUDED
+#define NETTLE_MACROS_H_INCLUDED
+
+/* Reads a 64-bit integer, in network, big-endian, byte order */
+#define READ_UINT64(p)                         \
+(  (((uint64_t) (p)[0]) << 56)                 \
+ | (((uint64_t) (p)[1]) << 48)                 \
+ | (((uint64_t) (p)[2]) << 40)                 \
+ | (((uint64_t) (p)[3]) << 32)                 \
+ | (((uint64_t) (p)[4]) << 24)                 \
+ | (((uint64_t) (p)[5]) << 16)                 \
+ | (((uint64_t) (p)[6]) << 8)                  \
+ |  ((uint64_t) (p)[7]))
+
+#define WRITE_UINT64(p, i)                     \
+do {                                           \
+  (p)[0] = ((i) >> 56) & 0xff;                 \
+  (p)[1] = ((i) >> 48) & 0xff;                 \
+  (p)[2] = ((i) >> 40) & 0xff;                 \
+  (p)[3] = ((i) >> 32) & 0xff;                 \
+  (p)[4] = ((i) >> 24) & 0xff;                 \
+  (p)[5] = ((i) >> 16) & 0xff;                 \
+  (p)[6] = ((i) >> 8) & 0xff;                  \
+  (p)[7] = (i) & 0xff;                         \
+} while(0)
+
+/* Reads a 32-bit integer, in network, big-endian, byte order */
+#define READ_UINT32(p)                         \
+(  (((uint32_t) (p)[0]) << 24)                 \
+ | (((uint32_t) (p)[1]) << 16)                 \
+ | (((uint32_t) (p)[2]) << 8)                  \
+ |  ((uint32_t) (p)[3]))
+
+#define WRITE_UINT32(p, i)                     \
+do {                                           \
+  (p)[0] = ((i) >> 24) & 0xff;                 \
+  (p)[1] = ((i) >> 16) & 0xff;                 \
+  (p)[2] = ((i) >> 8) & 0xff;                  \
+  (p)[3] = (i) & 0xff;                         \
+} while(0)
+
+/* Analogous macros, for 24 and 16 bit numbers */
+#define READ_UINT24(p)                         \
+(  (((uint32_t) (p)[0]) << 16)                 \
+ | (((uint32_t) (p)[1]) << 8)                  \
+ |  ((uint32_t) (p)[2]))
+
+#define WRITE_UINT24(p, i)                     \
+do {                                           \
+  (p)[0] = ((i) >> 16) & 0xff;                 \
+  (p)[1] = ((i) >> 8) & 0xff;                  \
+  (p)[2] = (i) & 0xff;                         \
+} while(0)
+
+#define READ_UINT16(p)                         \
+(  (((uint32_t) (p)[0]) << 8)                  \
+ |  ((uint32_t) (p)[1]))
+
+#define WRITE_UINT16(p, i)                     \
+do {                                           \
+  (p)[0] = ((i) >> 8) & 0xff;                  \
+  (p)[1] = (i) & 0xff;                         \
+} while(0)
+
+/* And the other, little-endian, byteorder */
+#define LE_READ_UINT32(p)                      \
+(  (((uint32_t) (p)[3]) << 24)                 \
+ | (((uint32_t) (p)[2]) << 16)                 \
+ | (((uint32_t) (p)[1]) << 8)                  \
+ |  ((uint32_t) (p)[0]))
+
+#define LE_WRITE_UINT32(p, i)                  \
+do {                                           \
+  (p)[3] = ((i) >> 24) & 0xff;                 \
+  (p)[2] = ((i) >> 16) & 0xff;                 \
+  (p)[1] = ((i) >> 8) & 0xff;                  \
+  (p)[0] = (i) & 0xff;                         \
+} while(0)
+
+/* Analogous macros, for 16 bit numbers */
+#define LE_READ_UINT16(p)                      \
+  (  (((uint32_t) (p)[1]) << 8)                        \
+     |  ((uint32_t) (p)[0]))
+
+#define LE_WRITE_UINT16(p, i)                  \
+  do {                                         \
+    (p)[1] = ((i) >> 8) & 0xff;                        \
+    (p)[0] = (i) & 0xff;                       \
+  } while(0)
+
+/* Macro to make it easier to loop over several blocks. */
+#define FOR_BLOCKS(length, dst, src, blocksize)        \
+  assert( !((length) % (blocksize)));           \
+  for (; (length); ((length) -= (blocksize),   \
+                 (dst) += (blocksize),         \
+                 (src) += (blocksize)) )
+
+/* Requires that size >= 2 */
+#define INCREMENT(size, ctr)                   \
+  do {                                         \
+    unsigned increment_i = (size) - 1;         \
+    if (++(ctr)[increment_i] == 0)             \
+      {                                                \
+       while (++(ctr)[--increment_i] == 0      \
+              && increment_i > 0)              \
+         ;                                     \
+      }                                                \
+  } while (0)
+
+
+/* Helper macro for Merkle-Damgård hash functions. Assumes the context
+   structs includes the following fields:
+
+     xxx count_low, count_high;                // Two word block count
+     uint8_t block[...];               // Buffer holding one block
+     unsigned int index;               // Index into block
+*/
+
+/* FIXME: Should probably switch to using uint64_t for the count, but
+   due to alignment and byte order that may be an ABI change. */
+
+#define MD_INCR(ctx) ((ctx)->count_high += !++(ctx)->count_low)
+
+/* Takes the compression function f as argument. NOTE: also clobbers
+   length and data. */
+#define MD_UPDATE(ctx, length, data, f, incr)                          \
+  do {                                                                 \
+    if ((ctx)->index)                                                  \
+      {                                                                        \
+       /* Try to fill partial block */                                 \
+       unsigned __md_left = sizeof((ctx)->block) - (ctx)->index;       \
+       if ((length) < __md_left)                                       \
+         {                                                             \
+           memcpy((ctx)->block + (ctx)->index, (data), (length));      \
+           (ctx)->index += (length);                                   \
+           goto __md_done; /* Finished */                              \
+         }                                                             \
+       else                                                            \
+         {                                                             \
+           memcpy((ctx)->block + (ctx)->index, (data), __md_left);     \
+                                                                       \
+           f((ctx), (ctx)->block);                                     \
+           (incr);                                                     \
+                                                                       \
+           (data) += __md_left;                                        \
+           (length) -= __md_left;                                      \
+         }                                                             \
+      }                                                                        \
+    while ((length) >= sizeof((ctx)->block))                           \
+      {                                                                        \
+       f((ctx), (data));                                               \
+       (incr);                                                         \
+                                                                       \
+       (data) += sizeof((ctx)->block);                                 \
+       (length) -= sizeof((ctx)->block);                               \
+      }                                                                        \
+    memcpy ((ctx)->block, (data), (length));                           \
+    (ctx)->index = (length);                                           \
+  __md_done:                                                           \
+    ;                                                                  \
+  } while (0)
+
+/* Pads the block to a block boundary with the bit pattern 1 0*,
+   leaving size octets for the length field at the end. If needed,
+   compresses the block and starts a new one. */
+#define MD_PAD(ctx, size, f)                                           \
+  do {                                                                 \
+    unsigned __md_i;                                                   \
+    __md_i = (ctx)->index;                                             \
+                                                                       \
+    /* Set the first char of padding to 0x80. This is safe since there \
+       is always at least one byte free */                             \
+                                                                       \
+    assert(__md_i < sizeof((ctx)->block));                                     \
+    (ctx)->block[__md_i++] = 0x80;                                             \
+                                                                       \
+    if (__md_i > (sizeof((ctx)->block) - 2*sizeof((ctx)->count_low)))  \
+      { /* No room for length in this block. Process it and            \
+          pad with another one */                                      \
+       memset((ctx)->block + __md_i, 0, sizeof((ctx)->block) - __md_i); \
+                                                                       \
+       f((ctx), (ctx)->block);                                         \
+       __md_i = 0;                                                     \
+      }                                                                        \
+    memset((ctx)->block + __md_i, 0,                                   \
+          sizeof((ctx)->block) - (size) - __md_i);                     \
+                                                                       \
+  } while (0)
+
+#endif /* NETTLE_MACROS_H_INCLUDED */
diff --git a/md2-meta.c b/md2-meta.c
new file mode 100644 (file)
index 0000000..0ed0b47
--- /dev/null
@@ -0,0 +1,32 @@
+/* md2-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "md2.h"
+
+const struct nettle_hash nettle_md2
+= _NETTLE_HASH(md2, MD2);
diff --git a/md2.c b/md2.c
new file mode 100644 (file)
index 0000000..ba3e102
--- /dev/null
+++ b/md2.c
@@ -0,0 +1,131 @@
+/* md2.h
+ *
+ * The MD2 hash function, described in RFC 1319.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2003 Niels Möller, Andreas Sigfridsson
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* This code originates from the Python Cryptography Toolkit, version 1.0.1.
+   Further hacked by Andreas Sigfridsson and Niels Möller. Original license:
+
+   ===================================================================
+   Distribute and use freely; there are no restrictions on further
+   dissemination and usage except those imposed by the laws of your
+   country of residence.  This software is provided "as is" without
+   warranty of fitness for use or suitability for any purpose, express
+   or implied. Use at your own risk or not at all.
+   ===================================================================
+   
+   Incorporating the code into commercial products is permitted; you do
+   not have to make source available or contribute your changes back
+   (though that would be nice).
+   
+   --amk                                                    (www.amk.ca) */
+   
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <string.h>
+
+#include "md2.h"
+
+#include "macros.h"
+
+static const uint8_t
+S[256] = {
+  41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
+  19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
+  76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
+  138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
+  245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
+  148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
+  39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
+  181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
+  150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
+  112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
+  96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
+  85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
+  234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
+  129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
+  8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
+  203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
+  166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
+  31, 26, 219, 153, 141, 51, 159, 17, 131, 20
+};
+
+static void
+md2_transform(struct md2_ctx *ctx, const uint8_t *data)
+{
+  unsigned i;
+  uint8_t t;
+  
+  memcpy(ctx->X + 16, data, MD2_DATA_SIZE);
+
+  for (i = 0, t = ctx->C[15];
+       i<MD2_DATA_SIZE; i++)
+    {
+      ctx->X[2 * MD2_DATA_SIZE + i]
+       = ctx->X[i] ^ ctx->X[MD2_DATA_SIZE + i];
+      t = (ctx->C[i] ^= S[data[i]^t]);
+    }
+  for (i = t = 0;
+       i< MD2_DATA_SIZE + 2;
+       t = (t + i) & 0xff, i++)
+    {
+      unsigned j;
+      for (j = 0; j < 3 * MD2_DATA_SIZE; j++)
+       t = (ctx->X[j] ^= S[t]);
+    }
+}
+
+void
+md2_init(struct md2_ctx *ctx)
+{
+  memset(ctx, 0, sizeof(*ctx));
+}
+
+void
+md2_update(struct md2_ctx *ctx,
+          unsigned length,
+          const uint8_t *data)
+{
+  MD_UPDATE(ctx, length, data, md2_transform, (void)0);
+}
+
+void
+md2_digest(struct md2_ctx *ctx,
+          unsigned length,
+          uint8_t *digest)
+{
+  unsigned left;
+  
+  assert(length <= MD2_DIGEST_SIZE);
+
+  left = MD2_DATA_SIZE - ctx->index;
+  memset(ctx->block + ctx->index, left, left);
+  md2_transform(ctx, ctx->block);
+  
+  md2_transform(ctx, ctx->C);
+  memcpy(digest, ctx->X, length);
+  md2_init(ctx);
+}
diff --git a/md2.h b/md2.h
new file mode 100644 (file)
index 0000000..ac1cf33
--- /dev/null
+++ b/md2.h
@@ -0,0 +1,69 @@
+/* md2.h
+ *
+ * The MD2 hash function, described in RFC 1319.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_MD2_H_INCLUDED
+#define NETTLE_MD2_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define md2_init nettle_md2_init
+#define md2_update nettle_md2_update
+#define md2_digest nettle_md2_digest
+
+#define MD2_DIGEST_SIZE 16
+#define MD2_DATA_SIZE 16
+
+struct md2_ctx
+{
+  uint8_t C[MD2_DATA_SIZE];
+  uint8_t X[3 * MD2_DATA_SIZE];
+  uint8_t block[MD2_DATA_SIZE]; /* Block buffer */
+  unsigned index;               /* Into buffer */
+};
+
+void
+md2_init(struct md2_ctx *ctx);
+
+void
+md2_update(struct md2_ctx *ctx,
+          unsigned length,
+          const uint8_t *data);
+
+void
+md2_digest(struct md2_ctx *ctx,
+          unsigned length,
+          uint8_t *digest);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_MD2_H_INCLUDED */
diff --git a/md4-meta.c b/md4-meta.c
new file mode 100644 (file)
index 0000000..2d74f79
--- /dev/null
@@ -0,0 +1,32 @@
+/* md4-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "md4.h"
+
+const struct nettle_hash nettle_md4
+= _NETTLE_HASH(md4, MD4);
diff --git a/md4.c b/md4.c
new file mode 100644 (file)
index 0000000..4387b3e
--- /dev/null
+++ b/md4.c
@@ -0,0 +1,188 @@
+/* md4.h
+ *
+ * The MD4 hash function, described in RFC 1320.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2003 Niels Möller, Marcus Comstedt
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* Based on the public domain md5 code, and modified by Marcus
+   Comstedt */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <string.h>
+
+#include "md4.h"
+
+#include "macros.h"
+#include "nettle-write.h"
+
+/* A block, treated as a sequence of 32-bit words. */
+#define MD4_DATA_LENGTH 16
+
+static void
+md4_transform(uint32_t *digest, const uint32_t *data);
+
+static void
+md4_compress(struct md4_ctx *ctx, const uint8_t *block);
+
+/* FIXME: Could be an alias for md5_init */
+void
+md4_init(struct md4_ctx *ctx)
+{
+  /* Same constants as for md5. */
+  const uint32_t iv[_MD4_DIGEST_LENGTH] =
+    {
+      0x67452301,
+      0xefcdab89,
+      0x98badcfe,
+      0x10325476,
+    };
+  memcpy(ctx->state, iv, sizeof(ctx->state));
+  
+  ctx->count_low = ctx->count_high = 0;
+  ctx->index = 0;
+}
+
+void
+md4_update(struct md4_ctx *ctx,
+          unsigned length,
+          const uint8_t *data)
+{
+  MD_UPDATE(ctx, length, data, md4_compress, MD_INCR(ctx));
+}
+
+void
+md4_digest(struct md4_ctx *ctx,
+          unsigned length,
+          uint8_t *digest)
+{
+  uint32_t data[MD4_DATA_LENGTH];
+  unsigned i;
+
+  assert(length <= MD4_DIGEST_SIZE);
+
+  MD_PAD(ctx, 8, md4_compress);
+  for (i = 0; i < MD4_DATA_LENGTH - 2; i++)
+    data[i] = LE_READ_UINT32(ctx->block + 4*i);
+
+  /* There are 512 = 2^9 bits in one block 
+   * Little-endian order => Least significant word first */
+
+  data[MD4_DATA_LENGTH-1] = (ctx->count_high << 9) | (ctx->count_low >> 23);
+  data[MD4_DATA_LENGTH-2] = (ctx->count_low << 9) | (ctx->index << 3);
+  md4_transform(ctx->state, data);
+
+  _nettle_write_le32(length, digest, ctx->state);
+  md4_init(ctx);
+}
+
+/* MD4 functions */
+#define F(x, y, z) (((y) & (x)) | ((z) & ~(x)))
+#define G(x, y, z) (((y) & (x)) | ((z) & (x)) | ((y) & (z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+
+#define ROUND(f, w, x, y, z, data, s) \
+( w += f(x, y, z) + data,  w = w<<s | w>>(32-s) )
+
+/* Perform the MD4 transformation on one full block of 16 32-bit words. */
+   
+static void
+md4_transform(uint32_t *digest, const uint32_t *data)
+{
+  uint32_t a, b, c, d;
+  a = digest[0];
+  b = digest[1];
+  c = digest[2];
+  d = digest[3];
+
+  ROUND(F, a, b, c, d, data[ 0], 3);
+  ROUND(F, d, a, b, c, data[ 1], 7);
+  ROUND(F, c, d, a, b, data[ 2], 11);
+  ROUND(F, b, c, d, a, data[ 3], 19);
+  ROUND(F, a, b, c, d, data[ 4], 3);
+  ROUND(F, d, a, b, c, data[ 5], 7);
+  ROUND(F, c, d, a, b, data[ 6], 11);
+  ROUND(F, b, c, d, a, data[ 7], 19);
+  ROUND(F, a, b, c, d, data[ 8], 3);
+  ROUND(F, d, a, b, c, data[ 9], 7);
+  ROUND(F, c, d, a, b, data[10], 11);
+  ROUND(F, b, c, d, a, data[11], 19);
+  ROUND(F, a, b, c, d, data[12], 3);
+  ROUND(F, d, a, b, c, data[13], 7);
+  ROUND(F, c, d, a, b, data[14], 11);
+  ROUND(F, b, c, d, a, data[15], 19);
+
+  ROUND(G, a, b, c, d, data[ 0] + 0x5a827999, 3);
+  ROUND(G, d, a, b, c, data[ 4] + 0x5a827999, 5);
+  ROUND(G, c, d, a, b, data[ 8] + 0x5a827999, 9);
+  ROUND(G, b, c, d, a, data[12] + 0x5a827999, 13);
+  ROUND(G, a, b, c, d, data[ 1] + 0x5a827999, 3);
+  ROUND(G, d, a, b, c, data[ 5] + 0x5a827999, 5);
+  ROUND(G, c, d, a, b, data[ 9] + 0x5a827999, 9);
+  ROUND(G, b, c, d, a, data[13] + 0x5a827999, 13);
+  ROUND(G, a, b, c, d, data[ 2] + 0x5a827999, 3);
+  ROUND(G, d, a, b, c, data[ 6] + 0x5a827999, 5);
+  ROUND(G, c, d, a, b, data[10] + 0x5a827999, 9);
+  ROUND(G, b, c, d, a, data[14] + 0x5a827999, 13);
+  ROUND(G, a, b, c, d, data[ 3] + 0x5a827999, 3);
+  ROUND(G, d, a, b, c, data[ 7] + 0x5a827999, 5);
+  ROUND(G, c, d, a, b, data[11] + 0x5a827999, 9);
+  ROUND(G, b, c, d, a, data[15] + 0x5a827999, 13);
+
+  ROUND(H, a, b, c, d, data[ 0] + 0x6ed9eba1, 3);
+  ROUND(H, d, a, b, c, data[ 8] + 0x6ed9eba1, 9);
+  ROUND(H, c, d, a, b, data[ 4] + 0x6ed9eba1, 11);
+  ROUND(H, b, c, d, a, data[12] + 0x6ed9eba1, 15);
+  ROUND(H, a, b, c, d, data[ 2] + 0x6ed9eba1, 3);
+  ROUND(H, d, a, b, c, data[10] + 0x6ed9eba1, 9);
+  ROUND(H, c, d, a, b, data[ 6] + 0x6ed9eba1, 11);
+  ROUND(H, b, c, d, a, data[14] + 0x6ed9eba1, 15);
+  ROUND(H, a, b, c, d, data[ 1] + 0x6ed9eba1, 3);
+  ROUND(H, d, a, b, c, data[ 9] + 0x6ed9eba1, 9);
+  ROUND(H, c, d, a, b, data[ 5] + 0x6ed9eba1, 11);
+  ROUND(H, b, c, d, a, data[13] + 0x6ed9eba1, 15);
+  ROUND(H, a, b, c, d, data[ 3] + 0x6ed9eba1, 3);
+  ROUND(H, d, a, b, c, data[11] + 0x6ed9eba1, 9);
+  ROUND(H, c, d, a, b, data[ 7] + 0x6ed9eba1, 11);
+  ROUND(H, b, c, d, a, data[15] + 0x6ed9eba1, 15);
+
+  digest[0] += a;
+  digest[1] += b;
+  digest[2] += c;
+  digest[3] += d;
+}
+
+static void
+md4_compress(struct md4_ctx *ctx, const uint8_t *block)
+{
+  uint32_t data[MD4_DATA_LENGTH];
+  unsigned i;
+  
+  /* Endian independent conversion */
+  for (i = 0; i<16; i++, block += 4)
+    data[i] = LE_READ_UINT32(block);
+
+  md4_transform(ctx->state, data);
+}
diff --git a/md4.h b/md4.h
new file mode 100644 (file)
index 0000000..c0627e9
--- /dev/null
+++ b/md4.h
@@ -0,0 +1,73 @@
+/* md4.h
+ *
+ * The MD4 hash function, described in RFC 1320.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_MD4_H_INCLUDED
+#define NETTLE_MD4_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define md4_init nettle_md4_init
+#define md4_update nettle_md4_update
+#define md4_digest nettle_md4_digest
+
+#define MD4_DIGEST_SIZE 16
+#define MD4_DATA_SIZE 64
+
+/* Digest is kept internally as 4 32-bit words. */
+#define _MD4_DIGEST_LENGTH 4
+
+/* FIXME: Identical to md5_ctx */
+struct md4_ctx
+{
+  uint32_t state[_MD4_DIGEST_LENGTH];
+  uint32_t count_low, count_high;      /* Block count */
+  uint8_t block[MD4_DATA_SIZE];                /* Block buffer */
+  unsigned index;                      /* Into buffer */
+};
+
+void
+md4_init(struct md4_ctx *ctx);
+
+void
+md4_update(struct md4_ctx *ctx,
+          unsigned length,
+          const uint8_t *data);
+
+void
+md4_digest(struct md4_ctx *ctx,
+          unsigned length,
+          uint8_t *digest);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_MD4_H_INCLUDED */
diff --git a/md5-compat.c b/md5-compat.c
new file mode 100644 (file)
index 0000000..31a2fd5
--- /dev/null
@@ -0,0 +1,48 @@
+/* md5-compat.c
+ *
+ * The md5 hash function, RFC 1321-style interface.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "md5-compat.h"
+
+void
+MD5Init(MD5_CTX *ctx)
+{
+  md5_init(ctx);
+}
+
+void
+MD5Update(MD5_CTX *ctx, const unsigned char *data, unsigned int length)
+{
+  md5_update(ctx, length, data);
+}
+
+void
+MD5Final(unsigned char *out, MD5_CTX *ctx)
+{
+  md5_digest(ctx, MD5_DIGEST_SIZE, out);
+}
diff --git a/md5-compat.h b/md5-compat.h
new file mode 100644 (file)
index 0000000..8f5f331
--- /dev/null
@@ -0,0 +1,50 @@
+/* md5-compat.h
+ *
+ * The md5 hash function, RFC 1321-style interface.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_MD5_COMPAT_H_INCLUDED
+#define NETTLE_MD5_COMPAT_H_INCLUDED
+
+#include "md5.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define MD5Init nettle_MD5Init
+#define MD5Update nettle_MD5Update
+#define MD5Final nettle_MD5Final
+
+typedef struct md5_ctx MD5_CTX;
+
+void MD5Init(MD5_CTX *ctx);
+void MD5Update(MD5_CTX *ctx, const unsigned char *data, unsigned int length);
+void MD5Final(unsigned char *out, MD5_CTX *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_MD5_COMPAT_H_INCLUDED */
diff --git a/md5-compress.c b/md5-compress.c
new file mode 100644 (file)
index 0000000..ec949e7
--- /dev/null
@@ -0,0 +1,167 @@
+/* md5-compress.c
+ *
+ * The compression function for the sha1 hash function.
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2005 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* Based on public domain code hacked by Colin Plumb, Andrew Kuchling, and
+ * Niels Möller. */
+
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifndef MD5_DEBUG
+# define MD5_DEBUG 0
+#endif
+
+#if MD5_DEBUG
+# include <stdio.h>
+# define DEBUG(i) \
+  fprintf(stderr, "%2d: %8x %8x %8x %8x\n", i, a, b, c, d)
+#else
+# define DEBUG(i)
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "md5.h"
+
+#include "macros.h"
+
+/* A block, treated as a sequence of 32-bit words. */
+#define MD5_DATA_LENGTH 16
+
+/* MD5 functions */
+
+#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
+#define F2(x, y, z) F1((z), (x), (y))
+#define F3(x, y, z) ((x) ^ (y) ^ (z))
+#define F4(x, y, z) ((y) ^ ((x) | ~(z)))
+
+#define ROUND(f, w, x, y, z, data, s) \
+( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
+
+/* Perform the MD5 transformation on one full block of 16 32-bit
+ * words.
+ *
+ * Compresses 20 (_MD5_DIGEST_LENGTH + MD5_DATA_LENGTH) words into 4
+ * (_MD5_DIGEST_LENGTH) words. */
+
+void
+_nettle_md5_compress(uint32_t *digest, const uint8_t *input)
+{
+  uint32_t data[MD5_DATA_LENGTH];
+  uint32_t a, b, c, d;
+  unsigned i;
+
+  for (i = 0; i < MD5_DATA_LENGTH; i++, input += 4)
+    data[i] = LE_READ_UINT32(input);
+
+  a = digest[0];
+  b = digest[1];
+  c = digest[2];
+  d = digest[3];
+
+  DEBUG(-1);
+  ROUND(F1, a, b, c, d, data[ 0] + 0xd76aa478, 7); DEBUG(0);
+  ROUND(F1, d, a, b, c, data[ 1] + 0xe8c7b756, 12); DEBUG(1);
+  ROUND(F1, c, d, a, b, data[ 2] + 0x242070db, 17);
+  ROUND(F1, b, c, d, a, data[ 3] + 0xc1bdceee, 22);
+  ROUND(F1, a, b, c, d, data[ 4] + 0xf57c0faf, 7);
+  ROUND(F1, d, a, b, c, data[ 5] + 0x4787c62a, 12);
+  ROUND(F1, c, d, a, b, data[ 6] + 0xa8304613, 17);
+  ROUND(F1, b, c, d, a, data[ 7] + 0xfd469501, 22);
+  ROUND(F1, a, b, c, d, data[ 8] + 0x698098d8, 7);
+  ROUND(F1, d, a, b, c, data[ 9] + 0x8b44f7af, 12);
+  ROUND(F1, c, d, a, b, data[10] + 0xffff5bb1, 17);
+  ROUND(F1, b, c, d, a, data[11] + 0x895cd7be, 22);
+  ROUND(F1, a, b, c, d, data[12] + 0x6b901122, 7);
+  ROUND(F1, d, a, b, c, data[13] + 0xfd987193, 12);
+  ROUND(F1, c, d, a, b, data[14] + 0xa679438e, 17);
+  ROUND(F1, b, c, d, a, data[15] + 0x49b40821, 22); DEBUG(15);
+
+  ROUND(F2, a, b, c, d, data[ 1] + 0xf61e2562, 5); DEBUG(16);
+  ROUND(F2, d, a, b, c, data[ 6] + 0xc040b340, 9); DEBUG(17);
+  ROUND(F2, c, d, a, b, data[11] + 0x265e5a51, 14);
+  ROUND(F2, b, c, d, a, data[ 0] + 0xe9b6c7aa, 20);
+  ROUND(F2, a, b, c, d, data[ 5] + 0xd62f105d, 5);
+  ROUND(F2, d, a, b, c, data[10] + 0x02441453, 9);
+  ROUND(F2, c, d, a, b, data[15] + 0xd8a1e681, 14);
+  ROUND(F2, b, c, d, a, data[ 4] + 0xe7d3fbc8, 20);
+  ROUND(F2, a, b, c, d, data[ 9] + 0x21e1cde6, 5);
+  ROUND(F2, d, a, b, c, data[14] + 0xc33707d6, 9);
+  ROUND(F2, c, d, a, b, data[ 3] + 0xf4d50d87, 14);
+  ROUND(F2, b, c, d, a, data[ 8] + 0x455a14ed, 20);
+  ROUND(F2, a, b, c, d, data[13] + 0xa9e3e905, 5);
+  ROUND(F2, d, a, b, c, data[ 2] + 0xfcefa3f8, 9);
+  ROUND(F2, c, d, a, b, data[ 7] + 0x676f02d9, 14);
+  ROUND(F2, b, c, d, a, data[12] + 0x8d2a4c8a, 20); DEBUG(31);
+
+  ROUND(F3, a, b, c, d, data[ 5] + 0xfffa3942, 4); DEBUG(32);
+  ROUND(F3, d, a, b, c, data[ 8] + 0x8771f681, 11); DEBUG(33);
+  ROUND(F3, c, d, a, b, data[11] + 0x6d9d6122, 16);
+  ROUND(F3, b, c, d, a, data[14] + 0xfde5380c, 23);
+  ROUND(F3, a, b, c, d, data[ 1] + 0xa4beea44, 4);
+  ROUND(F3, d, a, b, c, data[ 4] + 0x4bdecfa9, 11);
+  ROUND(F3, c, d, a, b, data[ 7] + 0xf6bb4b60, 16);
+  ROUND(F3, b, c, d, a, data[10] + 0xbebfbc70, 23);
+  ROUND(F3, a, b, c, d, data[13] + 0x289b7ec6, 4);
+  ROUND(F3, d, a, b, c, data[ 0] + 0xeaa127fa, 11);
+  ROUND(F3, c, d, a, b, data[ 3] + 0xd4ef3085, 16);
+  ROUND(F3, b, c, d, a, data[ 6] + 0x04881d05, 23);
+  ROUND(F3, a, b, c, d, data[ 9] + 0xd9d4d039, 4);
+  ROUND(F3, d, a, b, c, data[12] + 0xe6db99e5, 11);
+  ROUND(F3, c, d, a, b, data[15] + 0x1fa27cf8, 16);
+  ROUND(F3, b, c, d, a, data[ 2] + 0xc4ac5665, 23); DEBUG(47);
+
+  ROUND(F4, a, b, c, d, data[ 0] + 0xf4292244, 6); DEBUG(48);
+  ROUND(F4, d, a, b, c, data[ 7] + 0x432aff97, 10); DEBUG(49);
+  ROUND(F4, c, d, a, b, data[14] + 0xab9423a7, 15);
+  ROUND(F4, b, c, d, a, data[ 5] + 0xfc93a039, 21);
+  ROUND(F4, a, b, c, d, data[12] + 0x655b59c3, 6);
+  ROUND(F4, d, a, b, c, data[ 3] + 0x8f0ccc92, 10);
+  ROUND(F4, c, d, a, b, data[10] + 0xffeff47d, 15);
+  ROUND(F4, b, c, d, a, data[ 1] + 0x85845dd1, 21);
+  ROUND(F4, a, b, c, d, data[ 8] + 0x6fa87e4f, 6);
+  ROUND(F4, d, a, b, c, data[15] + 0xfe2ce6e0, 10);
+  ROUND(F4, c, d, a, b, data[ 6] + 0xa3014314, 15);
+  ROUND(F4, b, c, d, a, data[13] + 0x4e0811a1, 21);
+  ROUND(F4, a, b, c, d, data[ 4] + 0xf7537e82, 6);
+  ROUND(F4, d, a, b, c, data[11] + 0xbd3af235, 10);
+  ROUND(F4, c, d, a, b, data[ 2] + 0x2ad7d2bb, 15);
+  ROUND(F4, b, c, d, a, data[ 9] + 0xeb86d391, 21); DEBUG(63);
+
+  digest[0] += a;
+  digest[1] += b;
+  digest[2] += c;
+  digest[3] += d;
+#if MD5_DEBUG
+  fprintf(stderr, "99: %8x %8x %8x %8x\n",
+         digest[0], digest[1], digest[2], digest[3]);
+#endif
+  
+}
diff --git a/md5-meta.c b/md5-meta.c
new file mode 100644 (file)
index 0000000..3ea5900
--- /dev/null
@@ -0,0 +1,32 @@
+/* md5-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "md5.h"
+
+const struct nettle_hash nettle_md5
+= _NETTLE_HASH(md5, MD5);
diff --git a/md5.c b/md5.c
new file mode 100644 (file)
index 0000000..48c1a35
--- /dev/null
+++ b/md5.c
@@ -0,0 +1,87 @@
+/* md5.c
+ *
+ * The MD5 hash function, described in RFC 1321.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* Based on public domain code hacked by Colin Plumb, Andrew Kuchling, and
+ * Niels Möller. */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <string.h>
+
+#include "md5.h"
+
+#include "macros.h"
+#include "nettle-write.h"
+
+void
+md5_init(struct md5_ctx *ctx)
+{
+  const uint32_t iv[_MD5_DIGEST_LENGTH] =
+    {
+      0x67452301,
+      0xefcdab89,
+      0x98badcfe,
+      0x10325476,
+    };
+  memcpy(ctx->state, iv, sizeof(ctx->state));
+  ctx->count_low = ctx->count_high = 0;
+  ctx->index = 0;
+}
+
+#define COMPRESS(ctx, data) (_nettle_md5_compress((ctx)->state, (data)))
+
+void
+md5_update(struct md5_ctx *ctx,
+          unsigned length,
+          const uint8_t *data)
+{
+  MD_UPDATE(ctx, length, data, COMPRESS, MD_INCR(ctx));
+}
+
+void
+md5_digest(struct md5_ctx *ctx,
+          unsigned length,
+          uint8_t *digest)
+{
+  uint32_t high, low;
+  
+  assert(length <= MD5_DIGEST_SIZE);
+
+  MD_PAD(ctx, 8, COMPRESS);
+
+  /* There are 512 = 2^9 bits in one block */  
+  high = (ctx->count_high << 9) | (ctx->count_low >> 23);
+  low = (ctx->count_low << 9) | (ctx->index << 3);
+
+  LE_WRITE_UINT32(ctx->block + (MD5_DATA_SIZE - 8), low);
+  LE_WRITE_UINT32(ctx->block + (MD5_DATA_SIZE - 4), high);
+  _nettle_md5_compress(ctx->state, ctx->block);
+
+  _nettle_write_le32(length, digest, ctx->state);
+  md5_init(ctx);
+}
diff --git a/md5.h b/md5.h
new file mode 100644 (file)
index 0000000..269152d
--- /dev/null
+++ b/md5.h
@@ -0,0 +1,76 @@
+/* md5.h
+ *
+ * The MD5 hash function, described in RFC 1321.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_MD5_H_INCLUDED
+#define NETTLE_MD5_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define md5_init nettle_md5_init
+#define md5_update nettle_md5_update
+#define md5_digest nettle_md5_digest
+
+#define MD5_DIGEST_SIZE 16
+#define MD5_DATA_SIZE 64
+
+/* Digest is kept internally as 4 32-bit words. */
+#define _MD5_DIGEST_LENGTH 4
+
+struct md5_ctx
+{
+  uint32_t state[_MD5_DIGEST_LENGTH];
+  uint32_t count_low, count_high; /* Block count */
+  uint8_t block[MD5_DATA_SIZE]; /* Block buffer */
+  unsigned index;               /* Into buffer */
+};
+
+void
+md5_init(struct md5_ctx *ctx);
+
+void
+md5_update(struct md5_ctx *ctx,
+          unsigned length,
+          const uint8_t *data);
+
+void
+md5_digest(struct md5_ctx *ctx,
+          unsigned length,
+          uint8_t *digest);
+
+/* Internal compression function. STATE points to 4 uint32_t words,
+   and DATA points to 64 bytes of input data, possibly unaligned. */
+void
+_nettle_md5_compress(uint32_t *state, const uint8_t *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_MD5_H_INCLUDED */
diff --git a/memxor.c b/memxor.c
new file mode 100644 (file)
index 0000000..5e10c3d
--- /dev/null
+++ b/memxor.c
@@ -0,0 +1,324 @@
+/* memxor.c
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc.
+ * Copyright (C) 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* Implementation inspired by memcmp in glibc, contributed to the FSF
+   by Torbjorn Granlund.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <limits.h>
+
+#include "memxor.h"
+
+typedef unsigned long int word_t;
+
+#if SIZEOF_LONG & (SIZEOF_LONG - 1)
+#error Word size must be a power of two
+#endif
+
+#define ALIGN_OFFSET(p) ((uintptr_t) (p) % sizeof(word_t))
+
+#ifndef WORDS_BIGENDIAN
+#define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
+#else
+#define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2)))
+#endif
+
+#define WORD_T_THRESH 16
+
+/* XOR word-aligned areas. n is the number of words, not bytes. */
+static void
+memxor_common_alignment (word_t *dst, const word_t *src, size_t n)
+{
+  /* FIXME: Require n > 0? */
+  /* FIXME: Unroll four times, like memcmp? Probably not worth the
+     effort. */
+
+  if (n & 1)
+    {
+      *dst++ ^= *src++;
+      n--;
+    }
+  for (; n >= 2; dst += 2, src += 2, n -= 2)
+    {
+      dst[0] ^= src[0];
+      dst[1] ^= src[1];
+    }
+}
+
+/* XOR *un-aligned* src-area onto aligned dst area. n is number of
+   words, not bytes. Assumes we can read complete words at the start
+   and end of the src operand. */
+static void
+memxor_different_alignment (word_t *dst, const uint8_t *src, size_t n)
+{
+  size_t i;
+  int shl, shr;
+  const word_t *src_word;
+  unsigned offset = ALIGN_OFFSET (src);
+  word_t s0, s1;
+
+  shl = CHAR_BIT * offset;
+  shr = CHAR_BIT * (sizeof(word_t) - offset);
+
+  src_word = (const word_t *) ((uintptr_t) src & -SIZEOF_LONG);
+
+  /* FIXME: Unroll four times, like memcmp? */
+  i = n & 1;
+  s0 = src_word[i];
+  if (i)
+    {
+      s1 = src_word[0];
+      dst[0] ^= MERGE (s1, shl, s0, shr);
+    }
+
+  for (; i < n; i += 2)
+    {
+      s1 = src_word[i+1];
+      dst[i] ^= MERGE(s0, shl, s1, shr);
+      s0 = src_word[i+2];
+      dst[i+1] ^= MERGE(s1, shl, s0, shr);
+    }
+}
+
+/* Performance, Intel SU1400 (x86_64): 0.25 cycles/byte aligned, 0.45
+   cycles/byte unaligned. */
+
+/* XOR LEN bytes starting at SRCADDR onto DESTADDR. Result undefined
+   if the source overlaps with the destination. Return DESTADDR. */
+uint8_t *
+memxor(uint8_t *dst, const uint8_t *src, size_t n)
+{
+  uint8_t *orig_dst = dst;
+
+  if (n >= WORD_T_THRESH)
+    {
+      /* There are at least some bytes to compare.  No need to test
+        for N == 0 in this alignment loop.  */
+      while (ALIGN_OFFSET (dst))
+       {
+         *dst++ ^= *src++;
+         n--;
+       }
+      if (ALIGN_OFFSET (src))
+       memxor_different_alignment ((word_t *) dst, src, n / sizeof(word_t));
+      else
+       memxor_common_alignment ((word_t *) dst, (const word_t *) src, n / sizeof(word_t));
+
+      dst += n & -SIZEOF_LONG;
+      src += n & -SIZEOF_LONG;
+      n = n & (SIZEOF_LONG - 1);
+    }
+  for (; n > 0; n--)
+    *dst++ ^= *src++;
+
+  return orig_dst;
+}
+
+
+/* XOR word-aligned areas. n is the number of words, not bytes. */
+static void
+memxor3_common_alignment (word_t *dst,
+                         const word_t *a, const word_t *b, size_t n)
+{
+  /* FIXME: Require n > 0? */
+  while (n-- > 0)
+    dst[n] = a[n] ^ b[n];
+}
+
+static void
+memxor3_different_alignment_b (word_t *dst,
+                              const word_t *a, const uint8_t *b, unsigned offset, size_t n)
+{
+  int shl, shr;
+  const word_t *b_word;
+
+  word_t s0, s1;
+
+  shl = CHAR_BIT * offset;
+  shr = CHAR_BIT * (sizeof(word_t) - offset);
+
+  b_word = (const word_t *) ((uintptr_t) b & -SIZEOF_LONG);
+
+  if (n & 1)
+    {
+      n--;
+      s1 = b_word[n];
+      s0 = b_word[n+1];
+      dst[n] = a[n] ^ MERGE (s1, shl, s0, shr);
+    }
+  else
+    s1 = b_word[n];
+  
+  while (n > 0)
+    {
+      n -= 2;
+      s0 = b_word[n+1]; 
+      dst[n+1] = a[n+1] ^ MERGE(s0, shl, s1, shr);
+      s1 = b_word[n];
+      dst[n] = a[n] ^ MERGE(s1, shl, s0, shr);
+    }
+}
+
+static void
+memxor3_different_alignment_ab (word_t *dst,
+                               const uint8_t *a, const uint8_t *b,
+                               unsigned offset, size_t n)
+{
+  int shl, shr;
+  const word_t *a_word;
+  const word_t *b_word;
+  
+  word_t s0, s1;
+
+  shl = CHAR_BIT * offset;
+  shr = CHAR_BIT * (sizeof(word_t) - offset);
+
+  a_word = (const word_t *) ((uintptr_t) a & -SIZEOF_LONG);
+  b_word = (const word_t *) ((uintptr_t) b & -SIZEOF_LONG);
+
+  if (n & 1)
+    {
+      n--;
+      s1 = a_word[n] ^ b_word[n];
+      s0 = a_word[n+1] ^ b_word[n+1];
+      dst[n] = MERGE (s1, shl, s0, shr);
+    }
+  else    
+    s1 = a_word[n] ^ b_word[n];
+  
+  while (n > 0)
+    {
+      n -= 2;
+      s0 = a_word[n+1] ^ b_word[n+1]; 
+      dst[n+1] = MERGE(s0, shl, s1, shr);
+      s1 = a_word[n] ^ b_word[n];
+      dst[n] = MERGE(s1, shl, s0, shr);
+    }
+}
+
+static void
+memxor3_different_alignment_all (word_t *dst,
+                                const uint8_t *a, const uint8_t *b,
+                                unsigned a_offset, unsigned b_offset,
+                                size_t n)
+{
+  int al, ar, bl, br;
+  const word_t *a_word;
+  const word_t *b_word;
+  
+  word_t a0, a1, b0, b1;
+
+  al = CHAR_BIT * a_offset;
+  ar = CHAR_BIT * (sizeof(word_t) - a_offset);
+  bl = CHAR_BIT * b_offset;
+  br = CHAR_BIT * (sizeof(word_t) - b_offset);
+
+  a_word = (const word_t *) ((uintptr_t) a & -SIZEOF_LONG);
+  b_word = (const word_t *) ((uintptr_t) b & -SIZEOF_LONG);
+
+  if (n & 1)
+    {
+      n--;
+      a1 = a_word[n]; a0 = a_word[n+1];
+      b1 = b_word[n]; b0 = b_word[n+1];
+      
+      dst[n] = MERGE (a1, al, a0, ar) ^ MERGE (b1, bl, b0, br);
+    }
+  else    
+    {
+      a1 = a_word[n];
+      b1 = b_word[n];
+    }
+  
+  while (n > 0)
+    {
+      n -= 2;
+      a0 = a_word[n+1]; b0 = b_word[n+1]; 
+      dst[n+1] = MERGE(a0, al, a1, ar) ^ MERGE(b0, bl, b1, br);
+      a1 = a_word[n]; b1 = b_word[n];
+      dst[n] = MERGE(a1, al, a0, ar) ^ MERGE(b1, bl, b0, br);
+    }
+}
+
+/* Current implementation processes data in descending order, to
+   support overlapping operation with one of the sources overlapping
+   the start of the destination area. This feature is used only
+   internally by cbc decrypt, and it is not advertised or documented
+   to nettle users. */
+uint8_t *
+memxor3(uint8_t *dst, const uint8_t *a, const uint8_t *b, size_t n)
+{
+  if (n >= WORD_T_THRESH)
+    {
+      unsigned i;
+      unsigned a_offset;
+      unsigned b_offset;
+      size_t nwords;
+
+      for (i = ALIGN_OFFSET(dst + n); i > 0; i--)
+       {
+         n--;
+         dst[n] = a[n] ^ b[n];
+       }
+
+      a_offset = ALIGN_OFFSET(a + n);
+      b_offset = ALIGN_OFFSET(b + n);
+
+      nwords = n / sizeof (word_t);
+      n %= sizeof (word_t);
+
+      if (a_offset == b_offset)
+       {
+         if (!a_offset)
+           memxor3_common_alignment((word_t *) (dst + n),
+                                    (const word_t *) (a + n),
+                                    (const word_t *) (b + n), nwords);
+         else
+           memxor3_different_alignment_ab((word_t *) (dst + n),
+                                          a + n, b + n, a_offset,
+                                          nwords);
+       }
+      else if (!a_offset)
+       memxor3_different_alignment_b((word_t *) (dst + n),
+                                     (const word_t *) (a + n), b + n,
+                                     b_offset, nwords);
+      else if (!b_offset)
+       memxor3_different_alignment_b((word_t *) (dst + n),
+                                     (const word_t *) (b + n), a + n,
+                                     a_offset, nwords);
+      else
+       memxor3_different_alignment_all((word_t *) (dst + n), a + n, b + n,
+                                       a_offset, b_offset, nwords);
+                                       
+    }
+  while (n-- > 0)
+    dst[n] = a[n] ^ b[n];
+
+  return dst;
+}
diff --git a/memxor.h b/memxor.h
new file mode 100644 (file)
index 0000000..c9e563d
--- /dev/null
+++ b/memxor.h
@@ -0,0 +1,22 @@
+/* memxor.h
+ *
+ */
+
+#ifndef NETTLE_MEMXOR_H_INCLUDED
+#define NETTLE_MEMXOR_H_INCLUDED
+
+#include <stdlib.h>
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uint8_t *memxor(uint8_t *dst, const uint8_t *src, size_t n);
+uint8_t *memxor3(uint8_t *dst, const uint8_t *a, const uint8_t *b, size_t n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_MEMXOR_H_INCLUDED */
diff --git a/nettle-internal.c b/nettle-internal.c
new file mode 100644 (file)
index 0000000..b97281a
--- /dev/null
@@ -0,0 +1,85 @@
+/* nettle-internal.c
+ *
+ * Things that are used only by the testsuite and benchmark, and
+ * subject to change.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "nettle-internal.h"
+#include "blowfish.h"
+#include "des.h"
+#include "gcm.h"
+
+/* DES uses a different signature for the key set function. We ignore
+   the return value incicating weak keys. */
+static void
+des_set_key_hack(void *ctx, unsigned length, const uint8_t *key)
+{
+  assert(length == DES_KEY_SIZE);
+  des_set_key(ctx, key);
+}
+
+static void
+des3_set_key_hack(void *ctx, unsigned length, const uint8_t *key)
+{
+  assert(length == DES3_KEY_SIZE);
+  des3_set_key(ctx, key);
+}
+
+/* NOTE: A bit ugly. Ignores weak keys, and pretends the set:key
+   functions have no return value. */
+const struct nettle_cipher
+nettle_des = {
+  "des", sizeof(struct des_ctx),
+  DES_BLOCK_SIZE, DES_KEY_SIZE,
+  des_set_key_hack, des_set_key_hack,
+  (nettle_crypt_func *) des_encrypt,
+  (nettle_crypt_func *) des_decrypt
+};
+
+const struct nettle_cipher
+nettle_des3 = {
+ "des3", sizeof(struct des3_ctx),
+ DES3_BLOCK_SIZE, DES3_KEY_SIZE,
+ des3_set_key_hack, des3_set_key_hack,
+ (nettle_crypt_func *) des3_encrypt,
+ (nettle_crypt_func *) des3_decrypt
+};
+
+/* NOTE: This is not as nice as one might think, as we pretend
+   blowfish_set_key has no return value. */
+const struct nettle_cipher
+nettle_blowfish128 = _NETTLE_CIPHER(blowfish, BLOWFISH, 128);
+
+const struct nettle_aead
+nettle_gcm_aes128 = _NETTLE_AEAD(gcm, GCM, aes, 128);
+const struct nettle_aead
+nettle_gcm_aes192 = _NETTLE_AEAD(gcm, GCM, aes, 192);
+const struct nettle_aead
+nettle_gcm_aes256 = _NETTLE_AEAD(gcm, GCM, aes, 256);
diff --git a/nettle-internal.h b/nettle-internal.h
new file mode 100644 (file)
index 0000000..b7bbe24
--- /dev/null
@@ -0,0 +1,127 @@
+/* nettle-internal.h
+ *
+ * Things that are used only by the testsuite and benchmark, and
+ * subject to change.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_INTERNAL_H_INCLUDED
+#define NETTLE_INTERNAL_H_INCLUDED
+
+#include "nettle-meta.h"
+
+/* Temporary allocation, for systems that don't support alloca. Note
+ * that the allocation requests should always be reasonably small, so
+ * that they can fit on the stack. For non-alloca systems, we use a
+ * fix maximum size, and abort if we ever need anything larger. */
+
+#if HAVE_ALLOCA
+# define TMP_DECL(name, type, max) type *name
+# define TMP_ALLOC(name, size) (name = alloca(sizeof (*name) * size))
+#else /* !HAVE_ALLOCA */
+# define TMP_DECL(name, type, max) type name[max]
+# define TMP_ALLOC(name, size) \
+do { if (size > (sizeof(name) / sizeof(name[0]))) abort(); } while (0)
+#endif 
+
+/* Arbitrary limits which apply to systems that don't have alloca */
+#define NETTLE_MAX_BIGNUM_BITS 10000
+#define NETTLE_MAX_HASH_BLOCK_SIZE 128
+#define NETTLE_MAX_HASH_DIGEST_SIZE 64
+#define NETTLE_MAX_SEXP_ASSOC 17
+#define NETTLE_MAX_CIPHER_BLOCK_SIZE 32
+
+/* Doesn't quite fit with the other algorithms, because of the weak
+ * keys. Weak keys are not reported, the functions will simply crash
+ * if you try to use a weak key. */
+
+extern const struct nettle_cipher nettle_des;
+extern const struct nettle_cipher nettle_des3;
+
+extern const struct nettle_cipher nettle_blowfish128;
+
+/* Glue to openssl, for comparative benchmarking. The corresponding
+ * code is not included in the nettle library, as that would make the
+ * shared library depend on openssl. Instead, look at
+ * examples/nettle-openssl.c. */
+extern const struct nettle_cipher nettle_openssl_aes128;
+extern const struct nettle_cipher nettle_openssl_aes192;
+extern const struct nettle_cipher nettle_openssl_aes256;
+extern const struct nettle_cipher nettle_openssl_arcfour128;
+extern const struct nettle_cipher nettle_openssl_blowfish128;
+extern const struct nettle_cipher nettle_openssl_des;
+extern const struct nettle_cipher nettle_openssl_cast128;
+
+extern const struct nettle_hash nettle_openssl_md5;
+extern const struct nettle_hash nettle_openssl_sha1;
+
+/* Tentative interface for "authenticated encryption with associated
+   data" algorithms. Should be moved to nettle-meta.h when stable. */
+struct nettle_aead
+{
+  const char *name;
+  
+  unsigned context_size;
+  /* Block size of the input, and the size of the output digest */
+  unsigned block_size;
+
+  /* Suggested key size; other sizes are sometimes possible. */
+  unsigned key_size;
+
+  nettle_set_key_func *set_key;
+  nettle_set_key_func *set_iv;
+  nettle_hash_update_func *update;
+  nettle_crypt_func *encrypt;
+  nettle_crypt_func *decrypt;
+  nettle_hash_digest_func *digest;
+};
+
+#define _NETTLE_AEAD(type, TYPE, name, key_size) {     \
+  #type "-" #name #key_size,                           \
+  sizeof(struct type##_##name##_ctx),                  \
+  TYPE##_BLOCK_SIZE,                                   \
+  key_size / 8,                                                \
+  (nettle_set_key_func *) type##_##name##_set_key,     \
+  (nettle_set_key_func *) type##_##name##_set_iv,      \
+  (nettle_hash_update_func *) type##_##name##_update,  \
+  (nettle_crypt_func *) type##_##name##_encrypt,       \
+  (nettle_crypt_func *) type##_##name##_decrypt,       \
+  (nettle_hash_digest_func *) type##_##name##_digest,  \
+}
+
+extern const struct nettle_aead nettle_gcm_aes128;
+extern const struct nettle_aead nettle_gcm_aes192;
+extern const struct nettle_aead nettle_gcm_aes256;
+
+extern const struct nettle_aead nettle_gcm_camellia128;
+extern const struct nettle_aead nettle_gcm_camellia192;
+extern const struct nettle_aead nettle_gcm_camellia256;
+
+extern const struct nettle_aead nettle_gcm_serpent128;
+extern const struct nettle_aead nettle_gcm_serpent192;
+extern const struct nettle_aead nettle_gcm_serpent256;
+
+extern const struct nettle_aead nettle_gcm_twofish128;
+extern const struct nettle_aead nettle_gcm_twofish192;
+extern const struct nettle_aead nettle_gcm_twofish256;
+
+#endif /* NETTLE_INTERNAL_H_INCLUDED */
diff --git a/nettle-meta-armors.c b/nettle-meta-armors.c
new file mode 100644 (file)
index 0000000..360006d
--- /dev/null
@@ -0,0 +1,34 @@
+/* nettle-meta-armors.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2011 Daniel Kahn Gillmor
+ * 
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stddef.h>
+#include "nettle-meta.h"
+
+const struct nettle_armor * const nettle_armors[] = {
+  &nettle_base64,
+  &nettle_base16,
+  NULL
+};
diff --git a/nettle-meta-ciphers.c b/nettle-meta-ciphers.c
new file mode 100644 (file)
index 0000000..1f07595
--- /dev/null
@@ -0,0 +1,50 @@
+/* nettle-meta-ciphers.c */
+
+/* nettle, low-level cryptographics library
+ *  
+ * Copyright (C) 2011 Daniel Kahn Gillmor
+ * 
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stddef.h>
+#include "nettle-meta.h"
+
+const struct nettle_cipher * const nettle_ciphers[] = {
+  &nettle_aes128,
+  &nettle_aes192,
+  &nettle_aes256,
+  &nettle_arcfour128,
+  &nettle_camellia128,
+  &nettle_camellia192,
+  &nettle_camellia256,
+  &nettle_cast128,
+  &nettle_serpent128,
+  &nettle_serpent192,
+  &nettle_serpent256,
+  &nettle_twofish128,
+  &nettle_twofish192,
+  &nettle_twofish256,
+  &nettle_arctwo40,
+  &nettle_arctwo64,
+  &nettle_arctwo128,
+  &nettle_arctwo_gutmann128,
+  NULL
+};
diff --git a/nettle-meta-hashes.c b/nettle-meta-hashes.c
new file mode 100644 (file)
index 0000000..0968bec
--- /dev/null
@@ -0,0 +1,41 @@
+/* nettle-meta-hashes.c */
+
+/* nettle, low-level cryptographics library
+ *  
+ * Copyright (C) 2011 Daniel Kahn Gillmor
+ * 
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stddef.h>
+#include "nettle-meta.h"
+
+const struct nettle_hash * const nettle_hashes[] = {
+  &nettle_md2,
+  &nettle_md4,
+  &nettle_md5,
+  &nettle_ripemd160,
+  &nettle_sha1,
+  &nettle_sha224,
+  &nettle_sha256,
+  &nettle_sha384,
+  &nettle_sha512,
+  NULL
+};
diff --git a/nettle-meta.h b/nettle-meta.h
new file mode 100644 (file)
index 0000000..16af7f0
--- /dev/null
@@ -0,0 +1,227 @@
+/* nettle-meta.h
+ *
+ * Information about algorithms.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_META_H_INCLUDED
+#define NETTLE_META_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct nettle_cipher
+{
+  const char *name;
+  
+  unsigned context_size;
+  
+  /* Zero for stream ciphers */
+  unsigned block_size;
+
+  /* Suggested key size; other sizes are sometimes possible. */
+  unsigned key_size;
+
+  nettle_set_key_func *set_encrypt_key;
+  nettle_set_key_func *set_decrypt_key;
+
+  nettle_crypt_func *encrypt;
+  nettle_crypt_func *decrypt;
+};
+
+#define _NETTLE_CIPHER(name, NAME, key_size) { \
+  #name #key_size,                             \
+  sizeof(struct name##_ctx),                   \
+  NAME##_BLOCK_SIZE,                           \
+  key_size / 8,                                        \
+  (nettle_set_key_func *) name##_set_key,      \
+  (nettle_set_key_func *) name##_set_key,      \
+  (nettle_crypt_func *) name##_encrypt,                \
+  (nettle_crypt_func *) name##_decrypt,                \
+}
+
+#define _NETTLE_CIPHER_SEP(name, NAME, key_size) {     \
+  #name #key_size,                                     \
+  sizeof(struct name##_ctx),                           \
+  NAME##_BLOCK_SIZE,                                   \
+  key_size / 8,                                                \
+  (nettle_set_key_func *) name##_set_encrypt_key,      \
+  (nettle_set_key_func *) name##_set_decrypt_key,      \
+  (nettle_crypt_func *) name##_encrypt,                        \
+  (nettle_crypt_func *) name##_decrypt,                        \
+}
+
+#define _NETTLE_CIPHER_SEP_SET_KEY(name, NAME, key_size) {\
+  #name #key_size,                                     \
+  sizeof(struct name##_ctx),                           \
+  NAME##_BLOCK_SIZE,                                   \
+  key_size / 8,                                                \
+  (nettle_set_key_func *) name##_set_encrypt_key,      \
+  (nettle_set_key_func *) name##_set_decrypt_key,      \
+  (nettle_crypt_func *) name##_crypt,                  \
+  (nettle_crypt_func *) name##_crypt,                  \
+}
+
+#define _NETTLE_CIPHER_FIX(name, NAME) {       \
+  #name,                                               \
+  sizeof(struct name##_ctx),                           \
+  NAME##_BLOCK_SIZE,                                   \
+  NAME##_KEY_SIZE,                                     \
+  (nettle_set_key_func *) name##_set_key,              \
+  (nettle_set_key_func *) name##_set_key,              \
+  (nettle_crypt_func *) name##_encrypt,                        \
+  (nettle_crypt_func *) name##_decrypt,                        \
+}
+
+/* null-terminated list of ciphers implemented by this version of nettle */
+extern const struct nettle_cipher * const nettle_ciphers[];
+
+extern const struct nettle_cipher nettle_aes128;
+extern const struct nettle_cipher nettle_aes192;
+extern const struct nettle_cipher nettle_aes256;
+
+extern const struct nettle_cipher nettle_arcfour128;
+
+extern const struct nettle_cipher nettle_camellia128;
+extern const struct nettle_cipher nettle_camellia192;
+extern const struct nettle_cipher nettle_camellia256;
+
+extern const struct nettle_cipher nettle_cast128;
+
+extern const struct nettle_cipher nettle_serpent128;
+extern const struct nettle_cipher nettle_serpent192;
+extern const struct nettle_cipher nettle_serpent256;
+
+extern const struct nettle_cipher nettle_twofish128;
+extern const struct nettle_cipher nettle_twofish192;
+extern const struct nettle_cipher nettle_twofish256;
+
+extern const struct nettle_cipher nettle_arctwo40;
+extern const struct nettle_cipher nettle_arctwo64;
+extern const struct nettle_cipher nettle_arctwo128;
+extern const struct nettle_cipher nettle_arctwo_gutmann128;
+
+struct nettle_hash
+{
+  const char *name;
+
+  /* Size of the context struct */
+  unsigned context_size;
+
+  /* Size of digests */
+  unsigned digest_size;
+  
+  /* Internal block size */
+  unsigned block_size;
+
+  nettle_hash_init_func *init;
+  nettle_hash_update_func *update;
+  nettle_hash_digest_func *digest;
+};
+
+#define _NETTLE_HASH(name, NAME) {             \
+ #name,                                                \
+ sizeof(struct name##_ctx),                    \
+ NAME##_DIGEST_SIZE,                           \
+ NAME##_DATA_SIZE,                             \
+ (nettle_hash_init_func *) name##_init,                \
+ (nettle_hash_update_func *) name##_update,    \
+ (nettle_hash_digest_func *) name##_digest     \
+} 
+
+/* null-terminated list of digests implemented by this version of nettle */
+extern const struct nettle_hash * const nettle_hashes[];
+
+extern const struct nettle_hash nettle_md2;
+extern const struct nettle_hash nettle_md4;
+extern const struct nettle_hash nettle_md5;
+extern const struct nettle_hash nettle_ripemd160;
+extern const struct nettle_hash nettle_sha1;
+extern const struct nettle_hash nettle_sha224;
+extern const struct nettle_hash nettle_sha256;
+extern const struct nettle_hash nettle_sha384;
+extern const struct nettle_hash nettle_sha512;
+
+struct nettle_armor
+{
+  const char *name;
+  unsigned encode_context_size;
+  unsigned decode_context_size;
+
+  unsigned encode_final_length;
+
+  nettle_armor_init_func *encode_init;
+  nettle_armor_length_func *encode_length;
+  nettle_armor_encode_update_func *encode_update;
+  nettle_armor_encode_final_func *encode_final;
+  
+  nettle_armor_init_func *decode_init;
+  nettle_armor_length_func *decode_length;
+  nettle_armor_decode_update_func *decode_update;
+  nettle_armor_decode_final_func *decode_final;
+};
+
+#define _NETTLE_ARMOR(name, NAME) {                            \
+  #name,                                                       \
+  sizeof(struct name##_encode_ctx),                            \
+  sizeof(struct name##_decode_ctx),                            \
+  NAME##_ENCODE_FINAL_LENGTH,                                  \
+  (nettle_armor_init_func *) name##_encode_init,               \
+  (nettle_armor_length_func *) name##_encode_length,           \
+  (nettle_armor_encode_update_func *) name##_encode_update,    \
+  (nettle_armor_encode_final_func *) name##_encode_final,      \
+  (nettle_armor_init_func *) name##_decode_init,               \
+  (nettle_armor_length_func *) name##_decode_length,           \
+  (nettle_armor_decode_update_func *) name##_decode_update,    \
+  (nettle_armor_decode_final_func *) name##_decode_final,      \
+}
+
+#define _NETTLE_ARMOR_0(name, NAME) {                          \
+  #name,                                                       \
+  0,                                                           \
+  sizeof(struct name##_decode_ctx),                            \
+  NAME##_ENCODE_FINAL_LENGTH,                                  \
+  (nettle_armor_init_func *) name##_encode_init,               \
+  (nettle_armor_length_func *) name##_encode_length,           \
+  (nettle_armor_encode_update_func *) name##_encode_update,    \
+  (nettle_armor_encode_final_func *) name##_encode_final,      \
+  (nettle_armor_init_func *) name##_decode_init,               \
+  (nettle_armor_length_func *) name##_decode_length,           \
+  (nettle_armor_decode_update_func *) name##_decode_update,    \
+  (nettle_armor_decode_final_func *) name##_decode_final,      \
+}
+
+/* null-terminated list of armor schemes implemented by this version of nettle */
+extern const struct nettle_armor * const nettle_armors[];
+
+extern const struct nettle_armor nettle_base64;
+extern const struct nettle_armor nettle_base16;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_META_H_INCLUDED */
diff --git a/nettle-types.h b/nettle-types.h
new file mode 100644 (file)
index 0000000..4c4e091
--- /dev/null
@@ -0,0 +1,89 @@
+/* nettle-types.h */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2005 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_TYPES_H
+#define NETTLE_TYPES_H
+
+#include "nettle-stdint.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Randomness. Used by key generation and dsa signature creation. */
+typedef void nettle_random_func(void *ctx,
+                               unsigned length, uint8_t *dst);
+
+/* Progress report function, mainly for key generation. */
+typedef void nettle_progress_func(void *ctx, int c);
+
+/* Realloc function, used by struct nettle_buffer. */
+typedef void *nettle_realloc_func(void *ctx, void *p, unsigned length);
+
+/* Ciphers */
+typedef void nettle_set_key_func(void *ctx,
+                                unsigned length,
+                                const uint8_t *key);
+
+/* Uses a void * for cipher contexts.
+
+   For block ciphers it would make sense with a const void * for the
+   context, but we use the same typedef for stream ciphers where the
+   internal state changes during the encryption. */
+
+typedef void nettle_crypt_func(void *ctx,
+                              unsigned length, uint8_t *dst,
+                              const uint8_t *src);
+
+/* Hash algorithms */
+typedef void nettle_hash_init_func(void *ctx);
+typedef void nettle_hash_update_func(void *ctx,
+                                    unsigned length,
+                                    const uint8_t *src);
+typedef void nettle_hash_digest_func(void *ctx,
+                                    unsigned length, uint8_t *dst);
+
+/* ASCII armor codecs. NOTE: Experimental and subject to change. */
+
+typedef unsigned nettle_armor_length_func(unsigned length);
+typedef void nettle_armor_init_func(void *ctx);
+
+typedef unsigned nettle_armor_encode_update_func(void *ctx,
+                                                uint8_t *dst,
+                                                unsigned src_length,
+                                                const uint8_t *src);
+
+typedef unsigned nettle_armor_encode_final_func(void *ctx, uint8_t *dst);
+
+typedef int nettle_armor_decode_update_func(void *ctx,
+                                           unsigned *dst_length,
+                                           uint8_t *dst,
+                                           unsigned src_length,
+                                           const uint8_t *src);
+
+typedef int nettle_armor_decode_final_func(void *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_TYPES_H */
diff --git a/nettle-write.h b/nettle-write.h
new file mode 100644 (file)
index 0000000..7287270
--- /dev/null
@@ -0,0 +1,44 @@
+/* nettle-write.h
+ *
+ * Prototypes for some internal functions to write out word-sized data
+ * to byte arrays. */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_WRITE_H_INCLUDED
+#define NETTLE_WRITE_H_INCLUDED
+
+#include "nettle-stdint.h"
+
+/* Write the word array at SRC to the byte array at DST, using little
+   endian (le) or big endian (be) byte order, and truncating the
+   result to LENGTH bytes. */
+void
+_nettle_write_be32(unsigned length, uint8_t *dst,
+                  uint32_t *src);
+void
+_nettle_write_le32(unsigned length, uint8_t *dst,
+                  uint32_t *src);
+void
+_nettle_write_be64(unsigned length, uint8_t *dst,
+                  uint64_t *src);
+
+#endif /* NETTLE_WRITE_H_INCLUDED */
diff --git a/nettle.html b/nettle.html
new file mode 100644 (file)
index 0000000..919542d
--- /dev/null
@@ -0,0 +1,3616 @@
+<html lang="en">
+<head>
+<title>Nettle: a low-level cryptographic library</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta name="description" content="Nettle: a low-level cryptographic library">
+<meta name="generator" content="makeinfo 4.13">
+<link title="Top" rel="top" href="#Top">
+<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+<!--
+This manual is for the Nettle library (version 2.3), a
+low-level cryptographic library.
+
+Originally written 2001 by Niels Möller, updated 2011.
+
+     This manual is placed in the public domain. You may freely copy
+     it, in whole or in part, with or without modification. Attribution
+     is appreciated, but not required.
+   -->
+<meta http-equiv="Content-Style-Type" content="text/css">
+<style type="text/css"><!--
+  pre.display { font-family:inherit }
+  pre.format  { font-family:inherit }
+  pre.smalldisplay { font-family:inherit; font-size:smaller }
+  pre.smallformat  { font-family:inherit; font-size:smaller }
+  pre.smallexample { font-size:smaller }
+  pre.smalllisp    { font-size:smaller }
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
+--></style>
+</head>
+<body>
+<h1 class="settitle">Nettle: a low-level cryptographic library</h1>
+   <div class="contents">
+<h2>Table of Contents</h2>
+<ul>
+<li><a name="toc_Top" href="#Top">Nettle</a>
+<li><a name="toc_Introduction" href="#Introduction">1 Introduction</a>
+<li><a name="toc_Copyright" href="#Copyright">2 Copyright</a>
+<li><a name="toc_Conventions" href="#Conventions">3 Conventions</a>
+<li><a name="toc_Example" href="#Example">4 Example</a>
+<li><a name="toc_Linking" href="#Linking">5 Linking</a>
+<li><a name="toc_Reference" href="#Reference">6 Reference</a>
+<ul>
+<li><a href="#Hash-functions">6.1 Hash functions</a>
+<ul>
+<li><a href="#Hash-functions">6.1.1 <acronym>MD5</acronym></a>
+<li><a href="#Hash-functions">6.1.2 <acronym>MD2</acronym></a>
+<li><a href="#Hash-functions">6.1.3 <acronym>MD4</acronym></a>
+<li><a href="#Hash-functions">6.1.4 <acronym>RIPEMD160</acronym></a>
+<li><a href="#Hash-functions">6.1.5 <acronym>SHA1</acronym></a>
+<li><a href="#Hash-functions">6.1.6 <acronym>SHA256</acronym></a>
+<li><a href="#Hash-functions">6.1.7 <acronym>SHA224</acronym></a>
+<li><a href="#Hash-functions">6.1.8 <acronym>SHA512</acronym></a>
+<li><a href="#Hash-functions">6.1.9 <acronym>SHA384</acronym></a>
+<li><a href="#Hash-functions">6.1.10 <code>struct nettle_hash</code></a>
+</li></ul>
+<li><a href="#Cipher-functions">6.2 Cipher functions</a>
+<ul>
+<li><a href="#Cipher-functions">6.2.1 AES</a>
+<li><a href="#Cipher-functions">6.2.2 ARCFOUR</a>
+<li><a href="#Cipher-functions">6.2.3 ARCTWO</a>
+<li><a href="#Cipher-functions">6.2.4 BLOWFISH</a>
+<li><a href="#Cipher-functions">6.2.5 Camellia</a>
+<li><a href="#Cipher-functions">6.2.6 CAST128</a>
+<li><a href="#Cipher-functions">6.2.7 DES</a>
+<li><a href="#Cipher-functions">6.2.8 DES3</a>
+<li><a href="#Cipher-functions">6.2.9 SERPENT</a>
+<li><a href="#Cipher-functions">6.2.10 TWOFISH</a>
+<li><a href="#Cipher-functions">6.2.11 <code>struct nettle_cipher</code></a>
+</li></ul>
+<li><a href="#Cipher-modes">6.3 Cipher modes</a>
+<ul>
+<li><a href="#CBC">6.3.1 Cipher Block Chaining</a>
+<li><a href="#CTR">6.3.2 Counter mode</a>
+<li><a href="#GCM">6.3.3 Galois counter mode</a>
+<ul>
+<li><a href="#GCM">6.3.3.1 General <acronym>GCM</acronym> interface</a>
+<li><a href="#GCM">6.3.3.2 <acronym>GCM</acronym> helper macros</a>
+<li><a href="#GCM">6.3.3.3 <acronym>GCM</acronym>-<acronym>AES</acronym> interface</a>
+</li></ul>
+</li></ul>
+<li><a href="#Keyed-hash-functions">6.4 Keyed Hash Functions</a>
+<ul>
+<li><a href="#Keyed-hash-functions">6.4.1 <acronym>HMAC</acronym></a>
+<li><a href="#Keyed-hash-functions">6.4.2 Concrete <acronym>HMAC</acronym> functions</a>
+<ul>
+<li><a href="#Keyed-hash-functions">6.4.2.1 <acronym>HMAC-MD5</acronym></a>
+<li><a href="#Keyed-hash-functions">6.4.2.2 <acronym>HMAC-RIPEMD160</acronym></a>
+<li><a href="#Keyed-hash-functions">6.4.2.3 <acronym>HMAC-SHA1</acronym></a>
+<li><a href="#Keyed-hash-functions">6.4.2.4 <acronym>HMAC-SHA256</acronym></a>
+<li><a href="#Keyed-hash-functions">6.4.2.5 <acronym>HMAC-SHA512</acronym></a>
+</li></ul>
+</li></ul>
+<li><a href="#Public_002dkey-algorithms">6.5 Public-key algorithms</a>
+<ul>
+<li><a href="#RSA">6.5.1 <acronym>RSA</acronym></a>
+<li><a href="#RSA">6.5.2 Nettle's <acronym>RSA</acronym> support</a>
+<li><a href="#DSA">6.5.3 Nettle's <acronym>DSA</acronym> support</a>
+<li><a href="#DSA">6.5.4 Nettle's <acronym>DSA</acronym> support</a>
+</li></ul>
+<li><a href="#Randomness">6.6 Randomness</a>
+<ul>
+<li><a href="#Randomness">6.6.1 Yarrow</a>
+</li></ul>
+<li><a href="#Miscellaneous-functions">6.7 Miscellaneous functions</a>
+<li><a href="#Compatibility-functions">6.8 Compatibility functions</a>
+</li></ul>
+<li><a name="toc_Nettle-soup" href="#Nettle-soup">7 Traditional Nettle Soup</a>
+<li><a name="toc_Installation" href="#Installation">8 Installation</a>
+<li><a name="toc_Index" href="#Index">Function and Concept Index</a>
+</li></ul>
+</div>
+
+
+
+<div class="node">
+<a name="Top"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#Introduction">Introduction</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#dir">(dir)</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#dir">(dir)</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h2 class="unnumbered">Nettle</h2>
+
+<p>This document describes the Nettle low-level cryptographic library. You
+can use the library directly from your C programs, or write or use an
+object-oriented wrapper for your favorite language or application.
+
+   <p>This manual is for the Nettle library (version 2.3), a
+low-level cryptographic library.
+
+   <p>Originally written 2001 by Niels Möller, updated 2011.
+
+   <blockquote>
+This manual is placed in the public domain. You may freely copy it, in
+whole or in part, with or without modification. Attribution is
+appreciated, but not required. 
+</blockquote>
+
+<ul class="menu">
+<li><a accesskey="1" href="#Introduction">Introduction</a>:                 What is Nettle? 
+<li><a accesskey="2" href="#Copyright">Copyright</a>:                    Your rights. 
+<li><a accesskey="3" href="#Conventions">Conventions</a>:                  General interface conventions. 
+<li><a accesskey="4" href="#Example">Example</a>:                      An example program. 
+<li><a accesskey="5" href="#Linking">Linking</a>:                      Linking with the libnettle and libhogweed. 
+<li><a accesskey="6" href="#Reference">Reference</a>:                    All Nettle functions and features. 
+<li><a accesskey="7" href="#Nettle-soup">Nettle soup</a>:                  For the serious nettle hacker. 
+<li><a accesskey="8" href="#Installation">Installation</a>:                 How to install Nettle. 
+<li><a accesskey="9" href="#Index">Index</a>:                        Function and concept index.
+
+</li></ul>
+<p>--- The Detailed Node Listing ---
+
+<p>Reference
+
+</p>
+<ul class="menu">
+<li><a href="#Hash-functions">Hash functions</a>
+<li><a href="#Cipher-functions">Cipher functions</a>
+<li><a href="#Cipher-modes">Cipher modes</a>
+<li><a href="#Keyed-hash-functions">Keyed hash functions</a>
+<li><a href="#Public_002dkey-algorithms">Public-key algorithms</a>
+<li><a href="#Randomness">Randomness</a>
+<li><a href="#Miscellaneous-functions">Miscellaneous functions</a>
+<li><a href="#Compatibility-functions">Compatibility functions</a>
+
+</li></ul>
+<p>Cipher modes
+
+</p>
+<ul class="menu">
+<li><a href="#CBC">CBC</a>
+<li><a href="#CTR">CTR</a>
+<li><a href="#GCM">GCM</a>
+
+</li></ul>
+<p>Public-key algorithms
+
+</p>
+<ul class="menu">
+<li><a href="#RSA">RSA</a>:                          The RSA public key algorithm. 
+<li><a href="#DSA">DSA</a>:                          The DSA digital signature algorithm.
+
+   </ul>
+
+<div class="node">
+<a name="Introduction"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#Copyright">Copyright</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Top">Top</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Top">Top</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h2 class="chapter">1 Introduction</h2>
+
+<p>Nettle is a cryptographic library that is designed to fit easily in more
+or less any context: In crypto toolkits for object-oriented languages
+(C++, Python, Pike, ...), in applications like LSH or GNUPG, or even in
+kernel space. In most contexts, you need more than the basic
+cryptographic algorithms, you also need some way to keep track of available
+algorithms, their properties and variants. You often have some algorithm
+selection process, often dictated by a protocol you want to implement.
+
+   <p>And as the requirements of applications differ in subtle and not so
+subtle ways, an API that fits one application well can be a pain to use
+in a different context. And that is why there are so many different
+cryptographic libraries around.
+
+   <p>Nettle tries to avoid this problem by doing one thing, the low-level
+crypto stuff, and providing a <em>simple</em> but general interface to it. 
+In particular, Nettle doesn't do algorithm selection. It doesn't do
+memory allocation. It doesn't do any I/O.
+
+   <p>The idea is that one can build several application and context specific
+interfaces on top of Nettle, and share the code, test cases, benchmarks,
+documentation, etc. Examples are the Nettle module for the Pike
+language, and LSH, which both use an object-oriented abstraction on top
+of the library.
+
+   <p>This manual explains how to use the Nettle library. It also tries to
+provide some background on the cryptography, and advice on how to best
+put it to use.
+
+<div class="node">
+<a name="Copyright"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#Conventions">Conventions</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Introduction">Introduction</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Top">Top</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h2 class="chapter">2 Copyright</h2>
+
+<p>Nettle is distributed under the GNU Lesser General Public License
+(LGPL), see the file COPYING.LIB for details. A few of the individual
+files are in the public domain. To find the current status of particular
+files, you have to read the copyright notices at the top of the files.
+
+   <p>This manual is in the public domain. You may freely copy it in whole or
+in part, e.g., into documentation of programs that build on Nettle. 
+Attribution, as well as contribution of improvements to the text, is of
+course appreciated, but it is not required.
+
+   <p>A list of the supported algorithms, their origins and licenses:
+
+     <dl>
+<dt><em>AES</em><dd>The implementation of the AES cipher (also known as rijndael) is written
+by Rafael Sevilla. Assembler for x86 by Rafael Sevilla and
+Niels Möller, Sparc assembler by Niels Möller. Released under the
+LGPL.
+
+     <br><dt><em>ARCFOUR</em><dd>The implementation of the ARCFOUR (also known as RC4) cipher is written
+by Niels Möller. Released under the LGPL.
+
+     <br><dt><em>ARCTWO</em><dd>The implementation of the ARCTWO (also known as RC2) cipher is written
+by Nikos Mavroyanopoulos and modified by Werner Koch and Simon
+Josefsson. Released under the LGPL.
+
+     <br><dt><em>BLOWFISH</em><dd>The implementation of the BLOWFISH cipher is written by Werner Koch,
+copyright owned by the Free Software Foundation. Also hacked by Simon
+Josefsson and Niels Möller. Released under the LGPL.
+
+     <br><dt><em>CAMELLIA</em><dd>The C implementation is by Nippon Telegraph and Telephone Corporation
+(NTT), heavily modified by Niels Möller. Assembler for x86 and x86_64
+by Niels Möller. Released under the LGPL.
+
+     <br><dt><em>CAST128</em><dd>The implementation of the CAST128 cipher is written by Steve Reid. 
+Released into the public domain.
+
+     <br><dt><em>DES</em><dd>The implementation of the DES cipher is written by Dana L. How, and
+released under the LGPL.
+
+     <br><dt><em>MD2</em><dd>The implementation of MD2 is written by Andrew Kuchling, and hacked
+some by Andreas Sigfridsson and Niels Möller. Python Cryptography
+Toolkit license (essentially public domain).
+
+     <br><dt><em>MD4</em><dd>This is almost the same code as for MD5 below, with modifications by
+Marcus Comstedt. Released into the public domain.
+
+     <br><dt><em>MD5</em><dd>The implementation of the MD5 message digest is written by Colin Plumb. 
+It has been hacked some more by Andrew Kuchling and Niels Möller. 
+Released into the public domain.
+
+     <br><dt><em>RIPMED160</em><dd>The implementation of RIPEMD160 message digest is based on the code in
+libgcrypt, copyright owned by the Free Software Foundation. Ported to
+Nettle by Andres Mejia. Released under the LGPL.
+
+     <br><dt><em>SERPENT</em><dd>The implementation of the SERPENT cipher is based on the code in libgcrypt,
+copyright owned by the Free Software Foundation. Adapted to Nettle by
+Simon Josefsson and heavily modified by Niels Möller. Assembly for
+x86_64 by Niels Möller. Released under the LGPL.
+
+     <br><dt><em>SHA1</em><dd>The C implementation of the SHA1 message digest is written by Peter
+Gutmann, and hacked some more by Andrew Kuchling and Niels Möller. 
+Released into the public domain. Assembler for x86 by Niels Möller,
+released under the LGPL.
+
+     <br><dt><em>SHA224, SHA256, SHA384, and SHA512</em><dd>Written by Niels Möller, using Peter Gutmann's SHA1 code as a model. 
+Released under the LGPL.
+
+     <br><dt><em>TWOFISH</em><dd>The implementation of the TWOFISH cipher is written by Ruud de Rooij. 
+Released under the LGPL.
+
+     <br><dt><em>RSA</em><dd>Written by Niels Möller, released under the LGPL. Uses the GMP library
+for bignum operations.
+
+     <br><dt><em>DSA</em><dd>Written by Niels Möller, released under the LGPL. Uses the GMP library
+for bignum operations. 
+</dl>
+
+<div class="node">
+<a name="Conventions"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#Example">Example</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Copyright">Copyright</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Top">Top</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h2 class="chapter">3 Conventions</h2>
+
+<p>For each supported algorithm, there is an include file that defines a
+<em>context struct</em>, a few constants, and declares functions for
+operating on the context. The context struct encapsulates all information
+needed by the algorithm, and it can be copied or moved in memory with no
+unexpected effects.
+
+   <p>For consistency, functions for different algorithms are very similar,
+but there are some differences, for instance reflecting if the key setup
+or encryption function differ for encryption and decryption, and whether
+or not key setup can fail. There are also differences between algorithms
+that don't show in function prototypes, but which the application must
+nevertheless be aware of. There is no big difference between the
+functions for stream ciphers and for block ciphers, although they should
+be used quite differently by the application.
+
+   <p>If your application uses more than one algorithm of the same type, you
+should probably create an interface that is tailor-made for your needs,
+and then write a few lines of glue code on top of Nettle.
+
+   <p>By convention, for an algorithm named <code>foo</code>, the struct tag for the
+context struct is <code>foo_ctx</code>, constants and functions uses prefixes
+like <code>FOO_BLOCK_SIZE</code> (a constant) and <code>foo_set_key</code> (a
+function).
+
+   <p>In all functions, strings are represented with an explicit length, of
+type <code>unsigned</code>, and a pointer of type <code>uint8_t *</code> or
+<code>const uint8_t *</code>. For functions that transform one string to
+another, the argument order is length, destination pointer and source
+pointer. Source and destination areas are of the same length. Source and
+destination may be the same, so that you can process strings in place,
+but they <em>must not</em> overlap in any other way.
+
+   <p>Many of the functions lack return value and can never fail. Those
+functions which can fail, return one on success and zero on failure.
+
+<!-- FIXME: Say something about the name mangling. -->
+<div class="node">
+<a name="Example"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#Linking">Linking</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Conventions">Conventions</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Top">Top</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h2 class="chapter">4 Example</h2>
+
+<p>A simple example program that reads a file from standard input and
+writes its SHA1 checksum on standard output should give the flavor of
+Nettle.
+
+<pre class="example"><pre class="verbatim">     #include &lt;stdio.h>
+     #include &lt;stdlib.h>
+     
+     #include &lt;nettle/sha.h>
+     
+     #define BUF_SIZE 1000
+     
+     static void
+     display_hex(unsigned length, uint8_t *data)
+     {
+       unsigned i;
+     
+       for (i = 0; i&lt;length; i++)
+         printf("%02x ", data[i]);
+     
+       printf("\n");
+     }
+     
+     int
+     main(int argc, char **argv)
+     {
+       struct sha1_ctx ctx;
+       uint8_t buffer[BUF_SIZE];
+       uint8_t digest[SHA1_DIGEST_SIZE];
+       
+       sha1_init(&amp;ctx);
+       for (;;)
+       {
+         int done = fread(buffer, 1, sizeof(buffer), stdin);
+         sha1_update(&amp;ctx, done, buffer);
+         if (done &lt; sizeof(buffer))
+           break;
+       }
+       if (ferror(stdin))
+         return EXIT_FAILURE;
+     
+       sha1_digest(&amp;ctx, SHA1_DIGEST_SIZE, digest);
+     
+       display_hex(SHA1_DIGEST_SIZE, digest);
+       return EXIT_SUCCESS;  
+     }
+</pre></pre>
+   <p>On a typical Unix system, this program can be compiled and linked with
+the command line
+<pre class="example">     cc sha-example.c -o sha-example -lnettle
+</pre>
+   <div class="node">
+<a name="Linking"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#Reference">Reference</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Example">Example</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Top">Top</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h2 class="chapter">5 Linking</h2>
+
+<p>Nettle actually consists of two libraries, <samp><span class="file">libnettle</span></samp> and
+<samp><span class="file">libhogweed</span></samp>. The <samp><span class="file">libhogweed</span></samp> library contains those
+functions of Nettle that uses bignum operations, and depends on the GMP
+library. With this division, linking works the same for both static and
+dynamic libraries.
+
+   <p>If an application uses only the symmetric crypto algorithms of Nettle
+(i.e., block ciphers, hash functions, and the like), it's sufficient to
+link with <code>-lnettle</code>. If an application also uses public-key
+algorithms, the recommended linker flags are <code>-lhogweed -lnettle
+-lgmp</code>. If the involved libraries are installed as dynamic libraries, it
+may be sufficient to link with just <code>-lhogweed</code>, and the loader
+will resolve the dependencies automatically.
+
+<div class="node">
+<a name="Reference"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#Nettle-soup">Nettle soup</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Linking">Linking</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Top">Top</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h2 class="chapter">6 Reference</h2>
+
+<p>This chapter describes all the Nettle functions, grouped by family.
+
+<ul class="menu">
+<li><a accesskey="1" href="#Hash-functions">Hash functions</a>
+<li><a accesskey="2" href="#Cipher-functions">Cipher functions</a>
+<li><a accesskey="3" href="#Cipher-modes">Cipher modes</a>
+<li><a accesskey="4" href="#Keyed-hash-functions">Keyed hash functions</a>
+<li><a accesskey="5" href="#Public_002dkey-algorithms">Public-key algorithms</a>
+<li><a accesskey="6" href="#Randomness">Randomness</a>
+<li><a accesskey="7" href="#Miscellaneous-functions">Miscellaneous functions</a>
+<li><a accesskey="8" href="#Compatibility-functions">Compatibility functions</a>
+</ul>
+
+<div class="node">
+<a name="Hash-functions"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#Cipher-functions">Cipher functions</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Reference">Reference</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Reference">Reference</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h3 class="section">6.1 Hash functions</h3>
+
+<p><a name="index-Hash-function-1"></a>A cryptographic <dfn>hash function</dfn> is a function that takes variable
+size strings, and maps them to strings of fixed, short, length. There
+are naturally lots of collisions, as there are more possible 1MB files
+than 20 byte strings. But the function is constructed such that is hard
+to find the collisions. More precisely, a cryptographic hash function
+<code>H</code> should have the following properties:
+
+     <dl>
+<dt><em>One-way</em><dd><a name="index-One_002dway-2"></a>Given a hash value <code>H(x)</code> it is hard to find a string <code>x</code>
+that hashes to that value.
+
+     <br><dt><em>Collision-resistant</em><dd><a name="index-Collision_002dresistant-3"></a>It is hard to find two different strings, <code>x</code> and <code>y</code>, such
+that <code>H(x)</code> = <code>H(y)</code>.
+
+   </dl>
+
+   <p>Hash functions are useful as building blocks for digital signatures,
+message authentication codes, pseudo random generators, association of
+unique ids to documents, and many other things.
+
+   <p>The most commonly used hash functions are MD5 and SHA1. Unfortunately,
+both these fail the collision-resistance requirement; cryptologists have
+found ways to construct colliding inputs. The recommended hash function
+for new applications is SHA256, even though it uses a structure similar
+to MD5 and SHA1. Constructing better hash functions is an urgent research
+problem.
+
+<h4 class="subsection">6.1.1 <acronym>MD5</acronym></h4>
+
+<p>MD5 is a message digest function constructed by Ronald Rivest, and
+described in <cite>RFC 1321</cite>. It outputs message digests of 128 bits, or
+16 octets. Nettle defines MD5 in <samp><span class="file">&lt;nettle/md5.h&gt;</span></samp>.
+
+<div class="defun">
+&mdash; Context struct: <b>struct md5_ctx</b><var><a name="index-struct-md5_005fctx-4"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>MD5_DIGEST_SIZE</b><var><a name="index-MD5_005fDIGEST_005fSIZE-5"></a></var><br>
+<blockquote><p>The size of an MD5 digest, i.e. 16. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>MD5_DATA_SIZE</b><var><a name="index-MD5_005fDATA_005fSIZE-6"></a></var><br>
+<blockquote><p>The internal block size of MD5. Useful for some special constructions,
+in particular HMAC-MD5. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>md5_init</b> (<var>struct md5_ctx *ctx</var>)<var><a name="index-md5_005finit-7"></a></var><br>
+<blockquote><p>Initialize the MD5 state. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>md5_update</b> (<var>struct md5_ctx *ctx, unsigned length, const uint8_t *data</var>)<var><a name="index-md5_005fupdate-8"></a></var><br>
+<blockquote><p>Hash some more data. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>md5_digest</b> (<var>struct md5_ctx *ctx, unsigned length, uint8_t *digest</var>)<var><a name="index-md5_005fdigest-9"></a></var><br>
+<blockquote><p>Performs final processing and extracts the message digest, writing it
+to <var>digest</var>. <var>length</var> may be smaller than
+<code>MD5_DIGEST_SIZE</code>, in which case only the first <var>length</var>
+octets of the digest are written.
+
+        <p>This function also resets the context in the same way as
+<code>md5_init</code>. 
+</p></blockquote></div>
+
+   <p>The normal way to use MD5 is to call the functions in order: First
+<code>md5_init</code>, then <code>md5_update</code> zero or more times, and finally
+<code>md5_digest</code>. After <code>md5_digest</code>, the context is reset to
+its initial state, so you can start over calling <code>md5_update</code> to
+hash new data.
+
+   <p>To start over, you can call <code>md5_init</code> at any time.
+
+<h4 class="subsection">6.1.2 <acronym>MD2</acronym></h4>
+
+<p>MD2 is another hash function of Ronald Rivest's, described in
+<cite>RFC 1319</cite>. It outputs message digests of 128 bits, or 16 octets. 
+Nettle defines MD2 in <samp><span class="file">&lt;nettle/md2.h&gt;</span></samp>.
+
+<div class="defun">
+&mdash; Context struct: <b>struct md2_ctx</b><var><a name="index-struct-md2_005fctx-10"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>MD2_DIGEST_SIZE</b><var><a name="index-MD2_005fDIGEST_005fSIZE-11"></a></var><br>
+<blockquote><p>The size of an MD2 digest, i.e. 16. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>MD2_DATA_SIZE</b><var><a name="index-MD2_005fDATA_005fSIZE-12"></a></var><br>
+<blockquote><p>The internal block size of MD2. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>md2_init</b> (<var>struct md2_ctx *ctx</var>)<var><a name="index-md2_005finit-13"></a></var><br>
+<blockquote><p>Initialize the MD2 state. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>md2_update</b> (<var>struct md2_ctx *ctx, unsigned length, const uint8_t *data</var>)<var><a name="index-md2_005fupdate-14"></a></var><br>
+<blockquote><p>Hash some more data. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>md2_digest</b> (<var>struct md2_ctx *ctx, unsigned length, uint8_t *digest</var>)<var><a name="index-md2_005fdigest-15"></a></var><br>
+<blockquote><p>Performs final processing and extracts the message digest, writing it
+to <var>digest</var>. <var>length</var> may be smaller than
+<code>MD2_DIGEST_SIZE</code>, in which case only the first <var>length</var>
+octets of the digest are written.
+
+        <p>This function also resets the context in the same way as
+<code>md2_init</code>. 
+</p></blockquote></div>
+
+<h4 class="subsection">6.1.3 <acronym>MD4</acronym></h4>
+
+<p>MD4 is a predecessor of MD5, described in <cite>RFC 1320</cite>. Like MD5, it
+is constructed by Ronald Rivest. It outputs message digests of 128 bits,
+or 16 octets. Nettle defines MD4 in <samp><span class="file">&lt;nettle/md4.h&gt;</span></samp>. Use of MD4 is
+not recommended, but it is sometimes needed for compatibility with
+existing applications and protocols.
+
+<div class="defun">
+&mdash; Context struct: <b>struct md4_ctx</b><var><a name="index-struct-md4_005fctx-16"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>MD4_DIGEST_SIZE</b><var><a name="index-MD4_005fDIGEST_005fSIZE-17"></a></var><br>
+<blockquote><p>The size of an MD4 digest, i.e. 16. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>MD4_DATA_SIZE</b><var><a name="index-MD4_005fDATA_005fSIZE-18"></a></var><br>
+<blockquote><p>The internal block size of MD4. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>md4_init</b> (<var>struct md4_ctx *ctx</var>)<var><a name="index-md4_005finit-19"></a></var><br>
+<blockquote><p>Initialize the MD4 state. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>md4_update</b> (<var>struct md4_ctx *ctx, unsigned length, const uint8_t *data</var>)<var><a name="index-md4_005fupdate-20"></a></var><br>
+<blockquote><p>Hash some more data. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>md4_digest</b> (<var>struct md4_ctx *ctx, unsigned length, uint8_t *digest</var>)<var><a name="index-md4_005fdigest-21"></a></var><br>
+<blockquote><p>Performs final processing and extracts the message digest, writing it
+to <var>digest</var>. <var>length</var> may be smaller than
+<code>MD4_DIGEST_SIZE</code>, in which case only the first <var>length</var>
+octets of the digest are written.
+
+        <p>This function also resets the context in the same way as
+<code>md4_init</code>. 
+</p></blockquote></div>
+
+<h4 class="subsection">6.1.4 <acronym>RIPEMD160</acronym></h4>
+
+<p>RIPEMD160 is a hash function designed by Hans Dobbertin, Antoon
+Bosselaers, and Bart Preneel, as a strengthened version of RIPEMD
+(which, like MD4 and MD5, fails the collision-resistance requirement). 
+It produces message digests of 160 bits, or 20 octets. Nettle defined
+RIPEMD160 in <samp><span class="file">nettle/ripemd160.h</span></samp>.
+
+<div class="defun">
+&mdash; Context struct: <b>struct ripemd160_ctx</b><var><a name="index-struct-ripemd160_005fctx-22"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>RIPEMD160_DIGEST_SIZE</b><var><a name="index-RIPEMD160_005fDIGEST_005fSIZE-23"></a></var><br>
+<blockquote><p>The size of an RIPEMD160 digest, i.e. 20. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>RIPEMD160_DATA_SIZE</b><var><a name="index-RIPEMD160_005fDATA_005fSIZE-24"></a></var><br>
+<blockquote><p>The internal block size of RIPEMD160. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>ripemd160_init</b> (<var>struct ripemd160_ctx *ctx</var>)<var><a name="index-ripemd160_005finit-25"></a></var><br>
+<blockquote><p>Initialize the RIPEMD160 state. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>ripemd160_update</b> (<var>struct ripemd160_ctx *ctx, unsigned length, const uint8_t *data</var>)<var><a name="index-ripemd160_005fupdate-26"></a></var><br>
+<blockquote><p>Hash some more data. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>ripemd160_digest</b> (<var>struct ripemd160_ctx *ctx, unsigned length, uint8_t *digest</var>)<var><a name="index-ripemd160_005fdigest-27"></a></var><br>
+<blockquote><p>Performs final processing and extracts the message digest, writing it
+to <var>digest</var>. <var>length</var> may be smaller than
+<code>RIPEMD160_DIGEST_SIZE</code>, in which case only the first <var>length</var>
+octets of the digest are written.
+
+        <p>This function also resets the context in the same way as
+<code>ripemd160_init</code>. 
+</p></blockquote></div>
+
+<h4 class="subsection">6.1.5 <acronym>SHA1</acronym></h4>
+
+<p>SHA1 is a hash function specified by <dfn>NIST</dfn> (The U.S. National Institute
+for Standards and Technology). It outputs hash values of 160 bits, or 20
+octets. Nettle defines SHA1 in <samp><span class="file">&lt;nettle/sha.h&gt;</span></samp>.
+
+   <p>The functions are analogous to the MD5 ones.
+
+<div class="defun">
+&mdash; Context struct: <b>struct sha1_ctx</b><var><a name="index-struct-sha1_005fctx-28"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>SHA1_DIGEST_SIZE</b><var><a name="index-SHA1_005fDIGEST_005fSIZE-29"></a></var><br>
+<blockquote><p>The size of an SHA1 digest, i.e. 20. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>SHA1_DATA_SIZE</b><var><a name="index-SHA1_005fDATA_005fSIZE-30"></a></var><br>
+<blockquote><p>The internal block size of SHA1. Useful for some special constructions,
+in particular HMAC-SHA1. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>sha1_init</b> (<var>struct sha1_ctx *ctx</var>)<var><a name="index-sha1_005finit-31"></a></var><br>
+<blockquote><p>Initialize the SHA1 state. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>sha1_update</b> (<var>struct sha1_ctx *ctx, unsigned length, const uint8_t *data</var>)<var><a name="index-sha1_005fupdate-32"></a></var><br>
+<blockquote><p>Hash some more data. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>sha1_digest</b> (<var>struct sha1_ctx *ctx, unsigned length, uint8_t *digest</var>)<var><a name="index-sha1_005fdigest-33"></a></var><br>
+<blockquote><p>Performs final processing and extracts the message digest, writing it
+to <var>digest</var>. <var>length</var> may be smaller than
+<code>SHA1_DIGEST_SIZE</code>, in which case only the first <var>length</var>
+octets of the digest are written.
+
+        <p>This function also resets the context in the same way as
+<code>sha1_init</code>. 
+</p></blockquote></div>
+
+<h4 class="subsection">6.1.6 <acronym>SHA256</acronym></h4>
+
+<p>SHA256 is another hash function specified by <dfn>NIST</dfn>, intended as a
+replacement for <acronym>SHA1</acronym>, generating larger digests. It outputs
+hash values of 256 bits, or 32 octets. Nettle defines SHA256 in
+<samp><span class="file">&lt;nettle/sha.h&gt;</span></samp>.
+
+   <p>The functions are analogous to the MD5 ones.
+
+<div class="defun">
+&mdash; Context struct: <b>struct sha256_ctx</b><var><a name="index-struct-sha256_005fctx-34"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>SHA256_DIGEST_SIZE</b><var><a name="index-SHA256_005fDIGEST_005fSIZE-35"></a></var><br>
+<blockquote><p>The size of an SHA256 digest, i.e. 32. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>SHA256_DATA_SIZE</b><var><a name="index-SHA256_005fDATA_005fSIZE-36"></a></var><br>
+<blockquote><p>The internal block size of SHA256. Useful for some special constructions,
+in particular HMAC-SHA256. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>sha256_init</b> (<var>struct sha256_ctx *ctx</var>)<var><a name="index-sha256_005finit-37"></a></var><br>
+<blockquote><p>Initialize the SHA256 state. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>sha256_update</b> (<var>struct sha256_ctx *ctx, unsigned length, const uint8_t *data</var>)<var><a name="index-sha256_005fupdate-38"></a></var><br>
+<blockquote><p>Hash some more data. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>sha256_digest</b> (<var>struct sha256_ctx *ctx, unsigned length, uint8_t *digest</var>)<var><a name="index-sha256_005fdigest-39"></a></var><br>
+<blockquote><p>Performs final processing and extracts the message digest, writing it
+to <var>digest</var>. <var>length</var> may be smaller than
+<code>SHA256_DIGEST_SIZE</code>, in which case only the first <var>length</var>
+octets of the digest are written.
+
+        <p>This function also resets the context in the same way as
+<code>sha256_init</code>. 
+</p></blockquote></div>
+
+<h4 class="subsection">6.1.7 <acronym>SHA224</acronym></h4>
+
+<p>SHA224 is a variant of SHA256, with a different initial state, and with
+the output truncated to 224 bits, or 28 octets. Nettle defines SHA224 in
+<samp><span class="file">&lt;nettle/sha.h&gt;</span></samp>.
+
+   <p>The functions are analogous to the MD5 ones.
+
+<div class="defun">
+&mdash; Context struct: <b>struct sha224_ctx</b><var><a name="index-struct-sha224_005fctx-40"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>SHA224_DIGEST_SIZE</b><var><a name="index-SHA224_005fDIGEST_005fSIZE-41"></a></var><br>
+<blockquote><p>The size of an SHA224 digest, i.e. 28. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>SHA224_DATA_SIZE</b><var><a name="index-SHA224_005fDATA_005fSIZE-42"></a></var><br>
+<blockquote><p>The internal block size of SHA224. Useful for some special constructions,
+in particular HMAC-SHA224. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>sha224_init</b> (<var>struct sha224_ctx *ctx</var>)<var><a name="index-sha224_005finit-43"></a></var><br>
+<blockquote><p>Initialize the SHA224 state. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>sha224_update</b> (<var>struct sha224_ctx *ctx, unsigned length, const uint8_t *data</var>)<var><a name="index-sha224_005fupdate-44"></a></var><br>
+<blockquote><p>Hash some more data. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>sha224_digest</b> (<var>struct sha224_ctx *ctx, unsigned length, uint8_t *digest</var>)<var><a name="index-sha224_005fdigest-45"></a></var><br>
+<blockquote><p>Performs final processing and extracts the message digest, writing it
+to <var>digest</var>. <var>length</var> may be smaller than
+<code>SHA224_DIGEST_SIZE</code>, in which case only the first <var>length</var>
+octets of the digest are written.
+
+        <p>This function also resets the context in the same way as
+<code>sha224_init</code>. 
+</p></blockquote></div>
+
+<h4 class="subsection">6.1.8 <acronym>SHA512</acronym></h4>
+
+<p>SHA512 is a larger sibling to SHA256, with a very similar structure but
+with both the output and the internal variables of twice the size. The
+internal variables are 64 bits rather than 32, making it significantly
+slower on 32-bit computers. It outputs hash values of 512 bits, or 64
+octets. Nettle defines SHA512 in <samp><span class="file">&lt;nettle/sha.h&gt;</span></samp>.
+
+   <p>The functions are analogous to the MD5 ones.
+
+<div class="defun">
+&mdash; Context struct: <b>struct sha512_ctx</b><var><a name="index-struct-sha512_005fctx-46"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>SHA512_DIGEST_SIZE</b><var><a name="index-SHA512_005fDIGEST_005fSIZE-47"></a></var><br>
+<blockquote><p>The size of an SHA512 digest, i.e. 64. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>SHA512_DATA_SIZE</b><var><a name="index-SHA512_005fDATA_005fSIZE-48"></a></var><br>
+<blockquote><p>The internal block size of SHA512. Useful for some special constructions,
+in particular HMAC-SHA512. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>sha512_init</b> (<var>struct sha512_ctx *ctx</var>)<var><a name="index-sha512_005finit-49"></a></var><br>
+<blockquote><p>Initialize the SHA512 state. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>sha512_update</b> (<var>struct sha512_ctx *ctx, unsigned length, const uint8_t *data</var>)<var><a name="index-sha512_005fupdate-50"></a></var><br>
+<blockquote><p>Hash some more data. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>sha512_digest</b> (<var>struct sha512_ctx *ctx, unsigned length, uint8_t *digest</var>)<var><a name="index-sha512_005fdigest-51"></a></var><br>
+<blockquote><p>Performs final processing and extracts the message digest, writing it
+to <var>digest</var>. <var>length</var> may be smaller than
+<code>SHA512_DIGEST_SIZE</code>, in which case only the first <var>length</var>
+octets of the digest are written.
+
+        <p>This function also resets the context in the same way as
+<code>sha512_init</code>. 
+</p></blockquote></div>
+
+<h4 class="subsection">6.1.9 <acronym>SHA384</acronym></h4>
+
+<p>SHA384 is a variant of SHA512, with a different initial state, and with
+the output truncated to 384 bits, or 48 octets. Nettle defines SHA384 in
+<samp><span class="file">&lt;nettle/sha.h&gt;</span></samp>.
+
+   <p>The functions are analogous to the MD5 ones.
+
+<div class="defun">
+&mdash; Context struct: <b>struct sha384_ctx</b><var><a name="index-struct-sha384_005fctx-52"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>SHA384_DIGEST_SIZE</b><var><a name="index-SHA384_005fDIGEST_005fSIZE-53"></a></var><br>
+<blockquote><p>The size of an SHA384 digest, i.e. 48. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>SHA384_DATA_SIZE</b><var><a name="index-SHA384_005fDATA_005fSIZE-54"></a></var><br>
+<blockquote><p>The internal block size of SHA384. Useful for some special constructions,
+in particular HMAC-SHA384. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>sha384_init</b> (<var>struct sha384_ctx *ctx</var>)<var><a name="index-sha384_005finit-55"></a></var><br>
+<blockquote><p>Initialize the SHA384 state. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>sha384_update</b> (<var>struct sha384_ctx *ctx, unsigned length, const uint8_t *data</var>)<var><a name="index-sha384_005fupdate-56"></a></var><br>
+<blockquote><p>Hash some more data. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>sha384_digest</b> (<var>struct sha384_ctx *ctx, unsigned length, uint8_t *digest</var>)<var><a name="index-sha384_005fdigest-57"></a></var><br>
+<blockquote><p>Performs final processing and extracts the message digest, writing it
+to <var>digest</var>. <var>length</var> may be smaller than
+<code>SHA384_DIGEST_SIZE</code>, in which case only the first <var>length</var>
+octets of the digest are written.
+
+        <p>This function also resets the context in the same way as
+<code>sha384_init</code>. 
+</p></blockquote></div>
+
+<h4 class="subsection">6.1.10 <code>struct nettle_hash</code></h4>
+
+<p>Nettle includes a struct including information about the supported hash
+functions. It is defined in <samp><span class="file">&lt;nettle/nettle-meta.h&gt;</span></samp>, and is used
+by Nettle's implementation of <acronym>HMAC</acronym> (see <a href="#Keyed-hash-functions">Keyed hash functions</a>).
+
+<div class="defun">
+&mdash; Meta struct: <code>struct nettle_hash</code><var> name context_size digest_size block_size init update digest<a name="index-g_t_0040code_007bstruct-nettle_005fhash_007d-58"></a></var><br>
+<blockquote><p>The last three attributes are function pointers, of types
+<code>nettle_hash_init_func</code>, <code>nettle_hash_update_func</code>, and
+<code>nettle_hash_digest_func</code>. The first argument to these functions is
+<code>void *</code> pointer to a context struct, which is of size
+<code>context_size</code>. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant Struct: struct nettle_hash <b>nettle_md2</b><var><a name="index-nettle_005fmd2-59"></a></var><br>
+&mdash; Constant Struct: struct nettle_hash <b>nettle_md4</b><var><a name="index-nettle_005fmd4-60"></a></var><br>
+&mdash; Constant Struct: struct nettle_hash <b>nettle_md5</b><var><a name="index-nettle_005fmd5-61"></a></var><br>
+&mdash; Constant Struct: struct nettle_hash <b>nettle_ripemd160</b><var><a name="index-nettle_005fripemd160-62"></a></var><br>
+&mdash; Constant Struct: struct nettle_hash <b>nettle_sha1</b><var><a name="index-nettle_005fsha1-63"></a></var><br>
+&mdash; Constant Struct: struct nettle_hash <b>nettle_sha224</b><var><a name="index-nettle_005fsha224-64"></a></var><br>
+&mdash; Constant Struct: struct nettle_hash <b>nettle_sha256</b><var><a name="index-nettle_005fsha256-65"></a></var><br>
+&mdash; Constant Struct: struct nettle_hash <b>nettle_sha384</b><var><a name="index-nettle_005fsha384-66"></a></var><br>
+&mdash; Constant Struct: struct nettle_hash <b>nettle_sha512</b><var><a name="index-nettle_005fsha512-67"></a></var><br>
+<blockquote>
+        <p>These are all the hash functions that Nettle implements.
+
+        <p>Nettle also exports a list of all these hashes.  This list can be used
+to dynamically enumerate or search the supported algorithms:
+
+   &mdash; Constant Struct: struct nettle_hash ** <b>nettle_hashes</b><var><a name="index-nettle_005fhashes-68"></a></var><br>
+
+        </div>
+
+<div class="node">
+<a name="Cipher-functions"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#Cipher-modes">Cipher modes</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Hash-functions">Hash functions</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Reference">Reference</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h3 class="section">6.2 Cipher functions</h3>
+
+<p><a name="index-Cipher-69"></a>
+A <dfn>cipher</dfn> is a function that takes a message or <dfn>plaintext</dfn>
+and a secret <dfn>key</dfn> and transforms it to a <dfn>ciphertext</dfn>. Given
+only the ciphertext, but not the key, it should be hard to find the
+plaintext. Given matching pairs of plaintext and ciphertext, it should
+be hard to find the key.
+
+   <p><a name="index-Block-Cipher-70"></a><a name="index-Stream-Cipher-71"></a>
+There are two main classes of ciphers: Block ciphers and stream ciphers.
+
+   <p>A block cipher can process data only in fixed size chunks, called
+<dfn>blocks</dfn>. Typical block sizes are 8 or 16 octets. To encrypt
+arbitrary messages, you usually have to pad it to an integral number of
+blocks, split it into blocks, and then process each block. The simplest
+way is to process one block at a time, independent of each other. That
+mode of operation is called <dfn>ECB</dfn>, Electronic Code Book mode. 
+However, using <acronym>ECB</acronym> is usually a bad idea. For a start, plaintext blocks
+that are equal are transformed to ciphertext blocks that are equal; that
+leaks information about the plaintext. Usually you should apply the
+cipher is some &ldquo;feedback mode&rdquo;, <dfn>CBC</dfn> (Cipher Block Chaining) and
+<dfn>CTR</dfn> (Counter mode) being two of
+of the most popular. See See <a href="#Cipher-modes">Cipher modes</a>, for information on
+how to apply <acronym>CBC</acronym> and <acronym>CTR</acronym> with Nettle.
+
+   <p>A stream cipher can be used for messages of arbitrary length. A typical
+stream cipher is a keyed pseudo-random generator. To encrypt a plaintext
+message of <var>n</var> octets, you key the generator, generate <var>n</var>
+octets of pseudo-random data, and XOR it with the plaintext. To decrypt,
+regenerate the same stream using the key, XOR it to the ciphertext, and
+the plaintext is recovered.
+
+   <p><strong>Caution:</strong> The first rule for this kind of cipher is the
+same as for a One Time Pad: <em>never</em> ever use the same key twice.
+
+   <p>A common misconception is that encryption, by itself, implies
+authentication. Say that you and a friend share a secret key, and you
+receive an encrypted message. You apply the key, and get a plaintext
+message that makes sense to you. Can you then be sure that it really was
+your friend that wrote the message you're reading? The answer is no. For
+example, if you were using a block cipher in ECB mode, an attacker may
+pick up the message on its way, and reorder, delete or repeat some of
+the blocks. Even if the attacker can't decrypt the message, he can
+change it so that you are not reading the same message as your friend
+wrote. If you are using a block cipher in <acronym>CBC</acronym> mode rather than
+ECB, or are using a stream cipher, the possibilities for this sort of
+attack are different, but the attacker can still make predictable
+changes to the message.
+
+   <p>It is recommended to <em>always</em> use an authentication mechanism in
+addition to encrypting the messages. Popular choices are Message
+Authentication Codes like <acronym>HMAC-SHA1</acronym> (see <a href="#Keyed-hash-functions">Keyed hash functions</a>), or digital signatures like <acronym>RSA</acronym>.
+
+   <p>Some ciphers have so called &ldquo;weak keys&rdquo;, keys that results in
+undesirable structure after the key setup processing, and should be
+avoided. In Nettle, most key setup functions have no return value, but
+for ciphers with weak keys, the return value indicates whether or not
+the given key is weak. For good keys, key setup returns 1, and for weak
+keys, it returns 0. When possible, avoid algorithms that
+have weak keys. There are several good ciphers that don't have any weak
+keys.
+
+   <p>To encrypt a message, you first initialize a cipher context for
+encryption or decryption with a particular key. You then use the context
+to process plaintext or ciphertext messages. The initialization is known
+as <dfn>key setup</dfn>. With Nettle, it is recommended to use each
+context struct for only one direction, even if some of the ciphers use a
+single key setup function that can be used for both encryption and
+decryption.
+
+<h4 class="subsection">6.2.1 AES</h4>
+
+<p>AES is a block cipher, specified by NIST as a replacement for
+the older DES standard. The standard is the result of a competition
+between cipher designers. The winning design, also known as RIJNDAEL,
+was constructed by Joan Daemen and Vincent Rijnmen.
+
+   <p>Like all the AES candidates, the winning design uses a block size of 128
+bits, or 16 octets, and variable key-size, 128, 192 and 256 bits (16, 24
+and 32 octets) being the allowed key sizes. It does not have any weak
+keys. Nettle defines AES in <samp><span class="file">&lt;nettle/aes.h&gt;</span></samp>.
+
+<div class="defun">
+&mdash; Context struct: <b>struct aes_ctx</b><var><a name="index-struct-aes_005fctx-72"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>AES_BLOCK_SIZE</b><var><a name="index-AES_005fBLOCK_005fSIZE-73"></a></var><br>
+<blockquote><p>The AES block-size, 16
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>AES_MIN_KEY_SIZE</b><var><a name="index-AES_005fMIN_005fKEY_005fSIZE-74"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>AES_MAX_KEY_SIZE</b><var><a name="index-AES_005fMAX_005fKEY_005fSIZE-75"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>AES_KEY_SIZE</b><var><a name="index-AES_005fKEY_005fSIZE-76"></a></var><br>
+<blockquote><p>Default AES key size, 32
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>aes_set_encrypt_key</b> (<var>struct aes_ctx *ctx, unsigned length, const uint8_t *key</var>)<var><a name="index-aes_005fset_005fencrypt_005fkey-77"></a></var><br>
+&mdash; Function: void <b>aes_set_decrypt_key</b> (<var>struct aes_ctx *ctx, unsigned length, const uint8_t *key</var>)<var><a name="index-aes_005fset_005fdecrypt_005fkey-78"></a></var><br>
+<blockquote><p>Initialize the cipher, for encryption or decryption, respectively. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>aes_invert_key</b> (<var>struct aes_ctx *dst, const struct aes_ctx *src</var>)<var><a name="index-aes_005finvert_005fkey-79"></a></var><br>
+<blockquote><p>Given a context <var>src</var> initialized for encryption, initializes the
+context struct <var>dst</var> for decryption, using the same key. If the same
+context struct is passed for both <code>src</code> and <code>dst</code>, it is
+converted in place. Calling <code>aes_set_encrypt_key</code> and
+<code>aes_invert_key</code> is more efficient than calling
+<code>aes_set_encrypt_key</code> and <code>aes_set_decrypt_key</code>. This function
+is mainly useful for applications which needs to both encrypt and
+decrypt using the <em>same</em> key. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>aes_encrypt</b> (<var>struct aes_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-aes_005fencrypt-80"></a></var><br>
+<blockquote><p>Encryption function. <var>length</var> must be an integral multiple of the
+block size. If it is more than one block, the data is processed in ECB
+mode. <code>src</code> and <code>dst</code> may be equal, but they must not overlap
+in any other way. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>aes_decrypt</b> (<var>struct aes_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-aes_005fdecrypt-81"></a></var><br>
+<blockquote><p>Analogous to <code>aes_encrypt</code>
+</p></blockquote></div>
+
+<h4 class="subsection">6.2.2 ARCFOUR</h4>
+
+<p>ARCFOUR is a stream cipher, also known under the trade marked name RC4,
+and it is one of the fastest ciphers around. A problem is that the key
+setup of ARCFOUR is quite weak, you should never use keys with
+structure, keys that are ordinary passwords, or sequences of keys like
+&ldquo;secret:1&rdquo;, &ldquo;secret:2&rdquo;, <small class="enddots">...</small>. If you have keys that don't look
+like random bit strings, and you want to use ARCFOUR, always hash the
+key before feeding it to ARCFOUR. Furthermore, the initial bytes of the
+generated key stream leak information about the key; for this reason, it
+is recommended to discard the first 512 bytes of the key stream.
+
+<pre class="example">     /* A more robust key setup function for ARCFOUR */
+     void
+     arcfour_set_key_hashed(struct arcfour_ctx *ctx,
+                            unsigned length, const uint8_t *key)
+     {
+       struct sha256_ctx hash;
+       uint8_t digest[SHA256_DIGEST_SIZE];
+       uint8_t buffer[0x200];
+     
+       sha256_init(&amp;hash);
+       sha256_update(&amp;hash, length, key);
+       sha256_digest(&amp;hash, SHA256_DIGEST_SIZE, digest);
+     
+       arcfour_set_key(ctx, SHA256_DIGEST_SIZE, digest);
+       arcfour_crypt(ctx, sizeof(buffer), buffer, buffer);
+     }
+</pre>
+   <p>Nettle defines ARCFOUR in <samp><span class="file">&lt;nettle/arcfour.h&gt;</span></samp>.
+
+<div class="defun">
+&mdash; Context struct: <b>struct arcfour_ctx</b><var><a name="index-struct-arcfour_005fctx-82"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>ARCFOUR_MIN_KEY_SIZE</b><var><a name="index-ARCFOUR_005fMIN_005fKEY_005fSIZE-83"></a></var><br>
+<blockquote><p>Minimum key size, 1
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>ARCFOUR_MAX_KEY_SIZE</b><var><a name="index-ARCFOUR_005fMAX_005fKEY_005fSIZE-84"></a></var><br>
+<blockquote><p>Maximum key size, 256
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>ARCFOUR_KEY_SIZE</b><var><a name="index-ARCFOUR_005fKEY_005fSIZE-85"></a></var><br>
+<blockquote><p>Default ARCFOUR key size, 16
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>arcfour_set_key</b> (<var>struct arcfour_ctx *ctx, unsigned length, const uint8_t *key</var>)<var><a name="index-arcfour_005fset_005fkey-86"></a></var><br>
+<blockquote><p>Initialize the cipher. The same function is used for both encryption and
+decryption. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>arcfour_crypt</b> (<var>struct arcfour_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-arcfour_005fcrypt-87"></a></var><br>
+<blockquote><p>Encrypt some data. The same function is used for both encryption and
+decryption. Unlike the block ciphers, this function modifies the
+context, so you can split the data into arbitrary chunks and encrypt
+them one after another. The result is the same as if you had called
+<code>arcfour_crypt</code> only once with all the data. 
+</p></blockquote></div>
+
+<h4 class="subsection">6.2.3 ARCTWO</h4>
+
+<p>ARCTWO (also known as the trade marked name RC2) is a block cipher
+specified in RFC 2268. Nettle also include a variation of the ARCTWO
+set key operation that lack one step, to be compatible with the
+reverse engineered RC2 cipher description, as described in a Usenet
+post to <code>sci.crypt</code> by Peter Gutmann.
+
+   <p>ARCTWO uses a block size of 64 bits, and variable key-size ranging
+from 1 to 128 octets. Besides the key, ARCTWO also has a second
+parameter to key setup, the number of effective key bits, <code>ekb</code>. 
+This parameter can be used to artificially reduce the key size. In
+practice, <code>ekb</code> is usually set equal to the input key size. 
+Nettle defines ARCTWO in <samp><span class="file">&lt;nettle/arctwo.h&gt;</span></samp>.
+
+   <p>We do not recommend the use of ARCTWO; the Nettle implementation is
+provided primarily for interoperability with existing applications and
+standards.
+
+<div class="defun">
+&mdash; Context struct: <b>struct arctwo_ctx</b><var><a name="index-struct-arctwo_005fctx-88"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>ARCTWO_BLOCK_SIZE</b><var><a name="index-ARCTWO_005fBLOCK_005fSIZE-89"></a></var><br>
+<blockquote><p>The ARCTWO block-size, 8
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>ARCTWO_MIN_KEY_SIZE</b><var><a name="index-ARCTWO_005fMIN_005fKEY_005fSIZE-90"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>ARCTWO_MAX_KEY_SIZE</b><var><a name="index-ARCTWO_005fMAX_005fKEY_005fSIZE-91"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>ARCTWO_KEY_SIZE</b><var><a name="index-ARCTWO_005fKEY_005fSIZE-92"></a></var><br>
+<blockquote><p>Default ARCTWO key size, 8
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>arctwo_set_key_ekb</b> (<var>struct arctwo_ctx *ctx, unsigned length, const uint8_t *key, unsigned ekb</var>)<var><a name="index-arctwo_005fset_005fkey_005fekb-93"></a></var><br>
+&mdash; Function: void <b>arctwo_set_key</b> (<var>struct arctwo_ctx *ctx, unsigned length, const uint8_t *key</var>)<var><a name="index-arctwo_005fset_005fkey-94"></a></var><br>
+&mdash; Function: void <b>arctwo_set_key_gutmann</b> (<var>struct arctwo_ctx *ctx, unsigned length, const uint8_t *key</var>)<var><a name="index-arctwo_005fset_005fkey_005fgutmann-95"></a></var><br>
+<blockquote><p>Initialize the cipher. The same function is used for both encryption
+and decryption. The first function is the most general one, which lets
+you provide both the variable size key, and the desired effective key
+size (in bits). The maximum value for <var>ekb</var> is 1024, and for
+convenience, <code>ekb = 0</code> has the same effect as <code>ekb = 1024</code>.
+
+        <p><code>arctwo_set_key(ctx, length, key)</code> is equivalent to
+<code>arctwo_set_key_ekb(ctx, length, key, 8*length)</code>, and
+<code>arctwo_set_key_gutmann(ctx, length, key)</code> is equivalent to
+<code>arctwo_set_key_ekb(ctx, length, key, 1024)</code>
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>arctwo_encrypt</b> (<var>struct arctwo_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-arctwo_005fencrypt-96"></a></var><br>
+<blockquote><p>Encryption function. <var>length</var> must be an integral multiple of the
+block size. If it is more than one block, the data is processed in ECB
+mode. <code>src</code> and <code>dst</code> may be equal, but they must not
+overlap in any other way. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>arctwo_decrypt</b> (<var>struct arctwo_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-arctwo_005fdecrypt-97"></a></var><br>
+<blockquote><p>Analogous to <code>arctwo_encrypt</code>
+</p></blockquote></div>
+
+<h4 class="subsection">6.2.4 BLOWFISH</h4>
+
+<p>BLOWFISH is a block cipher designed by Bruce Schneier. It uses a block
+size of 64 bits (8 octets), and a variable key size, up to 448 bits. It
+has some weak keys. Nettle defines BLOWFISH in <samp><span class="file">&lt;nettle/blowfish.h&gt;</span></samp>.
+
+<div class="defun">
+&mdash; Context struct: <b>struct blowfish_ctx</b><var><a name="index-struct-blowfish_005fctx-98"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>BLOWFISH_BLOCK_SIZE</b><var><a name="index-BLOWFISH_005fBLOCK_005fSIZE-99"></a></var><br>
+<blockquote><p>The BLOWFISH block-size, 8
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>BLOWFISH_MIN_KEY_SIZE</b><var><a name="index-BLOWFISH_005fMIN_005fKEY_005fSIZE-100"></a></var><br>
+<blockquote><p>Minimum BLOWFISH key size, 8
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>BLOWFISH_MAX_KEY_SIZE</b><var><a name="index-BLOWFISH_005fMAX_005fKEY_005fSIZE-101"></a></var><br>
+<blockquote><p>Maximum BLOWFISH key size, 56
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>BLOWFISH_KEY_SIZE</b><var><a name="index-BLOWFISH_005fKEY_005fSIZE-102"></a></var><br>
+<blockquote><p>Default BLOWFISH key size, 16
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: int <b>blowfish_set_key</b> (<var>struct blowfish_ctx *ctx, unsigned length, const uint8_t *key</var>)<var><a name="index-blowfish_005fset_005fkey-103"></a></var><br>
+<blockquote><p>Initialize the cipher. The same function is used for both encryption and
+decryption. Checks for weak keys, returning 1
+for good keys and 0 for weak keys. Applications that don't care about
+weak keys can ignore the return value.
+
+        <p><code>blowfish_encrypt</code> or <code>blowfish_decrypt</code> with a weak key will
+crash with an assert violation. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>blowfish_encrypt</b> (<var>struct blowfish_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-blowfish_005fencrypt-104"></a></var><br>
+<blockquote><p>Encryption function. <var>length</var> must be an integral multiple of the
+block size. If it is more than one block, the data is processed in ECB
+mode. <code>src</code> and <code>dst</code> may be equal, but they must not overlap
+in any other way. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>blowfish_decrypt</b> (<var>struct blowfish_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-blowfish_005fdecrypt-105"></a></var><br>
+<blockquote><p>Analogous to <code>blowfish_encrypt</code>
+</p></blockquote></div>
+
+<h4 class="subsection">6.2.5 Camellia</h4>
+
+<p>Camellia is a block cipher developed by Mitsubishi and Nippon Telegraph
+and Telephone Corporation, described in <cite>RFC3713</cite>, and recommended
+by some Japanese and European authorities as an alternative to AES. The
+algorithm is patented. The implementation in Nettle is derived from the
+implementation released by NTT under the GNU LGPL (v2.1 or later), and
+relies on the implicit patent license of the LGPL. There is also a
+statement of royalty-free licensing for Camellia at
+<a href="http://www.ntt.co.jp/news/news01e/0104/010417.html">http://www.ntt.co.jp/news/news01e/0104/010417.html</a>, but this
+statement has some limitations which seem problematic for free software.
+
+   <p>Camellia uses a the same block size and key sizes as AES: The block size
+is 128 bits (16 octets), and the supported key sizes are 128, 192, and
+256 bits. Nettle defines Camellia in <samp><span class="file">&lt;nettle/camellia.h&gt;</span></samp>.
+
+<div class="defun">
+&mdash; Context struct: <b>struct camellia_ctx</b><var><a name="index-struct-camellia_005fctx-106"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>CAMELLIA_BLOCK_SIZE</b><var><a name="index-CAMELLIA_005fBLOCK_005fSIZE-107"></a></var><br>
+<blockquote><p>The CAMELLIA block-size, 16
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>CAMELLIA_MIN_KEY_SIZE</b><var><a name="index-CAMELLIA_005fMIN_005fKEY_005fSIZE-108"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>CAMELLIA_MAX_KEY_SIZE</b><var><a name="index-CAMELLIA_005fMAX_005fKEY_005fSIZE-109"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>CAMELLIA_KEY_SIZE</b><var><a name="index-CAMELLIA_005fKEY_005fSIZE-110"></a></var><br>
+<blockquote><p>Default CAMELLIA key size, 32
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>camellia_set_encrypt_key</b> (<var>struct camellia_ctx *ctx, unsigned length, const uint8_t *key</var>)<var><a name="index-camellia_005fset_005fencrypt_005fkey-111"></a></var><br>
+&mdash; Function: void <b>camellia_set_decrypt_key</b> (<var>struct camellia_ctx *ctx, unsigned length, const uint8_t *key</var>)<var><a name="index-camellia_005fset_005fdecrypt_005fkey-112"></a></var><br>
+<blockquote><p>Initialize the cipher, for encryption or decryption, respectively. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>camellia_invert_key</b> (<var>struct camellia_ctx *dst, const struct camellia_ctx *src</var>)<var><a name="index-camellia_005finvert_005fkey-113"></a></var><br>
+<blockquote><p>Given a context <var>src</var> initialized for encryption, initializes the
+context struct <var>dst</var> for decryption, using the same key. If the same
+context struct is passed for both <code>src</code> and <code>dst</code>, it is
+converted in place. Calling <code>camellia_set_encrypt_key</code> and
+<code>camellia_invert_key</code> is more efficient than calling
+<code>camellia_set_encrypt_key</code> and <code>camellia_set_decrypt_key</code>. This function
+is mainly useful for applications which needs to both encrypt and
+decrypt using the <em>same</em> key. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>camellia_crypt</b> (<var>struct camellia_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-camellia_005fcrypt-114"></a></var><br>
+<blockquote><p>The same function is used for both encryption and decryption. 
+<var>length</var> must be an integral multiple of the block size. If it is
+more than one block, the data is processed in ECB mode. <code>src</code> and
+<code>dst</code> may be equal, but they must not overlap in any other way. 
+</p></blockquote></div>
+
+<h4 class="subsection">6.2.6 CAST128</h4>
+
+<p>CAST-128 is a block cipher, specified in <cite>RFC 2144</cite>. It uses a 64
+bit (8 octets) block size, and a variable key size of up to 128 bits. 
+Nettle defines cast128 in <samp><span class="file">&lt;nettle/cast128.h&gt;</span></samp>.
+
+<div class="defun">
+&mdash; Context struct: <b>struct cast128_ctx</b><var><a name="index-struct-cast128_005fctx-115"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>CAST128_BLOCK_SIZE</b><var><a name="index-CAST128_005fBLOCK_005fSIZE-116"></a></var><br>
+<blockquote><p>The CAST128 block-size, 8
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>CAST128_MIN_KEY_SIZE</b><var><a name="index-CAST128_005fMIN_005fKEY_005fSIZE-117"></a></var><br>
+<blockquote><p>Minimum CAST128 key size, 5
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>CAST128_MAX_KEY_SIZE</b><var><a name="index-CAST128_005fMAX_005fKEY_005fSIZE-118"></a></var><br>
+<blockquote><p>Maximum CAST128 key size, 16
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>CAST128_KEY_SIZE</b><var><a name="index-CAST128_005fKEY_005fSIZE-119"></a></var><br>
+<blockquote><p>Default CAST128 key size, 16
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>cast128_set_key</b> (<var>struct cast128_ctx *ctx, unsigned length, const uint8_t *key</var>)<var><a name="index-cast128_005fset_005fkey-120"></a></var><br>
+<blockquote><p>Initialize the cipher. The same function is used for both encryption and
+decryption. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>cast128_encrypt</b> (<var>struct cast128_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-cast128_005fencrypt-121"></a></var><br>
+<blockquote><p>Encryption function. <var>length</var> must be an integral multiple of the
+block size. If it is more than one block, the data is processed in ECB
+mode. <code>src</code> and <code>dst</code> may be equal, but they must not overlap
+in any other way. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>cast128_decrypt</b> (<var>struct cast128_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-cast128_005fdecrypt-122"></a></var><br>
+<blockquote><p>Analogous to <code>cast128_encrypt</code>
+</p></blockquote></div>
+
+<h4 class="subsection">6.2.7 DES</h4>
+
+<p>DES is the old Data Encryption Standard, specified by NIST. It uses a
+block size of 64 bits (8 octets), and a key size of 56 bits. However,
+the key bits are distributed over 8 octets, where the least significant
+bit of each octet may be used for parity. A common way to use DES is to
+generate 8 random octets in some way, then set the least significant bit
+of each octet to get odd parity, and initialize DES with the resulting
+key.
+
+   <p>The key size of DES is so small that keys can be found by brute force,
+using specialized hardware or lots of ordinary work stations in
+parallel. One shouldn't be using plain DES at all today, if one uses
+DES at all one should be using &ldquo;triple DES&rdquo;, see DES3 below.
+
+   <p>DES also has some weak keys. Nettle defines DES in <samp><span class="file">&lt;nettle/des.h&gt;</span></samp>.
+
+<div class="defun">
+&mdash; Context struct: <b>struct des_ctx</b><var><a name="index-struct-des_005fctx-123"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>DES_BLOCK_SIZE</b><var><a name="index-DES_005fBLOCK_005fSIZE-124"></a></var><br>
+<blockquote><p>The DES block-size, 8
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>DES_KEY_SIZE</b><var><a name="index-DES_005fKEY_005fSIZE-125"></a></var><br>
+<blockquote><p>DES key size, 8
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: int <b>des_set_key</b> (<var>struct des_ctx *ctx, const uint8_t *key</var>)<var><a name="index-des_005fset_005fkey-126"></a></var><br>
+<blockquote><p>Initialize the cipher. The same function is used for both encryption and
+decryption. Parity bits are ignored. Checks for weak keys, returning 1
+for good keys and 0 for weak keys. Applications that don't care about
+weak keys can ignore the return value. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>des_encrypt</b> (<var>struct des_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-des_005fencrypt-127"></a></var><br>
+<blockquote><p>Encryption function. <var>length</var> must be an integral multiple of the
+block size. If it is more than one block, the data is processed in ECB
+mode. <code>src</code> and <code>dst</code> may be equal, but they must not overlap
+in any other way. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>des_decrypt</b> (<var>struct des_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-des_005fdecrypt-128"></a></var><br>
+<blockquote><p>Analogous to <code>des_encrypt</code>
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: int <b>des_check_parity</b> (<var>unsigned length, const uint8_t *key</var>)<var>;<a name="index-des_005fcheck_005fparity-129"></a></var><br>
+<blockquote><p>Checks that the given key has correct, odd, parity. Returns 1 for
+correct parity, and 0 for bad parity. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>des_fix_parity</b> (<var>unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-des_005ffix_005fparity-130"></a></var><br>
+<blockquote><p>Adjusts the parity bits to match DES's requirements. You need this
+function if you have created a random-looking string by a key agreement
+protocol, and want to use it as a DES key. <var>dst</var> and <var>src</var> may
+be equal. 
+</p></blockquote></div>
+
+<h4 class="subsection">6.2.8 DES3</h4>
+
+<p>The inadequate key size of DES has already been mentioned. One way to
+increase the key size is to pipe together several DES boxes with
+independent keys. It turns out that using two DES ciphers is not as
+secure as one might think, even if the key size of the combination is a
+respectable 112 bits.
+
+   <p>The standard way to increase DES's key size is to use three DES boxes. 
+The mode of operation is a little peculiar: the middle DES box is wired
+in the reverse direction. To encrypt a block with DES3, you encrypt it
+using the first 56 bits of the key, then <em>decrypt</em> it using the
+middle 56 bits of the key, and finally encrypt it again using the last
+56 bits of the key. This is known as &ldquo;ede&rdquo; triple-DES, for
+&ldquo;encrypt-decrypt-encrypt&rdquo;.
+
+   <p>The &ldquo;ede&rdquo; construction provides some backward compatibility, as you get
+plain single DES simply by feeding the same key to all three boxes. That
+should help keeping down the gate count, and the price, of hardware
+circuits implementing both plain DES and DES3.
+
+   <p>DES3 has a key size of 168 bits, but just like plain DES, useless parity
+bits are inserted, so that keys are represented as 24 octets (192 bits). 
+As a 112 bit key is large enough to make brute force attacks
+impractical, some applications uses a &ldquo;two-key&rdquo; variant of triple-DES. 
+In this mode, the same key bits are used for the first and the last DES
+box in the pipe, while the middle box is keyed independently. The
+two-key variant is believed to be secure, i.e. there are no known
+attacks significantly better than brute force.
+
+   <p>Naturally, it's simple to implement triple-DES on top of Nettle's DES
+functions. Nettle includes an implementation of three-key &ldquo;ede&rdquo;
+triple-DES, it is defined in the same place as plain DES,
+<samp><span class="file">&lt;nettle/des.h&gt;</span></samp>.
+
+<div class="defun">
+&mdash; Context struct: <b>struct des3_ctx</b><var><a name="index-struct-des3_005fctx-131"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>DES3_BLOCK_SIZE</b><var><a name="index-DES3_005fBLOCK_005fSIZE-132"></a></var><br>
+<blockquote><p>The DES3 block-size is the same as DES_BLOCK_SIZE, 8
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>DES3_KEY_SIZE</b><var><a name="index-DES3_005fKEY_005fSIZE-133"></a></var><br>
+<blockquote><p>DES key size, 24
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: int <b>des3_set_key</b> (<var>struct des3_ctx *ctx, const uint8_t *key</var>)<var><a name="index-des3_005fset_005fkey-134"></a></var><br>
+<blockquote><p>Initialize the cipher. The same function is used for both encryption and
+decryption. Parity bits are ignored. Checks for weak keys, returning 1
+if all three keys are good keys, and 0 if one or more key is weak. 
+Applications that don't care about weak keys can ignore the return
+value. 
+</p></blockquote></div>
+
+   <p>For random-looking strings, you can use <code>des_fix_parity</code> to adjust
+the parity bits before calling <code>des3_set_key</code>.
+
+<div class="defun">
+&mdash; Function: void <b>des3_encrypt</b> (<var>struct des3_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-des3_005fencrypt-135"></a></var><br>
+<blockquote><p>Encryption function. <var>length</var> must be an integral multiple of the
+block size. If it is more than one block, the data is processed in ECB
+mode. <code>src</code> and <code>dst</code> may be equal, but they must not overlap
+in any other way. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>des3_decrypt</b> (<var>struct des3_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-des3_005fdecrypt-136"></a></var><br>
+<blockquote><p>Analogous to <code>des_encrypt</code>
+</p></blockquote></div>
+
+<h4 class="subsection">6.2.9 SERPENT</h4>
+
+<p>SERPENT is one of the AES finalists, designed by Ross Anderson, Eli
+Biham and Lars Knudsen. Thus, the interface and properties are similar
+to AES'. One peculiarity is that it is quite pointless to use it with
+anything but the maximum key size, smaller keys are just padded to
+larger ones. Nettle defines SERPENT in <samp><span class="file">&lt;nettle/serpent.h&gt;</span></samp>.
+
+<div class="defun">
+&mdash; Context struct: <b>struct serpent_ctx</b><var><a name="index-struct-serpent_005fctx-137"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>SERPENT_BLOCK_SIZE</b><var><a name="index-SERPENT_005fBLOCK_005fSIZE-138"></a></var><br>
+<blockquote><p>The SERPENT block-size, 16
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>SERPENT_MIN_KEY_SIZE</b><var><a name="index-SERPENT_005fMIN_005fKEY_005fSIZE-139"></a></var><br>
+<blockquote><p>Minimum SERPENT key size, 16
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>SERPENT_MAX_KEY_SIZE</b><var><a name="index-SERPENT_005fMAX_005fKEY_005fSIZE-140"></a></var><br>
+<blockquote><p>Maximum SERPENT key size, 32
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>SERPENT_KEY_SIZE</b><var><a name="index-SERPENT_005fKEY_005fSIZE-141"></a></var><br>
+<blockquote><p>Default SERPENT key size, 32
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>serpent_set_key</b> (<var>struct serpent_ctx *ctx, unsigned length, const uint8_t *key</var>)<var><a name="index-serpent_005fset_005fkey-142"></a></var><br>
+<blockquote><p>Initialize the cipher. The same function is used for both encryption and
+decryption. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>serpent_encrypt</b> (<var>struct serpent_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-serpent_005fencrypt-143"></a></var><br>
+<blockquote><p>Encryption function. <var>length</var> must be an integral multiple of the
+block size. If it is more than one block, the data is processed in ECB
+mode. <code>src</code> and <code>dst</code> may be equal, but they must not overlap
+in any other way. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>serpent_decrypt</b> (<var>struct serpent_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-serpent_005fdecrypt-144"></a></var><br>
+<blockquote><p>Analogous to <code>serpent_encrypt</code>
+</p></blockquote></div>
+
+<h4 class="subsection">6.2.10 TWOFISH</h4>
+
+<p>Another AES finalist, this one designed by Bruce Schneier and others. 
+Nettle defines it in <samp><span class="file">&lt;nettle/twofish.h&gt;</span></samp>.
+
+<div class="defun">
+&mdash; Context struct: <b>struct twofish_ctx</b><var><a name="index-struct-twofish_005fctx-145"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Constant: <b>TWOFISH_BLOCK_SIZE</b><var><a name="index-TWOFISH_005fBLOCK_005fSIZE-146"></a></var><br>
+<blockquote><p>The TWOFISH block-size, 16
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>TWOFISH_MIN_KEY_SIZE</b><var><a name="index-TWOFISH_005fMIN_005fKEY_005fSIZE-147"></a></var><br>
+<blockquote><p>Minimum TWOFISH key size, 16
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>TWOFISH_MAX_KEY_SIZE</b><var><a name="index-TWOFISH_005fMAX_005fKEY_005fSIZE-148"></a></var><br>
+<blockquote><p>Maximum TWOFISH key size, 32
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>TWOFISH_KEY_SIZE</b><var><a name="index-TWOFISH_005fKEY_005fSIZE-149"></a></var><br>
+<blockquote><p>Default TWOFISH key size, 32
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>twofish_set_key</b> (<var>struct twofish_ctx *ctx, unsigned length, const uint8_t *key</var>)<var><a name="index-twofish_005fset_005fkey-150"></a></var><br>
+<blockquote><p>Initialize the cipher. The same function is used for both encryption and
+decryption. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>twofish_encrypt</b> (<var>struct twofish_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-twofish_005fencrypt-151"></a></var><br>
+<blockquote><p>Encryption function. <var>length</var> must be an integral multiple of the
+block size. If it is more than one block, the data is processed in ECB
+mode. <code>src</code> and <code>dst</code> may be equal, but they must not overlap
+in any other way. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>twofish_decrypt</b> (<var>struct twofish_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-twofish_005fdecrypt-152"></a></var><br>
+<blockquote><p>Analogous to <code>twofish_encrypt</code>
+</p></blockquote></div>
+
+<!-- @node nettle_cipher, Cipher Block Chaining, Cipher functions, Reference -->
+<!-- @comment  node-name,  next,  previous,  up -->
+<h4 class="subsection">6.2.11 <code>struct nettle_cipher</code></h4>
+
+<p>Nettle includes a struct including information about some of the more
+regular cipher functions. It should be considered a little experimental,
+but can be useful for applications that need a simple way to handle
+various algorithms. Nettle defines these structs in
+<samp><span class="file">&lt;nettle/nettle-meta.h&gt;</span></samp>.
+
+<div class="defun">
+&mdash; Meta struct: <code>struct nettle_cipher</code><var> name context_size block_size key_size set_encrypt_key set_decrypt_key encrypt decrypt<a name="index-g_t_0040code_007bstruct-nettle_005fcipher_007d-153"></a></var><br>
+<blockquote><p>The last four attributes are function pointers, of types
+<code>nettle_set_key_func</code> and <code>nettle_crypt_func</code>. The first
+argument to these functions is a <code>void *</code> pointer to a context
+struct, which is of size <code>context_size</code>. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant Struct: struct nettle_cipher <b>nettle_aes128</b><var><a name="index-nettle_005faes128-154"></a></var><br>
+&mdash; Constant Struct: struct nettle_cipher <b>nettle_aes192</b><var><a name="index-nettle_005faes192-155"></a></var><br>
+&mdash; Constant Struct: struct nettle_cipher <b>nettle_aes256</b><var><a name="index-nettle_005faes256-156"></a></var><br>
+
+   &mdash; Constant Struct: struct nettle_cipher <b>nettle_arctwo40;</b><var><a name="index-nettle_005farctwo40_003b-157"></a></var><br>
+&mdash; Constant Struct: struct nettle_cipher <b>nettle_arctwo64;</b><var><a name="index-nettle_005farctwo64_003b-158"></a></var><br>
+&mdash; Constant Struct: struct nettle_cipher <b>nettle_arctwo128;</b><var><a name="index-nettle_005farctwo128_003b-159"></a></var><br>
+&mdash; Constant Struct: struct nettle_cipher <b>nettle_arctwo_gutmann128;</b><var><a name="index-nettle_005farctwo_005fgutmann128_003b-160"></a></var><br>
+
+   &mdash; Constant Struct: struct nettle_cipher <b>nettle_arcfour128</b><var><a name="index-nettle_005farcfour128-161"></a></var><br>
+
+   &mdash; Constant Struct: struct nettle_cipher <b>nettle_camellia128</b><var><a name="index-nettle_005fcamellia128-162"></a></var><br>
+&mdash; Constant Struct: struct nettle_cipher <b>nettle_camellia192</b><var><a name="index-nettle_005fcamellia192-163"></a></var><br>
+&mdash; Constant Struct: struct nettle_cipher <b>nettle_camellia256</b><var><a name="index-nettle_005fcamellia256-164"></a></var><br>
+
+   &mdash; Constant Struct: struct nettle_cipher <b>nettle_cast128</b><var><a name="index-nettle_005fcast128-165"></a></var><br>
+
+   &mdash; Constant Struct: struct nettle_cipher <b>nettle_serpent128</b><var><a name="index-nettle_005fserpent128-166"></a></var><br>
+&mdash; Constant Struct: struct nettle_cipher <b>nettle_serpent192</b><var><a name="index-nettle_005fserpent192-167"></a></var><br>
+&mdash; Constant Struct: struct nettle_cipher <b>nettle_serpent256</b><var><a name="index-nettle_005fserpent256-168"></a></var><br>
+
+   &mdash; Constant Struct: struct nettle_cipher <b>nettle_twofish128</b><var><a name="index-nettle_005ftwofish128-169"></a></var><br>
+&mdash; Constant Struct: struct nettle_cipher <b>nettle_twofish192</b><var><a name="index-nettle_005ftwofish192-170"></a></var><br>
+&mdash; Constant Struct: struct nettle_cipher <b>nettle_twofish256</b><var><a name="index-nettle_005ftwofish256-171"></a></var><br>
+<blockquote>
+        <p>Nettle includes such structs for all the <em>regular</em> ciphers, i.e. 
+ones without weak keys or other oddities.
+
+        <p>Nettle also exports a list of all these ciphers without weak keys or
+other oddities.  This list can be used to dynamically enumerate or
+search the supported algorithms:
+
+   &mdash; Constant Struct: struct nettle_cipher ** <b>nettle_ciphers</b><var><a name="index-nettle_005fciphers-172"></a></var><br>
+
+        </div>
+
+<div class="node">
+<a name="Cipher-modes"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#Keyed-hash-functions">Keyed hash functions</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Cipher-functions">Cipher functions</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Reference">Reference</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h3 class="section">6.3 Cipher modes</h3>
+
+<p>Cipher modes of operation specifies the procedure to use when encrypting
+a message that is larger than the cipher's block size. As explained in
+See <a href="#Cipher-functions">Cipher functions</a>, splitting the message into blocks and
+processing them independently with the block cipher (Electronic Code
+Book mode, <acronym>ECB</acronym>) leaks information. Besides <acronym>ECB</acronym>,
+Nettle provides three other modes of operation: Cipher Block Chaining
+(<acronym>CBC</acronym>), Counter mode (<acronym>CTR</acronym>), and Galois/Counter mode
+(<acronym>gcm</acronym>). <acronym>CBC</acronym> is widely used, but there are a few
+subtle issues of information leakage, see, e.g.,
+<a href="http://www.kb.cert.org/vuls/id/958563"><acronym>SSH</acronym> <acronym>CBC</acronym> vulnerability</a>. <acronym>CTR</acronym> and <acronym>GCM</acronym>
+were standardized more recently, and are believed to be more secure. 
+<acronym>GCM</acronym> includes message authentication; for the other modes, one
+should always use a <acronym>MAC</acronym> (see <a href="#Keyed-hash-functions">Keyed hash functions</a>) or
+signature to authenticate the message.
+
+<ul class="menu">
+<li><a accesskey="1" href="#CBC">CBC</a>
+<li><a accesskey="2" href="#CTR">CTR</a>
+<li><a accesskey="3" href="#GCM">GCM</a>
+</ul>
+
+<div class="node">
+<a name="CBC"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#CTR">CTR</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Cipher-modes">Cipher modes</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Cipher-modes">Cipher modes</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h4 class="subsection">6.3.1 Cipher Block Chaining</h4>
+
+<p><a name="index-Cipher-Block-Chaining-173"></a><a name="index-CBC-Mode-174"></a>
+When using <acronym>CBC</acronym> mode, plaintext blocks are not encrypted
+independently of each other, like in Electronic Cook Book mode. Instead,
+when encrypting a block in <acronym>CBC</acronym> mode, the previous ciphertext
+block is XORed with the plaintext before it is fed to the block cipher. 
+When encrypting the first block, a random block called an <dfn>IV</dfn>, or
+Initialization Vector, is used as the &ldquo;previous ciphertext block&rdquo;. The
+IV should be chosen randomly, but it need not be kept secret, and can
+even be transmitted in the clear together with the encrypted data.
+
+   <p>In symbols, if <code>E_k</code> is the encryption function of a block cipher,
+and <code>IV</code> is the initialization vector, then <code>n</code> plaintext blocks
+<code>M_1</code>,<small class="dots">...</small> <code>M_n</code> are transformed into <code>n</code> ciphertext blocks
+<code>C_1</code>,<small class="dots">...</small> <code>C_n</code> as follows:
+
+<pre class="example">     C_1 = E_k(IV  XOR M_1)
+     C_2 = E_k(C_1 XOR M_2)
+     
+     ...
+     
+     C_n = E_k(C_(n-1) XOR M_n)
+</pre>
+   <p>Nettle's includes two functions for applying a block cipher in Cipher
+Block Chaining (<acronym>CBC</acronym>) mode, one for encryption and one for
+decryption. These functions uses <code>void *</code> to pass cipher contexts
+around.
+
+<div class="defun">
+&mdash; Function: void <b>cbc_encrypt</b> (<var>void *ctx, nettle_crypt_func f, unsigned block_size, uint8_t *iv, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-cbc_005fencrypt-175"></a></var><br>
+&mdash; Function: void <b>cbc_decrypt</b> (<var>void *ctx, void </var>(<var>*f</var>)()<var>, unsigned block_size, uint8_t *iv, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-cbc_005fdecrypt-176"></a></var><br>
+<blockquote>
+        <p>Applies the encryption or decryption function <var>f</var> in <acronym>CBC</acronym>
+mode. The final ciphertext block processed is copied into <var>iv</var>
+before returning, so that large message be processed be a sequence of
+calls to <code>cbc_encrypt</code>. The function <var>f</var> is of type
+
+        <p><code>void f (void *</code><var>ctx</var><code>, unsigned </code><var>length</var><code>, uint8_t </code><var>dst</var><code>,
+const uint8_t *</code><var>src</var><code>)</code>,
+
+     <p class="noindent">and the <code>cbc_encrypt</code> and <code>cbc_decrypt</code> functions pass their
+argument <var>ctx</var> on to <var>f</var>. 
+</p></blockquote></div>
+
+   <p>There are also some macros to help use these functions correctly.
+
+<div class="defun">
+&mdash; Macro: <b>CBC_CTX</b> (<var>context_type, block_size</var>)<var><a name="index-CBC_005fCTX-177"></a></var><br>
+<blockquote><p>Expands to
+     <pre class="example">          {
+             context_type ctx;
+             uint8_t iv[block_size];
+          }
+</pre>
+        </blockquote></div>
+
+   <p>It can be used to define a <acronym>CBC</acronym> context struct, either directly,
+
+<pre class="example">     struct CBC_CTX(struct aes_ctx, AES_BLOCK_SIZE) ctx;
+</pre>
+   <p>or to give it a struct tag,
+
+<pre class="example">     struct aes_cbc_ctx CBC_CTX (struct aes_ctx, AES_BLOCK_SIZE);
+</pre>
+   <div class="defun">
+&mdash; Macro: <b>CBC_SET_IV</b> (<var>ctx, iv</var>)<var><a name="index-CBC_005fSET_005fIV-178"></a></var><br>
+<blockquote><p>First argument is a pointer to a context struct as defined by <code>CBC_CTX</code>,
+and the second is a pointer to an Initialization Vector (IV) that is
+copied into that context. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Macro: <b>CBC_ENCRYPT</b> (<var>ctx, f, length, dst, src</var>)<var><a name="index-CBC_005fENCRYPT-179"></a></var><br>
+&mdash; Macro: <b>CBC_DECRYPT</b> (<var>ctx, f, length, dst, src</var>)<var><a name="index-CBC_005fDECRYPT-180"></a></var><br>
+<blockquote><p>A simpler way to invoke <code>cbc_encrypt</code> and <code>cbc_decrypt</code>. The
+first argument is a pointer to a context struct as defined by
+<code>CBC_CTX</code>, and the second argument is an encryption or decryption
+function following Nettle's conventions. The last three arguments define
+the source and destination area for the operation. 
+</p></blockquote></div>
+
+   <p>These macros use some tricks to make the compiler display a warning if
+the types of <var>f</var> and <var>ctx</var> don't match, e.g. if you try to use
+an <code>struct aes_ctx</code> context with the <code>des_encrypt</code> function.
+
+<div class="node">
+<a name="CTR"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#GCM">GCM</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#CBC">CBC</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Cipher-modes">Cipher modes</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h4 class="subsection">6.3.2 Counter mode</h4>
+
+<p><a name="index-Counter-Mode-181"></a><a name="index-CTR-Mode-182"></a>
+Counter mode (<acronym>CTR</acronym>) uses the block cipher as a keyed
+pseudo-random generator. The output of the generator is XORed with the
+data to be encrypted. It can be understood as a way to transform a block
+cipher to a stream cipher.
+
+   <p>The message is divided into <code>n</code> blocks <code>M_1</code>,<small class="dots">...</small>
+<code>M_n</code>, where <code>M_n</code> is of size <code>m</code> which may be smaller
+than the block size. Except for the last block, all the message blocks
+must be of size equal to the cipher's block size.
+
+   <p>If <code>E_k</code> is the encryption function of a block cipher, <code>IC</code> is
+the initial counter, then the <code>n</code> plaintext blocks are
+transformed into <code>n</code> ciphertext blocks <code>C_1</code>,<small class="dots">...</small>
+<code>C_n</code> as follows:
+
+<pre class="example">     C_1 = E_k(IC) XOR M_1
+     C_2 = E_k(IC + 1) XOR M_2
+     
+     ...
+     
+     C_(n-1) = E_k(IC + n - 2) XOR M_(n-1)
+     C_n = E_k(IC + n - 1) [1..m] XOR M_n
+</pre>
+   <p>The <acronym>IC</acronym> is the initial value for the counter, it plays a
+similar role as the <acronym>IV</acronym> for <acronym>CBC</acronym>. When adding,
+<code>IC + x</code>, <acronym>IC</acronym> is interpreted as an integer, in network
+byte order. For the last block, <code>E_k(IC + n - 1) [1..m]</code> means that
+the cipher output is truncated to <code>m</code> bytes.
+
+<div class="defun">
+&mdash; Function: void <b>ctr_crypt</b> (<var>void *ctx, nettle_crypt_func f, unsigned block_size, uint8_t *ctr, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-ctr_005fcrypt-183"></a></var><br>
+<blockquote>
+        <p>Applies the encryption function <var>f</var> in <acronym>CTR</acronym> mode. Note that
+for <acronym>CTR</acronym> mode, encryption and decryption is the same operation,
+and hence <var>f</var> should always be the encryption function for the
+underlying block cipher.
+
+        <p>When a message is encrypted using a sequence of calls to
+<code>ctr_crypt</code>, all but the last call <em>must</em> use a length that is
+a multiple of the block size. 
+</p></blockquote></div>
+
+   <p>Like for <acronym>CBC</acronym>, there are also a couple of helper macros.
+
+<div class="defun">
+&mdash; Macro: <b>CTR_CTX</b> (<var>context_type, block_size</var>)<var><a name="index-CTR_005fCTX-184"></a></var><br>
+<blockquote><p>Expands to
+     <pre class="example">          {
+             context_type ctx;
+             uint8_t ctr[block_size];
+          }
+</pre>
+        </blockquote></div>
+
+<div class="defun">
+&mdash; Macro: <b>CTR_SET_COUNTER</b> (<var>ctx, iv</var>)<var><a name="index-CTR_005fSET_005fCOUNTER-185"></a></var><br>
+<blockquote><p>First argument is a pointer to a context struct as defined by
+<code>CTR_CTX</code>, and the second is a pointer to an initial counter that
+is copied into that context. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Macro: <b>CTR_CRYPT</b> (<var>ctx, f, length, dst, src</var>)<var><a name="index-CTR_005fCRYPT-186"></a></var><br>
+<blockquote><p>A simpler way to invoke <code>ctr_crypt</code>. The first argument is a
+pointer to a context struct as defined by <code>CTR_CTX</code>, and the second
+argument is an encryption function following Nettle's conventions. The
+last three arguments define the source and destination area for the
+operation. 
+</p></blockquote></div>
+
+<div class="node">
+<a name="GCM"></a>
+<p><hr>
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#CTR">CTR</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Cipher-modes">Cipher modes</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h4 class="subsection">6.3.3 Galois counter mode</h4>
+
+<p><a name="index-Galois-Counter-Mode-187"></a><a name="index-GCM-188"></a>
+Galois counter mode is the combination of counter mode with message
+authentication based on universal hashing. The main objective of the
+design is to provide high performance for hardware implementations,
+where other popular <acronym>MAC</acronym> algorithms (see <a href="#Keyed-hash-functions">Keyed hash functions</a> becomes a bottleneck for high-speed hardware implementations. 
+It was proposed by David A. McGrew and John Viega in 2005, and
+recommended by NIST in 2007,
+<a href="http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf">NIST Special Publication 800-38D</a>. It is constructed on top of a block
+cipher which must have a block size of 128 bits.
+
+   <p><acronym>GCM</acronym> is applied to messages of arbitrary length. The inputs
+are:
+
+     <ul>
+<li>A key, which can be used for many messages. 
+<li>An initialization vector (<acronym>IV</acronym>) which <em>must</em> be unique for
+each message. 
+<li>Additional authenticated data, which is to be included in the message
+authentication, but not encrypted. May be empty. 
+<li>The plaintext. Maybe empty. 
+</ul>
+
+   <p>The outputs are a ciphertext, of the same length as the plaintext, and a
+message digest of length 128 bits. Nettle's support for <acronym>GCM</acronym>
+consists of a low-level general interface, some convenience macros, and
+specific functions for <acronym>GCM</acronym> using <acronym>AES</acronym> as the
+underlying cipher. These interfaces are defined in <samp><span class="file">&lt;nettle/gcm.h&gt;</span></samp>
+
+<h5 class="subsubsection">6.3.3.1 General <acronym>GCM</acronym> interface</h5>
+
+<div class="defun">
+&mdash; Context struct: <b>struct gcm_key</b><var><a name="index-struct-gcm_005fkey-189"></a></var><br>
+<blockquote><p>Message independent hash subkey, and related tables. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Context struct: <b>struct gcm_ctx</b><var><a name="index-struct-gcm_005fctx-190"></a></var><br>
+<blockquote><p>Holds state corresponding to a particular message. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>GCM_BLOCK_SIZE</b><var><a name="index-GCM_005fBLOCK_005fSIZE-191"></a></var><br>
+<blockquote><p><acronym>GCM</acronym>'s block size, 16. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>GCM_IV_SIZE</b><var><a name="index-GCM_005fIV_005fSIZE-192"></a></var><br>
+<blockquote><p>Recommended size of the <acronym>IV</acronym>, 12. Other sizes are allowed. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>gcm_set_key</b> (<var>struct gcm_key *key, void *cipher, nettle_crypt_func *f</var>)<var><a name="index-gcm_005fset_005fkey-193"></a></var><br>
+<blockquote><p>Initializes <var>key</var>. <var>cipher</var> gives a context struct for the
+underlying cipher, which must have been previously initialized for
+encryption, and <var>f</var> is the encryption function. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>gcm_set_iv</b> (<var>struct gcm_ctx *ctx, const struct gcm_key *key, unsigned length, const uint8_t *iv</var>)<var><a name="index-gcm_005fset_005fiv-194"></a></var><br>
+<blockquote><p>Initializes <var>ctx</var> using the given <acronym>IV</acronym>. The <var>key</var>
+argument is actually needed only if <var>length</var> differs from
+<code>GCM_IV_SIZE</code>. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>gcm_update</b> (<var>struct gcm_ctx *ctx, const struct gcm_key *key, unsigned length, const uint8_t *data</var>)<var><a name="index-gcm_005fupdate-195"></a></var><br>
+<blockquote><p>Provides associated data to be authenticated. If used, must be called
+before <code>gcm_encrypt</code> or <code>gcm_decrypt</code>. All but the last call
+for each message <em>must</em> use a length that is a multiple of the
+block size. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>gcm_encrypt</b> (<var>struct gcm_ctx *ctx, const struct gcm_key *key void *cipher, nettle_crypt_func *f, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-gcm_005fencrypt-196"></a></var><br>
+&mdash; Function: void <b>gcm_decrypt</b> (<var>struct gcm_ctx *ctx, const struct gcm_key *key, void *cipher, nettle_crypt_func *f, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-gcm_005fdecrypt-197"></a></var><br>
+<blockquote><p>Encrypts or decrypts the data of a message. <var>cipher</var> is the context
+struct for the underlying cipher and <var>f</var> is the encryption function. 
+All but the last call for each message <em>must</em> use a length that is
+a multiple of the block size. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>gcm_digest</b> (<var>struct gcm_ctx *ctx, const struct gcm_key *key, void *cipher, nettle_crypt_func *f, unsigned length, uint8_t *digest</var>)<var><a name="index-gcm_005fdigest-198"></a></var><br>
+<blockquote><p>Extracts the message digest (also known &ldquo;authentication tag&rdquo;). This is
+the final operation when processing a message. <var>length</var> is usually
+equal to <code>GCM_BLOCK_SIZE</code>, but if you provide a smaller value,
+only the first <var>length</var> octets of the digest are written. 
+</p></blockquote></div>
+
+   <p>To encrypt a message using <acronym>GCM</acronym>, first initialize a context for
+the underlying block cipher with a key to use for encryption. Then call
+the above functions in the following order: <code>gcm_set_key</code>,
+<code>gcm_set_iv</code>, <code>gcm_update</code>, <code>gcm_encrypt</code>,
+<code>gcm_digest</code>. The decryption procedure is analogous, just calling
+<code>gcm_decrypt</code> instead of <code>gcm_encrypt</code> (note that
+<acronym>GCM</acronym> decryption still uses the encryption function of the
+underlying block cipher). To process a new message, using the same key,
+call <code>gcm_set_iv</code> with a new <acronym>iv</acronym>.
+
+<h5 class="subsubsection">6.3.3.2 <acronym>GCM</acronym> helper macros</h5>
+
+<p>The following macros are defined.
+
+<div class="defun">
+&mdash; Macro: <b>GCM_CTX</b> (<var>context_type</var>)<var><a name="index-GCM_005fCTX-199"></a></var><br>
+<blockquote><p>This defines an all-in-one context struct, including the context of the
+underlying cipher, the hash subkey, and the per-message state. It expands
+to
+     <pre class="example">          {
+             context_type cipher;
+             struct gcm_key key;
+             struct gcm_ctx gcm;
+          }
+</pre>
+        </blockquote></div>
+
+   <p>Example use:
+<pre class="example">     struct gcm_aes_ctx GCM_CTX(struct aes_ctx);
+</pre>
+   <p>The following macros operate on context structs of this form.
+
+<div class="defun">
+&mdash; Macro: <b>GCM_SET_KEY</b> (<var>ctx, set_key, encrypt, length, data</var>)<var><a name="index-GCM_005fSET_005fKEY-200"></a></var><br>
+<blockquote><p>First argument, <var>ctx</var>, is a context struct as defined
+by <code>GCM_CTX</code>. <var>set_key</var> and <var>encrypt</var> are functions for
+setting the encryption key and for encrypting data using the underlying
+cipher. <var>length</var> and <var>data</var> give the key. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Macro: <b>GCM_SET_IV</b> (<var>ctx, length, data</var>)<var><a name="index-GCM_005fSET_005fIV-201"></a></var><br>
+<blockquote><p>First argument is a context struct as defined by
+<code>GCM_CTX</code>. <var>length</var> and <var>data</var> give the initialization
+vector (<acronym>IV</acronym>). 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Macro: <b>GCM_UPDATE</b> (<var>ctx, length, data</var>)<var><a name="index-GCM_005fUPDATE-202"></a></var><br>
+<blockquote><p>Simpler way to call <code>gcm_update</code>. First argument is a context
+struct as defined by <code>GCM_CTX</code>
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Macro: <b>GCM_ENCRYPT</b> (<var>ctx, encrypt, length, dst, src</var>)<var><a name="index-GCM_005fENCRYPT-203"></a></var><br>
+&mdash; Macro: <b>GCM_DECRYPT</b> (<var>ctx, encrypt, length, dst, src</var>)<var><a name="index-GCM_005fDECRYPT-204"></a></var><br>
+&mdash; Macro: <b>GCM_DIGEST</b> (<var>ctx, encrypt, length, digest</var>)<var><a name="index-GCM_005fDIGEST-205"></a></var><br>
+<blockquote><p>Simpler way to call <code>gcm_encrypt</code>, <code>gcm_decrypt</code> or
+<code>gcm_digest</code>. First argument is a context struct as defined by
+<code>GCM_CTX</code>. Second argument, <var>encrypt</var>, is a pointer to the
+encryption function of the underlying cipher. 
+</p></blockquote></div>
+
+<h5 class="subsubsection">6.3.3.3 <acronym>GCM</acronym>-<acronym>AES</acronym> interface</h5>
+
+<p>The following functions implement the common case of <acronym>GCM</acronym> using
+<acronym>AES</acronym> as the underlying cipher.
+
+<div class="defun">
+&mdash; Context struct: <b>struct gcm_aes_ctx</b><var><a name="index-struct-gcm_005faes_005fctx-206"></a></var><br>
+<blockquote><p>The context struct, defined using <code>GCM_CTX</code>. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>gcm_aes_set_key</b> (<var>struct gcm_aes_ctx *ctx, unsigned length, const uint8_t *key</var>)<var><a name="index-gcm_005faes_005fset_005fkey-207"></a></var><br>
+<blockquote><p>Initializes <var>ctx</var> using the given key. All valid <acronym>AES</acronym> key
+sizes can be used. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>gcm_aes_set_iv</b> (<var>struct gcm_aes_ctx *ctx, unsigned length, const uint8_t *iv</var>)<var><a name="index-gcm_005faes_005fset_005fiv-208"></a></var><br>
+<blockquote><p>Initializes the per-message state, using the given <acronym>IV</acronym>. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>gcm_aes_update</b> (<var>struct gcm_aes_ctx *ctx, unsigned length, const uint8_t *data</var>)<var><a name="index-gcm_005faes_005fupdate-209"></a></var><br>
+<blockquote><p>Provides associated data to be authenticated. If used, must be called
+before <code>gcm_aes_encrypt</code> or <code>gcm_aes_decrypt</code>. All but the last call
+for each message <em>must</em> use a length that is a multiple of the
+block size. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>gcm_aes_encrypt</b> (<var>struct gcm_aes_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-gcm_005faes_005fencrypt-210"></a></var><br>
+&mdash; Function: void <b>gcm_aes_decrypt</b> (<var>struct gcm_aes_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src</var>)<var><a name="index-gcm_005faes_005fdecrypt-211"></a></var><br>
+<blockquote><p>Encrypts or decrypts the data of a message. All but the last call for
+each message <em>must</em> use a length that is a multiple of the block
+size.
+
+        </blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>gcm_aes_digest</b> (<var>struct gcm_aes_ctx *ctx, unsigned length, uint8_t *digest</var>)<var><a name="index-gcm_005faes_005fdigest-212"></a></var><br>
+<blockquote><p>Extracts the message digest (also known &ldquo;authentication tag&rdquo;). This is
+the final operation when processing a message. <var>length</var> is usually
+equal to <code>GCM_BLOCK_SIZE</code>, but if you provide a smaller value,
+only the first <var>length</var> octets of the digest are written. 
+</p></blockquote></div>
+
+<div class="node">
+<a name="Keyed-hash-functions"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#Public_002dkey-algorithms">Public-key algorithms</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Cipher-modes">Cipher modes</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Reference">Reference</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h3 class="section">6.4 Keyed Hash Functions</h3>
+
+<p><a name="index-Keyed-Hash-Function-213"></a><a name="index-Message-Authentication-Code-214"></a><a name="index-MAC-215"></a>
+A <dfn>keyed hash function</dfn>, or <dfn>Message Authentication Code</dfn>
+(<acronym>MAC</acronym>) is a function that takes a key and a message, and
+produces fixed size <acronym>MAC</acronym>. It should be hard to compute a
+message and a matching <acronym>MAC</acronym> without knowledge of the key. It
+should also be hard to compute the key given only messages and
+corresponding <acronym>MAC</acronym>s.
+
+   <p>Keyed hash functions are useful primarily for message authentication,
+when Alice and Bob shares a secret: The sender, Alice, computes the
+<acronym>MAC</acronym> and attaches it to the message. The receiver, Bob, also computes
+the <acronym>MAC</acronym> of the message, using the same key, and compares that
+to Alice's value. If they match, Bob can be assured that
+the message has not been modified on its way from Alice.
+
+   <p>However, unlike digital signatures, this assurance is not transferable. 
+Bob can't show the message and the <acronym>MAC</acronym> to a third party and
+prove that Alice sent that message. Not even if he gives away the key to
+the third party. The reason is that the <em>same</em> key is used on both
+sides, and anyone knowing the key can create a correct <acronym>MAC</acronym> for
+any message. If Bob believes that only he and Alice knows the key, and
+he knows that he didn't attach a <acronym>MAC</acronym> to a particular message,
+he knows it must be Alice who did it. However, the third party can't
+distinguish between a <acronym>MAC</acronym> created by Alice and one created by
+Bob.
+
+   <p>Keyed hash functions are typically a lot faster than digital signatures
+as well.
+
+<h4 class="subsection">6.4.1 <acronym>HMAC</acronym></h4>
+
+<p>One can build keyed hash functions from ordinary hash functions. Older
+constructions simply concatenate secret key and message and hashes that, but
+such constructions have weaknesses. A better construction is
+<acronym>HMAC</acronym>, described in <cite>RFC 2104</cite>.
+
+   <p>For an underlying hash function <code>H</code>, with digest size <code>l</code> and
+internal block size <code>b</code>, <acronym>HMAC-H</acronym> is constructed as
+follows: From a given key <code>k</code>, two distinct subkeys <code>k_i</code> and
+<code>k_o</code> are constructed, both of length <code>b</code>. The
+<acronym>HMAC-H</acronym> of a message <code>m</code> is then computed as <code>H(k_o |
+H(k_i | m))</code>, where <code>|</code> denotes string concatenation.
+
+   <p><acronym>HMAC</acronym> keys can be of any length, but it is recommended to use
+keys of length <code>l</code>, the digest size of the underlying hash function
+<code>H</code>. Keys that are longer than <code>b</code> are shortened to length
+<code>l</code> by hashing with <code>H</code>, so arbitrarily long keys aren't
+very useful.
+
+   <p>Nettle's <acronym>HMAC</acronym> functions are defined in <samp><span class="file">&lt;nettle/hmac.h&gt;</span></samp>. 
+There are abstract functions that use a pointer to a <code>struct
+nettle_hash</code> to represent the underlying hash function and <code>void *</code>
+pointers that point to three different context structs for that hash
+function. There are also concrete functions for <acronym>HMAC-MD5</acronym>,
+<acronym>HMAC-RIPEMD160</acronym> <acronym>HMAC-SHA1</acronym>, <acronym>HMAC-SHA256</acronym>, and
+<acronym>HMAC-SHA512</acronym>. First, the abstract functions:
+
+<div class="defun">
+&mdash; Function: void <b>hmac_set_key</b> (<var>void *outer, void *inner, void *state, const struct nettle_hash *H, unsigned length, const uint8_t *key</var>)<var><a name="index-hmac_005fset_005fkey-216"></a></var><br>
+<blockquote><p>Initializes the three context structs from the key. The <var>outer</var> and
+<var>inner</var> contexts corresponds to the subkeys <code>k_o</code> and
+<code>k_i</code>. <var>state</var> is used for hashing the message, and is
+initialized as a copy of the <var>inner</var> context. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>hmac_update</b> (<var>void *state, const struct nettle_hash *H, unsigned length, const uint8_t *data</var>)<var><a name="index-hmac_005fupdate-217"></a></var><br>
+<blockquote><p>This function is called zero or more times to process the message. 
+Actually, <code>hmac_update(state, H, length, data)</code> is equivalent to
+<code>H-&gt;update(state, length, data)</code>, so if you wish you can use the
+ordinary update function of the underlying hash function instead. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>hmac_digest</b> (<var>const void *outer, const void *inner, void *state, const struct nettle_hash *H, unsigned length, uint8_t *digest</var>)<var><a name="index-hmac_005fdigest-218"></a></var><br>
+<blockquote><p>Extracts the <acronym>MAC</acronym> of the message, writing it to <var>digest</var>. 
+<var>outer</var> and <var>inner</var> are not modified. <var>length</var> is usually
+equal to <code>H-&gt;digest_size</code>, but if you provide a smaller value,
+only the first <var>length</var> octets of the <acronym>MAC</acronym> are written.
+
+        <p>This function also resets the <var>state</var> context so that you can start
+over processing a new message (with the same key). 
+</p></blockquote></div>
+
+   <p>Like for <acronym>CBC</acronym>, there are some macros to help use these
+functions correctly.
+
+<div class="defun">
+&mdash; Macro: <b>HMAC_CTX</b> (<var>type</var>)<var><a name="index-HMAC_005fCTX-219"></a></var><br>
+<blockquote><p>Expands to
+     <pre class="example">          {
+             type outer;
+             type inner;
+             type state;
+          }
+</pre>
+        </blockquote></div>
+
+   <p>It can be used to define a <acronym>HMAC</acronym> context struct, either
+directly,
+
+<pre class="example">     struct HMAC_CTX(struct md5_ctx) ctx;
+</pre>
+   <p>or to give it a struct tag,
+
+<pre class="example">     struct hmac_md5_ctx HMAC_CTX (struct md5_ctx);
+</pre>
+   <div class="defun">
+&mdash; Macro: <b>HMAC_SET_KEY</b> (<var>ctx, H, length, key</var>)<var><a name="index-HMAC_005fSET_005fKEY-220"></a></var><br>
+<blockquote><p><var>ctx</var> is a pointer to a context struct as defined by
+<code>HMAC_CTX</code>, <var>H</var> is a pointer to a <code>const struct
+nettle_hash</code> describing the underlying hash function (so it must match
+the type of the components of <var>ctx</var>). The last two arguments specify
+the secret key. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Macro: <b>HMAC_DIGEST</b> (<var>ctx, H, length, digest</var>)<var><a name="index-HMAC_005fDIGEST-221"></a></var><br>
+<blockquote><p><var>ctx</var> is a pointer to a context struct as defined by
+<code>HMAC_CTX</code>, <var>H</var> is a pointer to a <code>const struct
+nettle_hash</code> describing the underlying hash function. The last two
+arguments specify where the digest is written. 
+</p></blockquote></div>
+
+   <p>Note that there is no <code>HMAC_UPDATE</code> macro; simply call
+<code>hmac_update</code> function directly, or the update function of the
+underlying hash function.
+
+<h4 class="subsection">6.4.2 Concrete <acronym>HMAC</acronym> functions</h4>
+
+<p>Now we come to the specialized <acronym>HMAC</acronym> functions, which are
+easier to use than the general <acronym>HMAC</acronym> functions.
+
+<h5 class="subsubsection">6.4.2.1 <acronym>HMAC-MD5</acronym></h5>
+
+<div class="defun">
+&mdash; Context struct: <b>struct hmac_md5_ctx</b><var><a name="index-struct-hmac_005fmd5_005fctx-222"></a></var><br>
+     </div>
+
+<div class="defun">
+&mdash; Function: void <b>hmac_md5_set_key</b> (<var>struct hmac_md5_ctx *ctx, unsigned key_length, const uint8_t *key</var>)<var><a name="index-hmac_005fmd5_005fset_005fkey-223"></a></var><br>
+<blockquote><p>Initializes the context with the key. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>hmac_md5_update</b> (<var>struct hmac_md5_ctx *ctx, unsigned length, const uint8_t *data</var>)<var><a name="index-hmac_005fmd5_005fupdate-224"></a></var><br>
+<blockquote><p>Process some more data. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>hmac_md5_digest</b> (<var>struct hmac_md5_ctx *ctx, unsigned length, uint8_t *digest</var>)<var><a name="index-hmac_005fmd5_005fdigest-225"></a></var><br>
+<blockquote><p>Extracts the <acronym>MAC</acronym>, writing it to <var>digest</var>. <var>length</var> may be smaller than
+<code>MD5_DIGEST_SIZE</code>, in which case only the first <var>length</var>
+octets of the <acronym>MAC</acronym> are written.
+
+        <p>This function also resets the context for processing new messages, with
+the same key. 
+</p></blockquote></div>
+
+<h5 class="subsubsection">6.4.2.2 <acronym>HMAC-RIPEMD160</acronym></h5>
+
+<div class="defun">
+&mdash; Context struct: <b>struct hmac_ripemd160_ctx</b><var><a name="index-struct-hmac_005fripemd160_005fctx-226"></a></var><br>
+     </div>
+
+<div class="defun">
+&mdash; Function: void <b>hmac_ripemd160_set_key</b> (<var>struct hmac_ripemd160_ctx *ctx, unsigned key_length, const uint8_t *key</var>)<var><a name="index-hmac_005fripemd160_005fset_005fkey-227"></a></var><br>
+<blockquote><p>Initializes the context with the key. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>hmac_ripemd160_update</b> (<var>struct hmac_ripemd160_ctx *ctx, unsigned length, const uint8_t *data</var>)<var><a name="index-hmac_005fripemd160_005fupdate-228"></a></var><br>
+<blockquote><p>Process some more data. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>hmac_ripemd160_digest</b> (<var>struct hmac_ripemd160_ctx *ctx, unsigned length, uint8_t *digest</var>)<var><a name="index-hmac_005fripemd160_005fdigest-229"></a></var><br>
+<blockquote><p>Extracts the <acronym>MAC</acronym>, writing it to <var>digest</var>. <var>length</var> may be smaller than
+<code>RIPEMD160_DIGEST_SIZE</code>, in which case only the first <var>length</var>
+octets of the <acronym>MAC</acronym> are written.
+
+        <p>This function also resets the context for processing new messages, with
+the same key. 
+</p></blockquote></div>
+
+<h5 class="subsubsection">6.4.2.3 <acronym>HMAC-SHA1</acronym></h5>
+
+<div class="defun">
+&mdash; Context struct: <b>struct hmac_sha1_ctx</b><var><a name="index-struct-hmac_005fsha1_005fctx-230"></a></var><br>
+     </div>
+
+<div class="defun">
+&mdash; Function: void <b>hmac_sha1_set_key</b> (<var>struct hmac_sha1_ctx *ctx, unsigned key_length, const uint8_t *key</var>)<var><a name="index-hmac_005fsha1_005fset_005fkey-231"></a></var><br>
+<blockquote><p>Initializes the context with the key. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>hmac_sha1_update</b> (<var>struct hmac_sha1_ctx *ctx, unsigned length, const uint8_t *data</var>)<var><a name="index-hmac_005fsha1_005fupdate-232"></a></var><br>
+<blockquote><p>Process some more data. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>hmac_sha1_digest</b> (<var>struct hmac_sha1_ctx *ctx, unsigned length, uint8_t *digest</var>)<var><a name="index-hmac_005fsha1_005fdigest-233"></a></var><br>
+<blockquote><p>Extracts the <acronym>MAC</acronym>, writing it to <var>digest</var>. <var>length</var> may be smaller than
+<code>SHA1_DIGEST_SIZE</code>, in which case only the first <var>length</var>
+octets of the <acronym>MAC</acronym> are written.
+
+        <p>This function also resets the context for processing new messages, with
+the same key. 
+</p></blockquote></div>
+
+<h5 class="subsubsection">6.4.2.4 <acronym>HMAC-SHA256</acronym></h5>
+
+<div class="defun">
+&mdash; Context struct: <b>struct hmac_sha256_ctx</b><var><a name="index-struct-hmac_005fsha256_005fctx-234"></a></var><br>
+     </div>
+
+<div class="defun">
+&mdash; Function: void <b>hmac_sha256_set_key</b> (<var>struct hmac_sha256_ctx *ctx, unsigned key_length, const uint8_t *key</var>)<var><a name="index-hmac_005fsha256_005fset_005fkey-235"></a></var><br>
+<blockquote><p>Initializes the context with the key. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>hmac_sha256_update</b> (<var>struct hmac_sha256_ctx *ctx, unsigned length, const uint8_t *data</var>)<var><a name="index-hmac_005fsha256_005fupdate-236"></a></var><br>
+<blockquote><p>Process some more data. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>hmac_sha256_digest</b> (<var>struct hmac_sha256_ctx *ctx, unsigned length, uint8_t *digest</var>)<var><a name="index-hmac_005fsha256_005fdigest-237"></a></var><br>
+<blockquote><p>Extracts the <acronym>MAC</acronym>, writing it to <var>digest</var>. <var>length</var> may be smaller than
+<code>SHA256_DIGEST_SIZE</code>, in which case only the first <var>length</var>
+octets of the <acronym>MAC</acronym> are written.
+
+        <p>This function also resets the context for processing new messages, with
+the same key. 
+</p></blockquote></div>
+
+<h5 class="subsubsection">6.4.2.5 <acronym>HMAC-SHA512</acronym></h5>
+
+<div class="defun">
+&mdash; Context struct: <b>struct hmac_sha512_ctx</b><var><a name="index-struct-hmac_005fsha512_005fctx-238"></a></var><br>
+     </div>
+
+<div class="defun">
+&mdash; Function: void <b>hmac_sha512_set_key</b> (<var>struct hmac_sha512_ctx *ctx, unsigned key_length, const uint8_t *key</var>)<var><a name="index-hmac_005fsha512_005fset_005fkey-239"></a></var><br>
+<blockquote><p>Initializes the context with the key. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>hmac_sha512_update</b> (<var>struct hmac_sha512_ctx *ctx, unsigned length, const uint8_t *data</var>)<var><a name="index-hmac_005fsha512_005fupdate-240"></a></var><br>
+<blockquote><p>Process some more data. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>hmac_sha512_digest</b> (<var>struct hmac_sha512_ctx *ctx, unsigned length, uint8_t *digest</var>)<var><a name="index-hmac_005fsha512_005fdigest-241"></a></var><br>
+<blockquote><p>Extracts the <acronym>MAC</acronym>, writing it to <var>digest</var>. <var>length</var> may be smaller than
+<code>SHA512_DIGEST_SIZE</code>, in which case only the first <var>length</var>
+octets of the <acronym>MAC</acronym> are written.
+
+        <p>This function also resets the context for processing new messages, with
+the same key. 
+</p></blockquote></div>
+
+<div class="node">
+<a name="Public-key-algorithms"></a>
+<a name="Public_002dkey-algorithms"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#Randomness">Randomness</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Keyed-hash-functions">Keyed hash functions</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Reference">Reference</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h3 class="section">6.5 Public-key algorithms</h3>
+
+<p>Nettle uses <acronym>GMP</acronym>, the GNU bignum library, for all calculations
+with large numbers. In order to use the public-key features of Nettle,
+you must install <acronym>GMP</acronym>, at least version 3.0, before compiling
+Nettle, and you need to link your programs with <code>-lhogweed -lnettle
+-lgmp</code>.
+
+   <p>The concept of <dfn>Public-key</dfn> encryption and digital signatures was
+discovered by Whitfield Diffie and Martin E. Hellman and described in a
+paper 1976. In traditional, &ldquo;symmetric&rdquo;, cryptography, sender and
+receiver share the same keys, and these keys must be distributed in a
+secure way. And if there are many users or entities that need to
+communicate, each <em>pair</em> needs a shared secret key known by nobody
+else.
+
+   <p><a name="index-Public-Key-Cryptography-242"></a><a name="index-One_002dway-function-243"></a>
+Public-key cryptography uses trapdoor one-way functions. A
+<dfn>one-way function</dfn> is a function <code>F</code> such that it is easy to
+compute the value <code>F(x)</code> for any <code>x</code>, but given a value
+<code>y</code>, it is hard to compute a corresponding <code>x</code> such that
+<code>y = F(x)</code>. Two examples are cryptographic hash functions, and
+exponentiation in certain groups.
+
+   <p>A <dfn>trapdoor one-way function</dfn> is a function <code>F</code> that is
+one-way, unless one knows some secret information about <code>F</code>. If one
+knows the secret, it is easy to compute both <code>F</code> and it's inverse. 
+If this sounds strange, look at the <acronym>RSA</acronym> example below.
+
+   <p>Two important uses for one-way functions with trapdoors are public-key
+encryption, and digital signatures. The public-key encryption functions
+in Nettle are not yet documented; the rest of this chapter is about
+digital signatures.
+
+   <p>To use a digital signature algorithm, one must first create a
+<dfn>key-pair</dfn>: A public key and a corresponding private key. The private
+key is used to sign messages, while the public key is used for verifying
+that that signatures and messages match. Some care must be taken when
+distributing the public key; it need not be kept secret, but if a bad
+guy is able to replace it (in transit, or in some user's list of known
+public keys), bad things may happen.
+
+   <p>There are two operations one can do with the keys. The signature
+operation takes a message and a private key, and creates a signature for
+the message. A signature is some string of bits, usually at most a few
+thousand bits or a few hundred octets. Unlike paper-and-ink signatures,
+the digital signature depends on the message, so one can't cut it out of
+context and glue it to a different message.
+
+   <p>The verification operation takes a public key, a message, and a string
+that is claimed to be a signature on the message, and returns true or
+false. If it returns true, that means that the three input values
+matched, and the verifier can be sure that someone went through with the
+signature operation on that very message, and that the &ldquo;someone&rdquo; also
+knows the private key corresponding to the public key.
+
+   <p>The desired properties of a digital signature algorithm are as follows:
+Given the public key and pairs of messages and valid signatures on them,
+it should be hard to compute the private key, and it should also be hard
+to create a new message and signature that is accepted by the
+verification operation.
+
+   <p>Besides signing meaningful messages, digital signatures can be used for
+authorization. A server can be configured with a public key, such that
+any client that connects to the service is given a random nonce message. 
+If the server gets a reply with a correct signature matching the nonce
+message and the configured public key, the client is granted access. So
+the configuration of the server can be understood as &ldquo;grant access to
+whoever knows the private key corresponding to this particular public
+key, and to no others&rdquo;.
+
+<ul class="menu">
+<li><a accesskey="1" href="#RSA">RSA</a>:                          The RSA public key algorithm. 
+<li><a accesskey="2" href="#DSA">DSA</a>:                          The DSA digital signature algorithm. 
+</ul>
+
+<div class="node">
+<a name="RSA"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#DSA">DSA</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Public_002dkey-algorithms">Public-key algorithms</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Public_002dkey-algorithms">Public-key algorithms</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h4 class="subsection">6.5.1 <acronym>RSA</acronym></h4>
+
+<p>The <acronym>RSA</acronym> algorithm was the first practical digital signature
+algorithm that was constructed. It was described 1978 in a paper by
+Ronald Rivest, Adi Shamir and L.M. Adleman, and the technique was also
+patented in the <acronym>USA</acronym> in 1983. The patent expired on September 20, 2000, and since
+that day, <acronym>RSA</acronym> can be used freely, even in the <acronym>USA</acronym>.
+
+   <p>It's remarkably simple to describe the trapdoor function behind
+<acronym>RSA</acronym>. The &ldquo;one-way&rdquo;-function used is
+
+<pre class="example">     F(x) = x^e mod n
+</pre>
+   <p>I.e. raise x to the <code>e</code>:th power, while discarding all multiples of
+<code>n</code>. The pair of numbers <code>n</code> and <code>e</code> is the public key. 
+<code>e</code> can be quite small, even <code>e = 3</code> has been used, although
+slightly larger numbers are recommended. <code>n</code> should be about 1000
+bits or larger.
+
+   <p>If <code>n</code> is large enough, and properly chosen, the inverse of F,
+the computation of <code>e</code>:th roots modulo <code>n</code>, is very difficult. 
+But, where's the trapdoor?
+
+   <p>Let's first look at how <acronym>RSA</acronym> key-pairs are generated. First
+<code>n</code> is chosen as the product of two large prime numbers <code>p</code>
+and <code>q</code> of roughly the same size (so if <code>n</code> is 1000 bits,
+<code>p</code> and <code>q</code> are about 500 bits each). One also computes the
+number <code>phi = (p-1)(q-1)</code>, in mathematical speak, <code>phi</code> is the
+order of the multiplicative group of integers modulo n.
+
+   <p>Next, <code>e</code> is chosen. It must have no factors in common with <code>phi</code> (in
+particular, it must be odd), but can otherwise be chosen more or less
+randomly. <code>e = 65537</code> is a popular choice, because it makes raising
+to the <code>e</code>'th power particularly efficient, and being prime, it
+usually has no factors common with <code>phi</code>.
+
+   <p>Finally, a number <code>d</code>, <code>d &lt; n</code> is computed such that <code>e d
+mod phi = 1</code>. It can be shown that such a number exists (this is why
+<code>e</code> and <code>phi</code> must have no common factors), and that for all x,
+
+<pre class="example">     (x^e)^d mod n = x^(ed) mod n = (x^d)^e mod n = x
+</pre>
+   <p>Using Euclid's algorithm, <code>d</code> can be computed quite easily from
+<code>phi</code> and <code>e</code>. But it is still hard to get <code>d</code> without
+knowing <code>phi</code>, which depends on the factorization of <code>n</code>.
+
+   <p>So <code>d</code> is the trapdoor, if we know <code>d</code> and <code>y = F(x)</code>, we can
+recover x as <code>y^d mod n</code>. <code>d</code> is also the private half of
+the <acronym>RSA</acronym> key-pair.
+
+   <p>The most common signature operation for <acronym>RSA</acronym> is defined in
+<cite>PKCS#1</cite>, a specification by RSA Laboratories. The message to be
+signed is first hashed using a cryptographic hash function, e.g. 
+<acronym>MD5</acronym> or <acronym>SHA1</acronym>. Next, some padding, the <acronym>ASN.1</acronym>
+&ldquo;Algorithm Identifier&rdquo; for the hash function, and the message digest
+itself, are concatenated and converted to a number <code>x</code>. The
+signature is computed from <code>x</code> and the private key as <code>s = x^d
+mod n</code><a rel="footnote" href="#fn-1" name="fnd-1"><sup>1</sup></a>. The signature, <code>s</code> is a
+number of about the same size of <code>n</code>, and it usually encoded as a
+sequence of octets, most significant octet first.
+
+   <p>The verification operation is straight-forward, <code>x</code> is computed
+from the message in the same way as above. Then <code>s^e mod n</code> is
+computed, the operation returns true if and only if the result equals
+<code>x</code>.
+
+<h4 class="subsection">6.5.2 Nettle's <acronym>RSA</acronym> support</h4>
+
+<p>Nettle represents <acronym>RSA</acronym> keys using two structures that contain
+large numbers (of type <code>mpz_t</code>).
+
+<div class="defun">
+&mdash; Context struct: <b>rsa_public_key</b><var> size n e<a name="index-rsa_005fpublic_005fkey-244"></a></var><br>
+<blockquote><p><code>size</code> is the size, in octets, of the modulo, and is used internally. 
+<code>n</code> and <code>e</code> is the public key. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Context struct: <b>rsa_private_key</b><var> size d p q a b c<a name="index-rsa_005fprivate_005fkey-245"></a></var><br>
+<blockquote><p><code>size</code> is the size, in octets, of the modulo, and is used internally. 
+<code>d</code> is the secret exponent, but it is not actually used when
+signing. Instead, the factors <code>p</code> and <code>q</code>, and the parameters
+<code>a</code>, <code>b</code> and <code>c</code> are used. They are computed from <code>p</code>,
+<code>q</code> and <code>e</code> such that <code>a e mod (p - 1) = 1, b e mod (q -
+1) = 1, c q mod p = 1</code>. 
+</p></blockquote></div>
+
+   <p>Before use, these structs must be initialized by calling one of
+
+<div class="defun">
+&mdash; Function: void <b>rsa_public_key_init</b> (<var>struct rsa_public_key *pub</var>)<var><a name="index-rsa_005fpublic_005fkey_005finit-246"></a></var><br>
+&mdash; Function: void <b>rsa_private_key_init</b> (<var>struct rsa_private_key *key</var>)<var><a name="index-rsa_005fprivate_005fkey_005finit-247"></a></var><br>
+<blockquote><p>Calls <code>mpz_init</code> on all numbers in the key struct. 
+</p></blockquote></div>
+
+   <p>and when finished with them, the space for the numbers must be
+deallocated by calling one of
+
+<div class="defun">
+&mdash; Function: void <b>rsa_public_key_clear</b> (<var>struct rsa_public_key *pub</var>)<var><a name="index-rsa_005fpublic_005fkey_005fclear-248"></a></var><br>
+&mdash; Function: void <b>rsa_private_key_clear</b> (<var>struct rsa_private_key *key</var>)<var><a name="index-rsa_005fprivate_005fkey_005fclear-249"></a></var><br>
+<blockquote><p>Calls <code>mpz_clear</code> on all numbers in the key struct. 
+</p></blockquote></div>
+
+   <p>In general, Nettle's <acronym>RSA</acronym> functions deviates from Nettle's &ldquo;no
+memory allocation&rdquo;-policy. Space for all the numbers, both in the key structs
+above, and temporaries, are allocated dynamically. For information on how
+to customize allocation, see
+See <a href="gmp.html#Custom-Allocation">GMP Allocation</a>.
+
+   <p>When you have assigned values to the attributes of a key, you must call
+
+<div class="defun">
+&mdash; Function: int <b>rsa_public_key_prepare</b> (<var>struct rsa_public_key *pub</var>)<var><a name="index-rsa_005fpublic_005fkey_005fprepare-250"></a></var><br>
+&mdash; Function: int <b>rsa_private_key_prepare</b> (<var>struct rsa_private_key *key</var>)<var><a name="index-rsa_005fprivate_005fkey_005fprepare-251"></a></var><br>
+<blockquote><p>Computes the octet size of the key (stored in the <code>size</code> attribute,
+and may also do other basic sanity checks. Returns one if successful, or
+zero if the key can't be used, for instance if the modulo is smaller
+than the minimum size needed for <acronym>RSA</acronym> operations specified by PKCS#1. 
+</p></blockquote></div>
+
+   <p>Before signing or verifying a message, you first hash it with the
+appropriate hash function. You pass the hash function's context struct
+to the <acronym>RSA</acronym> signature function, and it will extract the message
+digest and do the rest of the work. There are also alternative functions
+that take the hash digest as argument.
+
+   <p>There is currently no support for using SHA224 or SHA384 with
+<acronym>RSA</acronym> signatures, since there's no gain in either computation
+time nor message size compared to using SHA256 and SHA512, respectively.
+
+   <p>Creation and verification of signatures is done with the following functions:
+
+<div class="defun">
+&mdash; Function: int <b>rsa_md5_sign</b> (<var>const struct rsa_private_key *key, struct md5_ctx *hash, mpz_t signature</var>)<var><a name="index-rsa_005fmd5_005fsign-252"></a></var><br>
+&mdash; Function: int <b>rsa_sha1_sign</b> (<var>const struct rsa_private_key *key, struct sha1_ctx *hash, mpz_t signature</var>)<var><a name="index-rsa_005fsha1_005fsign-253"></a></var><br>
+&mdash; Function: int <b>rsa_sha256_sign</b> (<var>const struct rsa_private_key *key, struct sha256_ctx *hash, mpz_t signature</var>)<var><a name="index-rsa_005fsha256_005fsign-254"></a></var><br>
+&mdash; Function: int <b>rsa_sha512_sign</b> (<var>const struct rsa_private_key *key, struct sha512_ctx *hash, mpz_t signature</var>)<var><a name="index-rsa_005fsha512_005fsign-255"></a></var><br>
+<blockquote><p>The signature is stored in <var>signature</var> (which must have been
+<code>mpz_init</code>'ed earlier). The hash context is reset so that it can be
+used for new messages. Returns one on success, or zero on failure. 
+Signing fails if the key is too small for the given hash size, e.g.,
+it's not possible to create a signature using SHA512 and a 512-bit
+<acronym>RSA</acronym> key. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: int <b>rsa_md5_sign_digest</b> (<var>const struct rsa_private_key *key, const uint8_t *digest, mpz_t signature</var>)<var><a name="index-rsa_005fmd5_005fsign_005fdigest-256"></a></var><br>
+&mdash; Function: int <b>rsa_sha1_sign_digest</b> (<var>const struct rsa_private_key *key, const uint8_t *digest, mpz_t signature</var>)<var>;<a name="index-rsa_005fsha1_005fsign_005fdigest-257"></a></var><br>
+&mdash; Function: int <b>rsa_sha256_sign_digest</b> (<var>const struct rsa_private_key *key, const uint8_t *digest, mpz_t signature</var>)<var>;<a name="index-rsa_005fsha256_005fsign_005fdigest-258"></a></var><br>
+&mdash; Function: int <b>rsa_sha512_sign_digest</b> (<var>const struct rsa_private_key *key, const uint8_t *digest, mpz_t signature</var>)<var>;<a name="index-rsa_005fsha512_005fsign_005fdigest-259"></a></var><br>
+<blockquote><p>Creates a signature from the given hash digest. <var>digest</var> should
+point to a digest of size <code>MD5_DIGEST_SIZE</code>,
+<code>SHA1_DIGEST_SIZE</code>, or <code>SHA256_DIGEST_SIZE</code>, respectively. The
+signature is stored in <var>signature</var> (which must have been
+<code>mpz_init</code>:ed earlier). Returns one on success, or zero on failure. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: int <b>rsa_md5_verify</b> (<var>const struct rsa_public_key *key, struct md5_ctx *hash, const mpz_t signature</var>)<var><a name="index-rsa_005fmd5_005fverify-260"></a></var><br>
+&mdash; Function: int <b>rsa_sha1_verify</b> (<var>const struct rsa_public_key *key, struct sha1_ctx *hash, const mpz_t signature</var>)<var><a name="index-rsa_005fsha1_005fverify-261"></a></var><br>
+&mdash; Function: int <b>rsa_sha256_verify</b> (<var>const struct rsa_public_key *key, struct sha256_ctx *hash, const mpz_t signature</var>)<var><a name="index-rsa_005fsha256_005fverify-262"></a></var><br>
+&mdash; Function: int <b>rsa_sha512_verify</b> (<var>const struct rsa_public_key *key, struct sha512_ctx *hash, const mpz_t signature</var>)<var><a name="index-rsa_005fsha512_005fverify-263"></a></var><br>
+<blockquote><p>Returns 1 if the signature is valid, or 0 if it isn't. In either case,
+the hash context is reset so that it can be used for new messages. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: int <b>rsa_md5_verify_digest</b> (<var>const struct rsa_public_key *key, const uint8_t *digest, const mpz_t signature</var>)<var><a name="index-rsa_005fmd5_005fverify_005fdigest-264"></a></var><br>
+&mdash; Function: int <b>rsa_sha1_verify_digest</b> (<var>const struct rsa_public_key *key, const uint8_t *digest, const mpz_t signature</var>)<var><a name="index-rsa_005fsha1_005fverify_005fdigest-265"></a></var><br>
+&mdash; Function: int <b>rsa_sha256_verify_digest</b> (<var>const struct rsa_public_key *key, const uint8_t *digest, const mpz_t signature</var>)<var><a name="index-rsa_005fsha256_005fverify_005fdigest-266"></a></var><br>
+&mdash; Function: int <b>rsa_sha512_verify_digest</b> (<var>const struct rsa_public_key *key, const uint8_t *digest, const mpz_t signature</var>)<var><a name="index-rsa_005fsha512_005fverify_005fdigest-267"></a></var><br>
+<blockquote><p>Returns 1 if the signature is valid, or 0 if it isn't. <var>digest</var> should
+point to a digest of size <code>MD5_DIGEST_SIZE</code>,
+<code>SHA1_DIGEST_SIZE</code>, or <code>SHA256_DIGEST_SIZE</code>, respectively. 
+</p></blockquote></div>
+
+   <p>If you need to use the <acronym>RSA</acronym> trapdoor, the private key, in a way
+that isn't supported by the above functions Nettle also includes a
+function that computes <code>x^d mod n</code> and nothing more, using the
+<acronym>CRT</acronym> optimization.
+
+<div class="defun">
+&mdash; Function: void <b>rsa_compute_root</b> (<var>struct rsa_private_key *key, mpz_t x, const mpz_t m</var>)<var><a name="index-rsa_005fcompute_005froot-268"></a></var><br>
+<blockquote><p>Computes <code>x = m^d</code>, efficiently. 
+</p></blockquote></div>
+
+   <p>At last, how do you create new keys?
+
+<div class="defun">
+&mdash; Function: int <b>rsa_generate_keypair</b> (<var>struct rsa_public_key *pub, struct rsa_private_key *key, void *random_ctx, nettle_random_func random, void *progress_ctx, nettle_progress_func progress, unsigned n_size, unsigned e_size</var>)<var>;<a name="index-rsa_005fgenerate_005fkeypair-269"></a></var><br>
+<blockquote><p>There are lots of parameters. <var>pub</var> and <var>key</var> is where the
+resulting key pair is stored. The structs should be initialized, but you
+don't need to call <code>rsa_public_key_prepare</code> or
+<code>rsa_private_key_prepare</code> after key generation.
+
+        <p><var>random_ctx</var> and <var>random</var> is a randomness generator. 
+<code>random(random_ctx, length, dst)</code> should generate <code>length</code>
+random octets and store them at <code>dst</code>. For advice, see
+See <a href="#Randomness">Randomness</a>.
+
+        <p><var>progress</var> and <var>progress_ctx</var> can be used to get callbacks
+during the key generation process, in order to uphold an illusion of
+progress. <var>progress</var> can be NULL, in that case there are no
+callbacks.
+
+        <p><var>size_n</var> is the desired size of the modulo, in bits. If <var>size_e</var>
+is non-zero, it is the desired size of the public exponent and a random
+exponent of that size is selected. But if <var>e_size</var> is zero, it is
+assumed that the caller has already chosen a value for <code>e</code>, and
+stored it in <var>pub</var>. 
+Returns one on success, and zero on failure. The function can fail for
+example if if <var>n_size</var> is too small, or if <var>e_size</var> is zero and
+<code>pub-&gt;e</code> is an even number. 
+</p></blockquote></div>
+
+<div class="node">
+<a name="DSA"></a>
+<p><hr>
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#RSA">RSA</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Public_002dkey-algorithms">Public-key algorithms</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h4 class="subsection">6.5.3 Nettle's <acronym>DSA</acronym> support</h4>
+
+<p>The <acronym>DSA</acronym> digital signature algorithm is more complex than
+<acronym>RSA</acronym>. It was specified during the early 1990s, and in 1994 NIST
+published <acronym>FIPS</acronym> 186 which is the authoritative specification. 
+Sometimes <acronym>DSA</acronym> is referred to using the acronym <acronym>DSS</acronym>,
+for Digital Signature Standard. The most recent revision of the
+specification, FIPS186-3, was issueed in 2009, and it adds support for
+larger hash functions than <acronym>sha1</acronym>.
+
+   <p>For <acronym>DSA</acronym>, the underlying mathematical problem is the
+computation of discreet logarithms. The public key consists of a large
+prime <code>p</code>, a small prime <code>q</code> which is a factor of <code>p-1</code>,
+a number <code>g</code> which generates a subgroup of order <code>q</code> modulo
+<code>p</code>, and an element <code>y</code> in that subgroup.
+
+   <p>In the original <acronym>DSA</acronym>, the size of <code>q</code> is fixed to 160
+bits, to match with the <acronym>SHA1</acronym> hash algorithm. The size of
+<code>p</code> is in principle unlimited, but the
+standard specifies only nine specific sizes: <code>512 + l*64</code>, where
+<code>l</code> is between 0 and 8. Thus, the maximum size of <code>p</code> is 1024
+bits, and sizes less than 1024 bits are considered obsolete and not
+secure.
+
+   <p>The subgroup requirement means that if you compute
+
+<pre class="example">     g^t mod p
+</pre>
+   <p>for all possible integers <code>t</code>, you will get precisely <code>q</code>
+distinct values.
+
+   <p>The private key is a secret exponent <code>x</code>, such that
+
+<pre class="example">     g^x = y mod p
+</pre>
+   <p>In mathematical speak, <code>x</code> is the <dfn>discrete logarithm</dfn> of
+<code>y</code> mod <code>p</code>, with respect to the generator <code>g</code>. The size
+of <code>x</code> will also be about the same size as <code>q</code>. The security of the
+<acronym>DSA</acronym> algorithm relies on the difficulty of the discrete
+logarithm problem. Current algorithms to compute discrete logarithms in
+this setting, and hence crack <acronym>DSA</acronym>, are of two types. The first
+type works directly in the (multiplicative) group of integers mod
+<code>p</code>. The best known algorithm of this type is the Number Field
+Sieve, and it's complexity is similar to the complexity of factoring
+numbers of the same size as <code>p</code>. The other type works in the
+smaller <code>q</code>-sized subgroup generated by <code>g</code>, which has a more
+difficult group structure. One good algorithm is Pollard-rho, which has
+complexity <code>sqrt(q)</code>.
+
+   <p>The important point is that security depends on the size of <em>both</em>
+<code>p</code> and <code>q</code>, and they should be choosen so that the difficulty
+of both discrete logarithm methods are comparable. Today, the security
+margin of the original <acronym>DSA</acronym> may be uncomfortably small. Using a
+<code>p</code> of 1024 bits implies that cracking using the number field sieve
+is expected to take about the same time as factoring a 1024-bit
+<acronym>RSA</acronym> modulo, and using a <code>q</code> of size 160 bits implies
+that cracking using Pollard-rho will take roughly <code>2^80</code> group
+operations. With the size of <code>q</code> fixed, tied to the <acronym>SHA1</acronym>
+digest size, it may be tempting to increase the size of <code>p</code> to,
+say, 4096 bits. This will provide excellent resistance against attacks
+like the number field sieve which works in the large group. But it will
+do very little to defend against Pollard-rho attacking the small
+subgroup; the attacker is slowed down at most by a single factor of 10
+due to the more expensive group operation. And the attacker will surely
+choose the latter attack.
+
+   <p>The signature generation algorithm is randomized; in order to create a
+<acronym>DSA</acronym> signature, you need a good source for random numbers
+(see <a href="#Randomness">Randomness</a>). Let us describe the common case of a 160-bit
+<code>q</code>.
+
+   <p>To create a signature, one starts with the hash digest of the message,
+<code>h</code>, which is a 160 bit number, and a random number <code>k,
+0&lt;k&lt;q</code>, also 160 bits. Next, one computes
+
+<pre class="example">     r = (g^k mod p) mod q
+     s = k^-1 (h + x r) mod q
+</pre>
+   <p>The signature is the pair <code>(r, s)</code>, two 160 bit numbers. Note the
+two different mod operations when computing <code>r</code>, and the use of the
+secret exponent <code>x</code>.
+
+   <p>To verify a signature, one first checks that <code>0 &lt; r,s &lt; q</code>, and
+then one computes backwards,
+
+<pre class="example">     w = s^-1 mod q
+     v = (g^(w h) y^(w r) mod p) mod q
+</pre>
+   <p>The signature is valid if <code>v = r</code>. This works out because <code>w =
+s^-1 mod q = k (h + x r)^-1 mod q</code>, so that
+
+<pre class="example">     g^(w h) y^(w r) = g^(w h) (g^x)^(w r) = g^(w (h + x r)) = g^k
+</pre>
+   <p>When reducing mod <code>q</code> this yields <code>r</code>. Note that when
+verifying a signature, we don't know either <code>k</code> or <code>x</code>: those
+numbers are secret.
+
+   <p>If you can choose between <acronym>RSA</acronym> and <acronym>DSA</acronym>, which one is
+best? Both are believed to be secure. <acronym>DSA</acronym> gained popularity in
+the late 1990s, as a patent free alternative to <acronym>RSA</acronym>. Now that
+the <acronym>RSA</acronym> patents have expired, there's no compelling reason to
+want to use <acronym>DSA</acronym>. Today, the original <acronym>DSA</acronym> key size
+does not provide a large security margin, and it should probably be
+phased out together with <acronym>RSA</acronym> keys of 1024 bits. Using the
+revised <acronym>DSA</acronym> algorithm with a larger hash function, in
+particular, <acronym>SHA256</acronym>, a 256-bit <code>q</code>, and <code>p</code> of size
+2048 bits or more, should provide for a more comfortable security
+margin, but these variants are not yet in wide use.
+
+   <p><acronym>DSA</acronym> signatures are smaller than <acronym>RSA</acronym> signatures,
+which is important for some specialized applications.
+
+   <p>From a practical point of view, <acronym>DSA</acronym>'s need for a good
+randomness source is a serious disadvantage. If you ever use the same
+<code>k</code> (and <code>r</code>) for two different message, you leak your private
+key.
+
+<h4 class="subsection">6.5.4 Nettle's <acronym>DSA</acronym> support</h4>
+
+<p>Like for <acronym>RSA</acronym>, Nettle represents <acronym>DSA</acronym> keys using two
+structures, containing values of type <code>mpz_t</code>. For information on
+how to customize allocation, see See <a href="gmp.html#Custom-Allocation">GMP Allocation</a>.
+
+   <p>Most of the <acronym>DSA</acronym> functions are very similar to the
+corresponding <acronym>RSA</acronym> functions, but there are a few differences
+pointed out below. For a start, there are no functions corresponding to
+<code>rsa_public_key_prepare</code> and <code>rsa_private_key_prepare</code>.
+
+<div class="defun">
+&mdash; Context struct: <b>dsa_public_key</b><var> p q g y<a name="index-dsa_005fpublic_005fkey-270"></a></var><br>
+<blockquote><p>The public parameters described above. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Context struct: <b>dsa_private_key</b><var> x<a name="index-dsa_005fprivate_005fkey-271"></a></var><br>
+<blockquote><p>The private key <code>x</code>. 
+</p></blockquote></div>
+
+   <p>Before use, these structs must be initialized by calling one of
+
+<div class="defun">
+&mdash; Function: void <b>dsa_public_key_init</b> (<var>struct dsa_public_key *pub</var>)<var><a name="index-dsa_005fpublic_005fkey_005finit-272"></a></var><br>
+&mdash; Function: void <b>dsa_private_key_init</b> (<var>struct dsa_private_key *key</var>)<var><a name="index-dsa_005fprivate_005fkey_005finit-273"></a></var><br>
+<blockquote><p>Calls <code>mpz_init</code> on all numbers in the key struct. 
+</p></blockquote></div>
+
+   <p>When finished with them, the space for the numbers must be
+deallocated by calling one of
+
+<div class="defun">
+&mdash; Function: void <b>dsa_public_key_clear</b> (<var>struct dsa_public_key *pub</var>)<var><a name="index-dsa_005fpublic_005fkey_005fclear-274"></a></var><br>
+&mdash; Function: void <b>dsa_private_key_clear</b> (<var>struct dsa_private_key *key</var>)<var><a name="index-dsa_005fprivate_005fkey_005fclear-275"></a></var><br>
+<blockquote><p>Calls <code>mpz_clear</code> on all numbers in the key struct. 
+</p></blockquote></div>
+
+   <p>Signatures are represented using the structure below, and need to be
+initialized and cleared in the same way as the key structs.
+
+<div class="defun">
+&mdash; Context struct: <b>dsa_signature</b><var> r s<a name="index-dsa_005fsignature-276"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Function: void <b>dsa_signature_init</b> (<var>struct dsa_signature *signature</var>)<var><a name="index-dsa_005fsignature_005finit-277"></a></var><br>
+&mdash; Function: void <b>dsa_signature_clear</b> (<var>struct dsa_signature *signature</var>)<var><a name="index-dsa_005fsignature_005fclear-278"></a></var><br>
+<blockquote><p>You must call <code>dsa_signature_init</code> before creating or using a
+signature, and call <code>dsa_signature_clear</code> when you are finished
+with it. 
+</p></blockquote></div>
+
+   <p>For signing, you need to provide both the public and the private key
+(unlike <acronym>RSA</acronym>, where the private key struct includes all
+information needed for signing), and a source for random numbers. 
+Signatures can use the <acronym>SHA1</acronym> or the <acronym>SHA256</acronym> hash
+function, although the implementation of <acronym>DSA</acronym> with
+<acronym>SHA256</acronym> should be considered somewhat experimental due to lack
+of official test vectors and interoperability testing.
+
+<div class="defun">
+&mdash; Function: int <b>dsa_sha1_sign</b> (<var>const struct dsa_public_key *pub, const struct dsa_private_key *key, void *random_ctx, nettle_random_func random, struct sha1_ctx *hash, struct dsa_signature *signature</var>)<var><a name="index-dsa_005fsha1_005fsign-279"></a></var><br>
+&mdash; Function: int <b>dsa_sha1_sign_digest</b> (<var>const struct dsa_public_key *pub, const struct dsa_private_key *key, void *random_ctx, nettle_random_func random, const uint8_t *digest, struct dsa_signature *signature</var>)<var><a name="index-dsa_005fsha1_005fsign_005fdigest-280"></a></var><br>
+&mdash; Function: int <b>dsa_sha256_sign</b> (<var>const struct dsa_public_key *pub, const struct dsa_private_key *key, void *random_ctx, nettle_random_func random, struct sha256_ctx *hash, struct dsa_signature *signature</var>)<var><a name="index-dsa_005fsha256_005fsign-281"></a></var><br>
+&mdash; Function: int <b>dsa_sha256_sign_digest</b> (<var>const struct dsa_public_key *pub, const struct dsa_private_key *key, void *random_ctx, nettle_random_func random, const uint8_t *digest, struct dsa_signature *signature</var>)<var><a name="index-dsa_005fsha256_005fsign_005fdigest-282"></a></var><br>
+<blockquote><p>Creates a signature from the given hash context or digest. 
+<var>random_ctx</var> and <var>random</var> is a randomness generator. 
+<code>random(random_ctx, length, dst)</code> should generate <code>length</code>
+random octets and store them at <code>dst</code>. For advice, see
+See <a href="#Randomness">Randomness</a>. Returns one on success, or zero on failure. 
+Signing fails if the key size and the hash size don't match. 
+</p></blockquote></div>
+
+   <p>Verifying signatures is a little easier, since no randomness generator is
+needed. The functions are
+
+<div class="defun">
+&mdash; Function: int <b>dsa_sha1_verify</b> (<var>const struct dsa_public_key *key, struct sha1_ctx *hash, const struct dsa_signature *signature</var>)<var><a name="index-dsa_005fsha1_005fverify-283"></a></var><br>
+&mdash; Function: int <b>dsa_sha1_verify_digest</b> (<var>const struct dsa_public_key *key, const uint8_t *digest, const struct dsa_signature *signature</var>)<var><a name="index-dsa_005fsha1_005fverify_005fdigest-284"></a></var><br>
+&mdash; Function: int <b>dsa_sha256_verify</b> (<var>const struct dsa_public_key *key, struct sha256_ctx *hash, const struct dsa_signature *signature</var>)<var><a name="index-dsa_005fsha256_005fverify-285"></a></var><br>
+&mdash; Function: int <b>dsa_sha256_verify_digest</b> (<var>const struct dsa_public_key *key, const uint8_t *digest, const struct dsa_signature *signature</var>)<var><a name="index-dsa_005fsha256_005fverify_005fdigest-286"></a></var><br>
+<blockquote><p>Verifies a signature. Returns 1 if the signature is valid, otherwise 0. 
+</p></blockquote></div>
+
+   <p>Key generation uses mostly the same parameters as the corresponding
+<acronym>RSA</acronym> function.
+
+<div class="defun">
+&mdash; Function: int <b>dsa_generate_keypair</b> (<var>struct dsa_public_key *pub, struct dsa_private_key *key, void *random_ctx, nettle_random_func random, void *progress_ctx, nettle_progress_func progress, unsigned p_bits, unsigned q_bits</var>)<var><a name="index-dsa_005fgenerate_005fkeypair-287"></a></var><br>
+<blockquote><p><var>pub</var> and <var>key</var> is where the resulting key pair is stored. The
+structs should be initialized before you call this function.
+
+        <p><var>random_ctx</var> and <var>random</var> is a randomness generator. 
+<code>random(random_ctx, length, dst)</code> should generate <code>length</code>
+random octets and store them at <code>dst</code>. For advice, see
+See <a href="#Randomness">Randomness</a>.
+
+        <p><var>progress</var> and <var>progress_ctx</var> can be used to get callbacks
+during the key generation process, in order to uphold an illusion of
+progress. <var>progress</var> can be NULL, in that case there are no
+callbacks.
+
+        <p><var>p_bits</var> and <var>q_bits</var> are the desired sizes of <code>p</code> and
+<code>q</code>. To generate keys that conform to the original <acronym>DSA</acronym>
+standard, you must use <code>q_bits = 160</code> and select <var>p_bits</var> of
+the form <code>p_bits = 512 + l*64</code>, for <code>0 &lt;= l &lt;= 8</code>, where the
+smaller sizes are no longer recommended, so you should most likely stick
+to <code>p_bits = 1024</code>. Non-standard sizes are possible, in particular
+<code>p_bits</code> larger than 1024, although <acronym>DSA</acronym> implementations
+can not in general be expected to support such keys. Also note that
+using very large <var>p_bits</var>, with <var>q_bits</var> fixed at 160, doesn't
+make much sense, because the security is also limited by the size of the
+smaller prime. Using a larger <code>q_bits</code> requires switchign to a
+larger hash function. To generate <acronym>DSA</acronym> keys for use with
+<acronym>SHA256</acronym>, use <code>q_bits = 256</code> and, e.g., <code>p_bits =
+2048</code>.
+
+        <p>Returns one on success, and zero on failure. The function will fail if
+<var>q_bits</var> is neither 160 nor 256, or if <var>p_bits</var> is unreasonably
+small. 
+</p></blockquote></div>
+
+<div class="node">
+<a name="Randomness"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#Miscellaneous-functions">Miscellaneous functions</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Public_002dkey-algorithms">Public-key algorithms</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Reference">Reference</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h3 class="section">6.6 Randomness</h3>
+
+<p><a name="index-Randomness-288"></a>
+A crucial ingredient in many cryptographic contexts is randomness: Let
+<code>p</code> be a random prime, choose a random initialization vector
+<code>iv</code>, a random key <code>k</code> and a random exponent <code>e</code>, etc. In
+the theories, it is assumed that you have plenty of randomness around. 
+If this assumption is not true in practice, systems that are otherwise
+perfectly secure, can be broken. Randomness has often turned out to be
+the weakest link in the chain.
+
+   <p>In non-cryptographic applications, such as games as well as scientific
+simulation, a good randomness generator usually means a generator that
+has good statistical properties, and is seeded by some simple function
+of things like the current time, process id, and host name.
+
+   <p>However, such a generator is inadequate for cryptography, for at least
+two reasons:
+
+     <ul>
+<li>It's too easy for an attacker to guess the initial seed. Even if it will
+take some 2^32 tries before he guesses right, that's far too easy. For
+example, if the process id is 16 bits, the resolution of &ldquo;current time&rdquo;
+is one second, and the attacker knows what day the generator was seeded,
+there are only about 2^32 possibilities to try if all possible values
+for the process id and time-of-day are tried.
+
+     <li>The generator output reveals too much. By observing only a small segment
+of the generator's output, its internal state can be recovered, and from
+there, all previous output and all future output can be computed by the
+attacker. 
+</ul>
+
+   <p>A randomness generator that is used for cryptographic purposes must have
+better properties. Let's first look at the seeding, as the issues here
+are mostly independent of the rest of the generator. The initial state
+of the generator (its seed) must be unguessable by the attacker. So
+what's unguessable? It depends on what the attacker already knows. The
+concept used in information theory to reason about such things is called
+&ldquo;entropy&rdquo;, or &ldquo;conditional entropy&rdquo; (not to be confused with the
+thermodynamic concept with the same name). A reasonable requirement is
+that the seed contains a conditional entropy of at least some 80-100
+bits. This property can be explained as follows: Allow the attacker to
+ask <code>n</code> yes-no-questions, of his own choice, about the seed. If
+the attacker, using this question-and-answer session, as well as any
+other information he knows about the seeding process, still can't guess
+the seed correctly, then the conditional entropy is more than <code>n</code>
+bits.
+
+   <p><a name="index-Entropy-289"></a><a name="index-Conditional-entropy-290"></a>
+Let's look at an example. Say information about timing of received
+network packets is used in the seeding process. If there is some random
+network traffic going on, this will contribute some bits of entropy or
+&ldquo;unguessability&rdquo; to the seed. However, if the attacker can listen in to
+the local network, or if all but a small number of the packets were
+transmitted by machines that the attacker can monitor, this additional
+information makes the seed easier for the attacker to figure out. Even
+if the information is exactly the same, the conditional entropy, or
+unguessability, is smaller for an attacker that knows some of it already
+before the hypothetical question-and-answer session.
+
+   <p>Seeding of good generators is usually based on several sources. The key
+point here is that the amount of unguessability that each source
+contributes, depends on who the attacker is. Some sources that have been
+used are:
+
+     <dl>
+<dt>High resolution timing of i/o activities<dd>Such as completed blocks from spinning hard disks, network packets, etc. 
+Getting access to such information is quite system dependent, and not
+all systems include suitable hardware. If available, it's one of the
+better randomness source one can find in a digital, mostly predictable,
+computer.
+
+     <br><dt>User activity<dd>Timing and contents of user interaction events is another popular source
+that is available for interactive programs (even if I suspect that it is
+sometimes used in order to make the user feel good, not because the
+quality of the input is needed or used properly). Obviously, not
+available when a machine is unattended. Also beware of networks: User
+interaction that happens across a long serial cable, <acronym>TELNET</acronym>
+session, or even <acronym>SSH</acronym> session may be visible to an attacker, in
+full or partially.
+
+     <br><dt>Audio input<dd>Any room, or even a microphone input that's left unconnected, is a
+source of some random background noise, which can be fed into the
+seeding process.
+
+     <br><dt>Specialized hardware<dd>Hardware devices with the sole purpose of generating random data have
+been designed. They range from radioactive samples with an attached
+Geiger counter, to amplification of the inherent noise in electronic
+components such as diodes and resistors, to low-frequency sampling of
+chaotic systems. Hashing successive images of a Lava lamp is a
+spectacular example of the latter type.
+
+     <br><dt>Secret information<dd>Secret information, such as user passwords or keys, or private files
+stored on disk, can provide some unguessability. A problem is that if
+the information is revealed at a later time, the unguessability
+vanishes. Another problem is that this kind of information tends to be
+fairly constant, so if you rely on it and seed your generator regularly,
+you risk constructing almost similar seeds or even constructing the same
+seed more than once. 
+</dl>
+
+   <p>For all practical sources, it's difficult but important to provide a
+reliable lower bound on the amount of unguessability that it provides. 
+Two important points are to make sure that the attacker can't observe
+your sources (so if you like the Lava lamp idea, remember that you have
+to get your own lamp, and not put it by a window or anywhere else where
+strangers can see it), and that hardware failures are detected. What if
+the bulb in the Lava lamp, which you keep locked into a cupboard
+following the above advice, breaks after a few months?
+
+   <p>So let's assume that we have been able to find an unguessable seed,
+which contains at least 80 bits of conditional entropy, relative to all
+attackers that we care about (typically, we must at the very least
+assume that no attacker has root privileges on our machine).
+
+   <p>How do we generate output from this seed, and how much can we get? Some
+generators (notably the Linux <samp><span class="file">/dev/random</span></samp> generator) tries to
+estimate available entropy and restrict the amount of output. The goal
+is that if you read 128 bits from <samp><span class="file">/dev/random</span></samp>, you should get 128
+&ldquo;truly random&rdquo; bits. This is a property that is useful in some
+specialized circumstances, for instance when generating key material for
+a one time pad, or when working with unconditional blinding, but in most
+cases, it doesn't matter much. For most application, there's no limit on
+the amount of useful &ldquo;random&rdquo; data that we can generate from a small
+seed; what matters is that the seed is unguessable and that the
+generator has good cryptographic properties.
+
+   <p>At the heart of all generators lies its internal state. Future output
+is determined by the internal state alone. Let's call it the generator's
+key. The key is initialized from the unguessable seed. Important
+properties of a generator are:
+
+     <dl>
+<dt><dfn>Key-hiding</dfn><dd>An attacker observing the output should not be able to recover the
+generator's key.
+
+     <br><dt><dfn>Independence of outputs</dfn><dd>Observing some of the output should not help the attacker to guess
+previous or future output.
+
+     <br><dt><dfn>Forward secrecy</dfn><dd>Even if an attacker compromises the generator's key, he should not be
+able to guess the generator output <em>before</em> the key compromise.
+
+     <br><dt><dfn>Recovery from key compromise</dfn><dd>If an attacker compromises the generator's key, he can compute
+<em>all</em> future output. This is inevitable if the generator is seeded
+only once, at startup. However, the generator can provide a reseeding
+mechanism, to achieve recovery from key compromise. More precisely: If
+the attacker compromises the key at a particular time <code>t_1</code>, there
+is another later time <code>t_2</code>, such that if the attacker observes all
+output generated between <code>t_1</code> and <code>t_2</code>, he still can't guess
+what output is generated after <code>t_2</code>.
+
+   </dl>
+
+   <p>Nettle includes one randomness generator that is believed to have all
+the above properties, and two simpler ones.
+
+   <p><acronym>ARCFOUR</acronym>, like any stream cipher, can be used as a randomness
+generator. Its output should be of reasonable quality, if the seed is
+hashed properly before it is used with <code>arcfour_set_key</code>. There's
+no single natural way to reseed it, but if you need reseeding, you
+should be using Yarrow instead.
+
+   <p>The &ldquo;lagged Fibonacci&rdquo; generator in <samp><span class="file">&lt;nettle/knuth-lfib.h&gt;</span></samp> is a
+fast generator with good statistical properties, but is <strong>not</strong> for
+cryptographic use, and therefore not documented here. It is included
+mostly because the Nettle test suite needs to generate some test data
+from a small seed.
+
+   <p>The recommended generator to use is Yarrow, described below.
+
+<h4 class="subsection">6.6.1 Yarrow</h4>
+
+<p>Yarrow is a family of pseudo-randomness generators, designed for
+cryptographic use, by John Kelsey, Bruce Schneier and Niels Ferguson. 
+Yarrow-160 is described in a paper at
+<a href="http://www.counterpane.com/yarrow.html">http://www.counterpane.com/yarrow.html</a>, and it uses <acronym>SHA1</acronym>
+and triple-DES, and has a 160-bit internal state. Nettle implements
+Yarrow-256, which is similar, but uses <acronym>SHA256</acronym> and
+<acronym>AES</acronym> to get an internal state of 256 bits.
+
+   <p>Yarrow was an almost finished project, the paper mentioned above is the
+closest thing to a specification for it, but some smaller details are
+left out. There is no official reference implementation or test cases. 
+This section includes an overview of Yarrow, but for the details of
+Yarrow-256, as implemented by Nettle, you have to consult the source
+code. Maybe a complete specification can be written later.
+
+   <p>Yarrow can use many sources (at least two are needed for proper
+reseeding), and two randomness &ldquo;pools&rdquo;, referred to as the &ldquo;slow pool&rdquo; and
+the &ldquo;fast pool&rdquo;. Input from the sources is fed alternatingly into the
+two pools. When one of the sources has contributed 100 bits of entropy
+to the fast pool, a &ldquo;fast reseed&rdquo; happens and the fast pool is mixed
+into the internal state. When at least two of the sources have
+contributed at least 160 bits each to the slow pool, a &ldquo;slow reseed&rdquo;
+takes place. The contents of both pools are mixed into the internal
+state. These procedures should ensure that the generator will eventually
+recover after a key compromise.
+
+   <p>The output is generated by using <acronym>AES</acronym> to encrypt a counter,
+using the generator's current key. After each request for output,
+another 256 bits are generated which replace the key. This ensures
+forward secrecy.
+
+   <p>Yarrow can also use a <dfn>seed file</dfn> to save state across restarts. 
+Yarrow is seeded by either feeding it the contents of the previous seed
+file, or feeding it input from its sources until a slow reseed happens.
+
+   <p>Nettle defines Yarrow-256 in <samp><span class="file">&lt;nettle/yarrow.h&gt;</span></samp>.
+
+<div class="defun">
+&mdash; Context struct: <b>struct yarrow256_ctx</b><var><a name="index-struct-yarrow256_005fctx-291"></a></var><br>
+        </div>
+
+<div class="defun">
+&mdash; Context struct: <b>struct yarrow_source</b><var><a name="index-struct-yarrow_005fsource-292"></a></var><br>
+<blockquote><p>Information about a single source. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Constant: <b>YARROW256_SEED_FILE_SIZE</b><var><a name="index-YARROW256_005fSEED_005fFILE_005fSIZE-293"></a></var><br>
+<blockquote><p>Recommanded size of the Yarrow-256 seed file. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>yarrow256_init</b> (<var>struct yarrow256_ctx *ctx, unsigned nsources, struct yarrow_source *sources</var>)<var><a name="index-yarrow256_005finit-294"></a></var><br>
+<blockquote><p>Initializes the yarrow context, and its <var>nsources</var> sources. It's
+possible to call it with <var>nsources</var>=0 and <var>sources</var>=NULL, if
+you don't need the update features. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>yarrow256_seed</b> (<var>struct yarrow256_ctx *ctx, unsigned length, uint8_t *seed_file</var>)<var><a name="index-yarrow256_005fseed-295"></a></var><br>
+<blockquote><p>Seeds Yarrow-256 from a previous seed file. <var>length</var> should be at least
+<code>YARROW256_SEED_FILE_SIZE</code>, but it can be larger.
+
+        <p>The generator will trust you that the <var>seed_file</var> data really is
+unguessable. After calling this function, you <em>must</em> overwrite the old
+seed file with newly generated data from <code>yarrow256_random</code>. If it's
+possible for several processes to read the seed file at about the same
+time, access must be coordinated using some locking mechanism. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: int <b>yarrow256_update</b> (<var>struct yarrow256_ctx *ctx, unsigned source, unsigned entropy, unsigned length, const uint8_t *data</var>)<var><a name="index-yarrow256_005fupdate-296"></a></var><br>
+<blockquote><p>Updates the generator with data from source <var>SOURCE</var> (an index that
+must be smaller than the number of sources). <var>entropy</var> is your
+estimated lower bound for the entropy in the data, measured in bits. 
+Calling update with zero <var>entropy</var> is always safe, no matter if the
+data is random or not.
+
+        <p>Returns 1 if a reseed happened, in which case an application using a
+seed file may want to generate new seed data with
+<code>yarrow256_random</code> and overwrite the seed file. Otherwise, the
+function returns 0. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>yarrow256_random</b> (<var>struct yarrow256_ctx *ctx, unsigned length, uint8_t *dst</var>)<var><a name="index-yarrow256_005frandom-297"></a></var><br>
+<blockquote><p>Generates <var>length</var> octets of output. The generator must be seeded
+before you call this function.
+
+        <p>If you don't need forward secrecy, e.g. if you need non-secret
+randomness for initialization vectors or padding, you can gain some
+efficiency by buffering, calling this function for reasonably large
+blocks of data, say 100-1000 octets at a time. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: int <b>yarrow256_is_seeded</b> (<var>struct yarrow256_ctx *ctx</var>)<var><a name="index-yarrow256_005fis_005fseeded-298"></a></var><br>
+<blockquote><p>Returns 1 if the generator is seeded and ready to generate output,
+otherwise 0. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: unsigned <b>yarrow256_needed_sources</b> (<var>struct yarrow256_ctx *ctx</var>)<var><a name="index-yarrow256_005fneeded_005fsources-299"></a></var><br>
+<blockquote><p>Returns the number of sources that must reach the threshold before a
+slow reseed will happen. Useful primarily when the generator is unseeded. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>yarrow256_fast_reseed</b> (<var>struct yarrow256_ctx *ctx</var>)<var><a name="index-yarrow256_005ffast_005freseed-300"></a></var><br>
+&mdash; Function: void <b>yarrow256_slow_reseed</b> (<var>struct yarrow256_ctx *ctx</var>)<var><a name="index-yarrow256_005fslow_005freseed-301"></a></var><br>
+<blockquote><p>Causes a fast or slow reseed to take place immediately, regardless of the
+current entropy estimates of the two pools. Use with care. 
+</p></blockquote></div>
+
+   <p>Nettle includes an entropy estimator for one kind of input source: User
+keyboard input.
+
+<div class="defun">
+&mdash; Context struct: <b>struct yarrow_key_event_ctx</b><var><a name="index-struct-yarrow_005fkey_005fevent_005fctx-302"></a></var><br>
+<blockquote><p>Information about recent key events. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: void <b>yarrow_key_event_init</b> (<var>struct yarrow_key_event_ctx *ctx</var>)<var><a name="index-yarrow_005fkey_005fevent_005finit-303"></a></var><br>
+<blockquote><p>Initializes the context. 
+</p></blockquote></div>
+
+<div class="defun">
+&mdash; Function: unsigned <b>yarrow_key_event_estimate</b> (<var>struct yarrow_key_event_ctx *ctx, unsigned key, unsigned time</var>)<var><a name="index-yarrow_005fkey_005fevent_005festimate-304"></a></var><br>
+<blockquote><p><var>key</var> is the id of the key (ASCII value, hardware key code, X
+keysym, <small class="dots">...</small>, it doesn't matter), and <var>time</var> is the timestamp of
+the event. The time must be given in units matching the resolution by
+which you read the clock. If you read the clock with microsecond
+precision, <var>time</var> should be provided in units of microseconds. But
+if you use <code>gettimeofday</code> on a typical Unix system where the clock
+ticks 10 or so microseconds at a time, <var>time</var> should be given in
+units of 10 microseconds.
+
+        <p>Returns an entropy estimate, in bits, suitable for calling
+<code>yarrow256_update</code>. Usually, 0, 1 or 2 bits. 
+</p></blockquote></div>
+
+<div class="node">
+<a name="Miscellaneous-functions"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#Compatibility-functions">Compatibility functions</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Randomness">Randomness</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Reference">Reference</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h3 class="section">6.7 Miscellaneous functions</h3>
+
+<div class="defun">
+&mdash; Function: uint8_t * <b>memxor</b> (<var>uint8_t *dst, const uint8_t *src, size_t n</var>)<var><a name="index-memxor-305"></a></var><br>
+<blockquote><p>XORs the source area on top of the destination area. The interface
+doesn't follow the Nettle conventions, because it is intended to be
+similar to the ANSI-C <code>memcpy</code> function. 
+</p></blockquote></div>
+
+   <p><code>memxor</code> is declared in <samp><span class="file">&lt;nettle/memxor.h&gt;</span></samp>.
+
+<div class="node">
+<a name="Compatibility-functions"></a>
+<p><hr>
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Miscellaneous-functions">Miscellaneous functions</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Reference">Reference</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h3 class="section">6.8 Compatibility functions</h3>
+
+<p>For convenience, Nettle includes alternative interfaces to some
+algorithms, for compatibility with some other popular crypto toolkits. 
+These are not fully documented here; refer to the source or to the
+documentation for the original implementation.
+
+   <p>MD5 is defined in [RFC 1321], which includes a reference implementation. 
+Nettle defines a compatible interface to MD5 in
+<samp><span class="file">&lt;nettle/md5-compat.h&gt;</span></samp>. This file defines the typedef
+<code>MD5_CTX</code>, and declares the functions <code>MD5Init</code>, <code>MD5Update</code> and
+<code>MD5Final</code>.
+
+   <p>Eric Young's &ldquo;libdes&rdquo; (also part of OpenSSL) is a quite popular DES
+implementation. Nettle includes a subset if its interface in
+<samp><span class="file">&lt;nettle/des-compat.h&gt;</span></samp>. This file defines the typedefs
+<code>des_key_schedule</code> and <code>des_cblock</code>, two constants
+<code>DES_ENCRYPT</code> and <code>DES_DECRYPT</code>, and declares one global
+variable <code>des_check_key</code>, and the functions <code>des_cbc_cksum</code>
+<code>des_cbc_encrypt</code>, <code>des_ecb2_encrypt</code>,
+<code>des_ecb3_encrypt</code>, <code>des_ecb_encrypt</code>,
+<code>des_ede2_cbc_encrypt</code>, <code>des_ede3_cbc_encrypt</code>,
+<code>des_is_weak_key</code>, <code>des_key_sched</code>, <code>des_ncbc_encrypt</code>
+<code>des_set_key</code>, and <code>des_set_odd_parity</code>.
+
+<div class="node">
+<a name="Nettle-soup"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#Installation">Installation</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Reference">Reference</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Top">Top</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h2 class="chapter">7 Traditional Nettle Soup</h2>
+
+<p>For the serious nettle hacker, here is a recipe for nettle soup. 4 servings.
+
+     <ul>
+<li>1 liter fresh nettles (urtica dioica)
+<li>2 tablespoons butter
+<li>3 tablespoons flour
+<li>1 liter stock (meat or vegetable)
+<li>1/2 teaspoon salt
+<li>a tad white pepper
+<li>some cream or milk
+</ul>
+
+   <p>Gather 1 liter fresh nettles. Use gloves! Small, tender shoots are
+preferable but the tops of larger nettles can also be used.
+
+   <p>Rinse the nettles very well. Boil them for 10 minutes in lightly salted
+water. Strain the nettles and save the water. Hack the nettles. Melt the
+butter and mix in the flour. Dilute with stock and the nettle-water you
+saved earlier. Add the hacked nettles. If you wish you can add some milk
+or cream at this stage. Bring to a boil and let boil for a few minutes. 
+Season with salt and pepper.
+
+   <p>Serve with boiled egg-halves.
+
+<!-- And the original Swedish version. -->
+<div class="node">
+<a name="Installation"></a>
+<p><hr>
+Next:&nbsp;<a rel="next" accesskey="n" href="#Index">Index</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Nettle-soup">Nettle soup</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Top">Top</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h2 class="chapter">8 Installation</h2>
+
+<p>Nettle uses <samp><span class="command">autoconf</span></samp>. To build it, unpack the source and run
+
+<pre class="example">     ./configure
+     make
+     make check
+     make install
+</pre>
+   <p class="noindent">to install in the default location, <samp><span class="file">/usr/local</span></samp>. The library files
+are installed in <samp><span class="file">/use/local/lib/libnettle.a</span></samp>
+<samp><span class="file">/use/local/lib/libhogweed.a</span></samp> and the include files are installed
+in <samp><span class="file">/use/local/include/nettle/</span></samp>.
+
+   <p>To get a list of configure options, use <code>./configure --help</code>.
+
+   <p>By default, only static libraries are built and installed. To also build
+and install shared libraries, use the <samp><span class="option"> --enable-shared</span></samp> option
+to <samp><span class="command">./configure</span></samp>.
+
+   <p>Using GNU make is recommended. For other make programs, in particular
+BSD make, you may have to use the <samp><span class="option">--disable-dependency-tracking</span></samp>
+option to <samp><span class="command">./configure</span></samp>.
+
+<div class="node">
+<a name="Index"></a>
+<p><hr>
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Installation">Installation</a>,
+Up:&nbsp;<a rel="up" accesskey="u" href="#Top">Top</a>
+
+</div>
+
+<!-- node-name,  next,  previous,  up -->
+<h2 class="unnumbered">Function and Concept Index</h2>
+
+<ul class="index-cp" compact>
+<li><a href="#index-aes_005fdecrypt-81"><code>aes_decrypt</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-aes_005fencrypt-80"><code>aes_encrypt</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-aes_005finvert_005fkey-79"><code>aes_invert_key</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-aes_005fset_005fdecrypt_005fkey-78"><code>aes_set_decrypt_key</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-aes_005fset_005fencrypt_005fkey-77"><code>aes_set_encrypt_key</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-arcfour_005fcrypt-87"><code>arcfour_crypt</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-arcfour_005fset_005fkey-86"><code>arcfour_set_key</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-arctwo_005fdecrypt-97"><code>arctwo_decrypt</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-arctwo_005fencrypt-96"><code>arctwo_encrypt</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-arctwo_005fset_005fkey-94"><code>arctwo_set_key</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-arctwo_005fset_005fkey_005fekb-93"><code>arctwo_set_key_ekb</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-arctwo_005fset_005fkey_005fgutmann-95"><code>arctwo_set_key_gutmann</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-Block-Cipher-70">Block Cipher</a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-blowfish_005fdecrypt-105"><code>blowfish_decrypt</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-blowfish_005fencrypt-104"><code>blowfish_encrypt</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-blowfish_005fset_005fkey-103"><code>blowfish_set_key</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-camellia_005fcrypt-114"><code>camellia_crypt</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-camellia_005finvert_005fkey-113"><code>camellia_invert_key</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-camellia_005fset_005fdecrypt_005fkey-112"><code>camellia_set_decrypt_key</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-camellia_005fset_005fencrypt_005fkey-111"><code>camellia_set_encrypt_key</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-cast128_005fdecrypt-122"><code>cast128_decrypt</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-cast128_005fencrypt-121"><code>cast128_encrypt</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-cast128_005fset_005fkey-120"><code>cast128_set_key</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-CBC-Mode-174">CBC Mode</a>: <a href="#CBC">CBC</a></li>
+<li><a href="#index-CBC_005fCTX-177"><code>CBC_CTX</code></a>: <a href="#CBC">CBC</a></li>
+<li><a href="#index-CBC_005fDECRYPT-180"><code>CBC_DECRYPT</code></a>: <a href="#CBC">CBC</a></li>
+<li><a href="#index-cbc_005fdecrypt-176"><code>cbc_decrypt</code></a>: <a href="#CBC">CBC</a></li>
+<li><a href="#index-CBC_005fENCRYPT-179"><code>CBC_ENCRYPT</code></a>: <a href="#CBC">CBC</a></li>
+<li><a href="#index-cbc_005fencrypt-175"><code>cbc_encrypt</code></a>: <a href="#CBC">CBC</a></li>
+<li><a href="#index-CBC_005fSET_005fIV-178"><code>CBC_SET_IV</code></a>: <a href="#CBC">CBC</a></li>
+<li><a href="#index-Cipher-69">Cipher</a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-Cipher-Block-Chaining-173">Cipher Block Chaining</a>: <a href="#CBC">CBC</a></li>
+<li><a href="#index-Collision_002dresistant-3">Collision-resistant</a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-Conditional-entropy-290">Conditional entropy</a>: <a href="#Randomness">Randomness</a></li>
+<li><a href="#index-Counter-Mode-181">Counter Mode</a>: <a href="#CTR">CTR</a></li>
+<li><a href="#index-CTR-Mode-182">CTR Mode</a>: <a href="#CTR">CTR</a></li>
+<li><a href="#index-CTR_005fCRYPT-186"><code>CTR_CRYPT</code></a>: <a href="#CTR">CTR</a></li>
+<li><a href="#index-ctr_005fcrypt-183"><code>ctr_crypt</code></a>: <a href="#CTR">CTR</a></li>
+<li><a href="#index-CTR_005fCTX-184"><code>CTR_CTX</code></a>: <a href="#CTR">CTR</a></li>
+<li><a href="#index-CTR_005fSET_005fCOUNTER-185"><code>CTR_SET_COUNTER</code></a>: <a href="#CTR">CTR</a></li>
+<li><a href="#index-des3_005fdecrypt-136"><code>des3_decrypt</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-des3_005fencrypt-135"><code>des3_encrypt</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-des3_005fset_005fkey-134"><code>des3_set_key</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-des_005fcheck_005fparity-129"><code>des_check_parity</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-des_005fdecrypt-128"><code>des_decrypt</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-des_005fencrypt-127"><code>des_encrypt</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-des_005ffix_005fparity-130"><code>des_fix_parity</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-des_005fset_005fkey-126"><code>des_set_key</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-dsa_005fgenerate_005fkeypair-287"><code>dsa_generate_keypair</code></a>: <a href="#DSA">DSA</a></li>
+<li><a href="#index-dsa_005fprivate_005fkey_005fclear-275"><code>dsa_private_key_clear</code></a>: <a href="#DSA">DSA</a></li>
+<li><a href="#index-dsa_005fprivate_005fkey_005finit-273"><code>dsa_private_key_init</code></a>: <a href="#DSA">DSA</a></li>
+<li><a href="#index-dsa_005fpublic_005fkey_005fclear-274"><code>dsa_public_key_clear</code></a>: <a href="#DSA">DSA</a></li>
+<li><a href="#index-dsa_005fpublic_005fkey_005finit-272"><code>dsa_public_key_init</code></a>: <a href="#DSA">DSA</a></li>
+<li><a href="#index-dsa_005fsha1_005fsign-279"><code>dsa_sha1_sign</code></a>: <a href="#DSA">DSA</a></li>
+<li><a href="#index-dsa_005fsha1_005fsign_005fdigest-280"><code>dsa_sha1_sign_digest</code></a>: <a href="#DSA">DSA</a></li>
+<li><a href="#index-dsa_005fsha1_005fverify-283"><code>dsa_sha1_verify</code></a>: <a href="#DSA">DSA</a></li>
+<li><a href="#index-dsa_005fsha1_005fverify_005fdigest-284"><code>dsa_sha1_verify_digest</code></a>: <a href="#DSA">DSA</a></li>
+<li><a href="#index-dsa_005fsha256_005fsign-281"><code>dsa_sha256_sign</code></a>: <a href="#DSA">DSA</a></li>
+<li><a href="#index-dsa_005fsha256_005fsign_005fdigest-282"><code>dsa_sha256_sign_digest</code></a>: <a href="#DSA">DSA</a></li>
+<li><a href="#index-dsa_005fsha256_005fverify-285"><code>dsa_sha256_verify</code></a>: <a href="#DSA">DSA</a></li>
+<li><a href="#index-dsa_005fsha256_005fverify_005fdigest-286"><code>dsa_sha256_verify_digest</code></a>: <a href="#DSA">DSA</a></li>
+<li><a href="#index-dsa_005fsignature_005fclear-278"><code>dsa_signature_clear</code></a>: <a href="#DSA">DSA</a></li>
+<li><a href="#index-dsa_005fsignature_005finit-277"><code>dsa_signature_init</code></a>: <a href="#DSA">DSA</a></li>
+<li><a href="#index-Entropy-289">Entropy</a>: <a href="#Randomness">Randomness</a></li>
+<li><a href="#index-Galois-Counter-Mode-187">Galois Counter Mode</a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-GCM-188">GCM</a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-gcm_005faes_005fdecrypt-211"><code>gcm_aes_decrypt</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-gcm_005faes_005fdigest-212"><code>gcm_aes_digest</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-gcm_005faes_005fencrypt-210"><code>gcm_aes_encrypt</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-gcm_005faes_005fset_005fiv-208"><code>gcm_aes_set_iv</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-gcm_005faes_005fset_005fkey-207"><code>gcm_aes_set_key</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-gcm_005faes_005fupdate-209"><code>gcm_aes_update</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-GCM_005fCTX-199"><code>GCM_CTX</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-GCM_005fDECRYPT-204"><code>GCM_DECRYPT</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-gcm_005fdecrypt-197"><code>gcm_decrypt</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-GCM_005fDIGEST-205"><code>GCM_DIGEST</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-gcm_005fdigest-198"><code>gcm_digest</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-GCM_005fENCRYPT-203"><code>GCM_ENCRYPT</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-gcm_005fencrypt-196"><code>gcm_encrypt</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-GCM_005fSET_005fIV-201"><code>GCM_SET_IV</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-gcm_005fset_005fiv-194"><code>gcm_set_iv</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-GCM_005fSET_005fKEY-200"><code>GCM_SET_KEY</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-gcm_005fset_005fkey-193"><code>gcm_set_key</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-GCM_005fUPDATE-202"><code>GCM_UPDATE</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-gcm_005fupdate-195"><code>gcm_update</code></a>: <a href="#GCM">GCM</a></li>
+<li><a href="#index-Hash-function-1">Hash function</a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-HMAC_005fCTX-219"><code>HMAC_CTX</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-HMAC_005fDIGEST-221"><code>HMAC_DIGEST</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-hmac_005fdigest-218"><code>hmac_digest</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-hmac_005fmd5_005fdigest-225"><code>hmac_md5_digest</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-hmac_005fmd5_005fset_005fkey-223"><code>hmac_md5_set_key</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-hmac_005fmd5_005fupdate-224"><code>hmac_md5_update</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-hmac_005fripemd160_005fdigest-229"><code>hmac_ripemd160_digest</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-hmac_005fripemd160_005fset_005fkey-227"><code>hmac_ripemd160_set_key</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-hmac_005fripemd160_005fupdate-228"><code>hmac_ripemd160_update</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-HMAC_005fSET_005fKEY-220"><code>HMAC_SET_KEY</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-hmac_005fset_005fkey-216"><code>hmac_set_key</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-hmac_005fsha1_005fdigest-233"><code>hmac_sha1_digest</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-hmac_005fsha1_005fset_005fkey-231"><code>hmac_sha1_set_key</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-hmac_005fsha1_005fupdate-232"><code>hmac_sha1_update</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-hmac_005fsha256_005fdigest-237"><code>hmac_sha256_digest</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-hmac_005fsha256_005fset_005fkey-235"><code>hmac_sha256_set_key</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-hmac_005fsha256_005fupdate-236"><code>hmac_sha256_update</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-hmac_005fsha512_005fdigest-241"><code>hmac_sha512_digest</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-hmac_005fsha512_005fset_005fkey-239"><code>hmac_sha512_set_key</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-hmac_005fsha512_005fupdate-240"><code>hmac_sha512_update</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-hmac_005fupdate-217"><code>hmac_update</code></a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-Keyed-Hash-Function-213">Keyed Hash Function</a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-MAC-215">MAC</a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-md2_005fdigest-15"><code>md2_digest</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-md2_005finit-13"><code>md2_init</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-md2_005fupdate-14"><code>md2_update</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-md4_005fdigest-21"><code>md4_digest</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-md4_005finit-19"><code>md4_init</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-md4_005fupdate-20"><code>md4_update</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-md5_005fdigest-9"><code>md5_digest</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-md5_005finit-7"><code>md5_init</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-md5_005fupdate-8"><code>md5_update</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-memxor-305"><code>memxor</code></a>: <a href="#Miscellaneous-functions">Miscellaneous functions</a></li>
+<li><a href="#index-Message-Authentication-Code-214">Message Authentication Code</a>: <a href="#Keyed-hash-functions">Keyed hash functions</a></li>
+<li><a href="#index-One_002dway-2">One-way</a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-One_002dway-function-243">One-way function</a>: <a href="#Public_002dkey-algorithms">Public-key algorithms</a></li>
+<li><a href="#index-Public-Key-Cryptography-242">Public Key Cryptography</a>: <a href="#Public_002dkey-algorithms">Public-key algorithms</a></li>
+<li><a href="#index-Randomness-288">Randomness</a>: <a href="#Randomness">Randomness</a></li>
+<li><a href="#index-ripemd160_005fdigest-27"><code>ripemd160_digest</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-ripemd160_005finit-25"><code>ripemd160_init</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-ripemd160_005fupdate-26"><code>ripemd160_update</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-rsa_005fcompute_005froot-268"><code>rsa_compute_root</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fgenerate_005fkeypair-269"><code>rsa_generate_keypair</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fmd5_005fsign-252"><code>rsa_md5_sign</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fmd5_005fsign_005fdigest-256"><code>rsa_md5_sign_digest</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fmd5_005fverify-260"><code>rsa_md5_verify</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fmd5_005fverify_005fdigest-264"><code>rsa_md5_verify_digest</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fprivate_005fkey_005fclear-249"><code>rsa_private_key_clear</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fprivate_005fkey_005finit-247"><code>rsa_private_key_init</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fprivate_005fkey_005fprepare-251"><code>rsa_private_key_prepare</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fpublic_005fkey_005fclear-248"><code>rsa_public_key_clear</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fpublic_005fkey_005finit-246"><code>rsa_public_key_init</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fpublic_005fkey_005fprepare-250"><code>rsa_public_key_prepare</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fsha1_005fsign-253"><code>rsa_sha1_sign</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fsha1_005fsign_005fdigest-257"><code>rsa_sha1_sign_digest</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fsha1_005fverify-261"><code>rsa_sha1_verify</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fsha1_005fverify_005fdigest-265"><code>rsa_sha1_verify_digest</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fsha256_005fsign-254"><code>rsa_sha256_sign</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fsha256_005fsign_005fdigest-258"><code>rsa_sha256_sign_digest</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fsha256_005fverify-262"><code>rsa_sha256_verify</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fsha256_005fverify_005fdigest-266"><code>rsa_sha256_verify_digest</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fsha512_005fsign-255"><code>rsa_sha512_sign</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fsha512_005fsign_005fdigest-259"><code>rsa_sha512_sign_digest</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fsha512_005fverify-263"><code>rsa_sha512_verify</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-rsa_005fsha512_005fverify_005fdigest-267"><code>rsa_sha512_verify_digest</code></a>: <a href="#RSA">RSA</a></li>
+<li><a href="#index-serpent_005fdecrypt-144"><code>serpent_decrypt</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-serpent_005fencrypt-143"><code>serpent_encrypt</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-serpent_005fset_005fkey-142"><code>serpent_set_key</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-sha1_005fdigest-33"><code>sha1_digest</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-sha1_005finit-31"><code>sha1_init</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-sha1_005fupdate-32"><code>sha1_update</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-sha224_005fdigest-45"><code>sha224_digest</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-sha224_005finit-43"><code>sha224_init</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-sha224_005fupdate-44"><code>sha224_update</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-sha256_005fdigest-39"><code>sha256_digest</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-sha256_005finit-37"><code>sha256_init</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-sha256_005fupdate-38"><code>sha256_update</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-sha384_005fdigest-57"><code>sha384_digest</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-sha384_005finit-55"><code>sha384_init</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-sha384_005fupdate-56"><code>sha384_update</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-sha512_005fdigest-51"><code>sha512_digest</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-sha512_005finit-49"><code>sha512_init</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-sha512_005fupdate-50"><code>sha512_update</code></a>: <a href="#Hash-functions">Hash functions</a></li>
+<li><a href="#index-Stream-Cipher-71">Stream Cipher</a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-twofish_005fdecrypt-152"><code>twofish_decrypt</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-twofish_005fencrypt-151"><code>twofish_encrypt</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-twofish_005fset_005fkey-150"><code>twofish_set_key</code></a>: <a href="#Cipher-functions">Cipher functions</a></li>
+<li><a href="#index-yarrow256_005ffast_005freseed-300"><code>yarrow256_fast_reseed</code></a>: <a href="#Randomness">Randomness</a></li>
+<li><a href="#index-yarrow256_005finit-294"><code>yarrow256_init</code></a>: <a href="#Randomness">Randomness</a></li>
+<li><a href="#index-yarrow256_005fis_005fseeded-298"><code>yarrow256_is_seeded</code></a>: <a href="#Randomness">Randomness</a></li>
+<li><a href="#index-yarrow256_005fneeded_005fsources-299"><code>yarrow256_needed_sources</code></a>: <a href="#Randomness">Randomness</a></li>
+<li><a href="#index-yarrow256_005frandom-297"><code>yarrow256_random</code></a>: <a href="#Randomness">Randomness</a></li>
+<li><a href="#index-yarrow256_005fseed-295"><code>yarrow256_seed</code></a>: <a href="#Randomness">Randomness</a></li>
+<li><a href="#index-yarrow256_005fslow_005freseed-301"><code>yarrow256_slow_reseed</code></a>: <a href="#Randomness">Randomness</a></li>
+<li><a href="#index-yarrow256_005fupdate-296"><code>yarrow256_update</code></a>: <a href="#Randomness">Randomness</a></li>
+<li><a href="#index-yarrow_005fkey_005fevent_005festimate-304"><code>yarrow_key_event_estimate</code></a>: <a href="#Randomness">Randomness</a></li>
+<li><a href="#index-yarrow_005fkey_005fevent_005finit-303"><code>yarrow_key_event_init</code></a>: <a href="#Randomness">Randomness</a></li>
+   </ul><div class="footnote">
+<hr>
+<a name="texinfo-footnotes-in-document"></a><h4>Footnotes</h4><p class="footnote"><small>[<a name="fn-1" href="#fnd-1">1</a>]</small> Actually, the computation is not done like this, it is
+done more efficiently using <code>p</code>, <code>q</code> and the Chinese remainder
+theorem (<acronym>CRT</acronym>). But the result is the same.</p>
+
+   <hr></div>
+
+</body></html>
+
+<!--
+\1f
+Local Variables:
+coding: iso-8859-1
+End:
+
+-->
diff --git a/nettle.info b/nettle.info
new file mode 100644 (file)
index 0000000..fd8f13c
--- /dev/null
@@ -0,0 +1,3120 @@
+This is nettle.info, produced by makeinfo version 4.13 from
+nettle.texinfo.
+
+This manual is for the Nettle library (version 2.3), a low-level
+cryptographic library.
+
+   Originally written 2001 by Niels Möller, updated 2011.
+
+     This manual is placed in the public domain. You may freely copy
+     it, in whole or in part, with or without modification. Attribution
+     is appreciated, but not required.
+
+INFO-DIR-SECTION Encryption
+START-INFO-DIR-ENTRY
+* Nettle: (nettle).             A low-level cryptographic library.
+END-INFO-DIR-ENTRY
+
+\1f
+File: nettle.info,  Node: Top,  Next: Introduction,  Prev: (dir),  Up: (dir)
+
+Nettle
+******
+
+This document describes the Nettle low-level cryptographic library. You
+can use the library directly from your C programs, or write or use an
+object-oriented wrapper for your favorite language or application.
+
+   This manual is for the Nettle library (version 2.3), a low-level
+cryptographic library.
+
+   Originally written 2001 by Niels Möller, updated 2011.
+
+     This manual is placed in the public domain. You may freely copy
+     it, in whole or in part, with or without modification. Attribution
+     is appreciated, but not required.
+
+* Menu:
+
+* Introduction::                What is Nettle?
+* Copyright::                   Your rights.
+* Conventions::                 General interface conventions.
+* Example::                     An example program.
+* Linking::                     Linking with the libnettle and libhogweed.
+* Reference::                   All Nettle functions and features.
+* Nettle soup::                 For the serious nettle hacker.
+* Installation::                How to install Nettle.
+* Index::                       Function and concept index.
+
+ --- The Detailed Node Listing ---
+
+Reference
+
+* Hash functions::
+* Cipher functions::
+* Cipher modes::
+* Keyed hash functions::
+* Public-key algorithms::
+* Randomness::
+* Miscellaneous functions::
+* Compatibility functions::
+
+Cipher modes
+
+* CBC::
+* CTR::
+* GCM::
+
+Public-key algorithms
+
+* RSA::                         The RSA public key algorithm.
+* DSA::                         The DSA digital signature algorithm.
+
+\1f
+File: nettle.info,  Node: Introduction,  Next: Copyright,  Prev: Top,  Up: Top
+
+1 Introduction
+**************
+
+Nettle is a cryptographic library that is designed to fit easily in more
+or less any context: In crypto toolkits for object-oriented languages
+(C++, Python, Pike, ...), in applications like LSH or GNUPG, or even in
+kernel space. In most contexts, you need more than the basic
+cryptographic algorithms, you also need some way to keep track of
+available algorithms, their properties and variants. You often have
+some algorithm selection process, often dictated by a protocol you want
+to implement.
+
+   And as the requirements of applications differ in subtle and not so
+subtle ways, an API that fits one application well can be a pain to use
+in a different context. And that is why there are so many different
+cryptographic libraries around.
+
+   Nettle tries to avoid this problem by doing one thing, the low-level
+crypto stuff, and providing a _simple_ but general interface to it.  In
+particular, Nettle doesn't do algorithm selection. It doesn't do memory
+allocation. It doesn't do any I/O.
+
+   The idea is that one can build several application and context
+specific interfaces on top of Nettle, and share the code, test cases,
+benchmarks, documentation, etc. Examples are the Nettle module for the
+Pike language, and LSH, which both use an object-oriented abstraction
+on top of the library.
+
+   This manual explains how to use the Nettle library. It also tries to
+provide some background on the cryptography, and advice on how to best
+put it to use.
+
+\1f
+File: nettle.info,  Node: Copyright,  Next: Conventions,  Prev: Introduction,  Up: Top
+
+2 Copyright
+***********
+
+Nettle is distributed under the GNU Lesser General Public License
+(LGPL), see the file COPYING.LIB for details. A few of the individual
+files are in the public domain. To find the current status of particular
+files, you have to read the copyright notices at the top of the files.
+
+   This manual is in the public domain. You may freely copy it in whole
+or in part, e.g., into documentation of programs that build on Nettle.
+Attribution, as well as contribution of improvements to the text, is of
+course appreciated, but it is not required.
+
+   A list of the supported algorithms, their origins and licenses:
+
+_AES_
+     The implementation of the AES cipher (also known as rijndael) is
+     written by Rafael Sevilla. Assembler for x86 by Rafael Sevilla and
+     Niels Möller, Sparc assembler by Niels Möller. Released under the
+     LGPL.
+
+_ARCFOUR_
+     The implementation of the ARCFOUR (also known as RC4) cipher is
+     written by Niels Möller. Released under the LGPL.
+
+_ARCTWO_
+     The implementation of the ARCTWO (also known as RC2) cipher is
+     written by Nikos Mavroyanopoulos and modified by Werner Koch and
+     Simon Josefsson. Released under the LGPL.
+
+_BLOWFISH_
+     The implementation of the BLOWFISH cipher is written by Werner
+     Koch, copyright owned by the Free Software Foundation. Also hacked
+     by Simon Josefsson and Niels Möller. Released under the LGPL.
+
+_CAMELLIA_
+     The C implementation is by Nippon Telegraph and Telephone
+     Corporation (NTT), heavily modified by Niels Möller. Assembler for
+     x86 and x86_64 by Niels Möller. Released under the LGPL.
+
+_CAST128_
+     The implementation of the CAST128 cipher is written by Steve Reid.
+     Released into the public domain.
+
+_DES_
+     The implementation of the DES cipher is written by Dana L. How, and
+     released under the LGPL.
+
+_MD2_
+     The implementation of MD2 is written by Andrew Kuchling, and hacked
+     some by Andreas Sigfridsson and Niels Möller. Python Cryptography
+     Toolkit license (essentially public domain).
+
+_MD4_
+     This is almost the same code as for MD5 below, with modifications
+     by Marcus Comstedt. Released into the public domain.
+
+_MD5_
+     The implementation of the MD5 message digest is written by Colin
+     Plumb.  It has been hacked some more by Andrew Kuchling and Niels
+     Möller.  Released into the public domain.
+
+_RIPMED160_
+     The implementation of RIPEMD160 message digest is based on the
+     code in libgcrypt, copyright owned by the Free Software
+     Foundation. Ported to Nettle by Andres Mejia. Released under the
+     LGPL.
+
+_SERPENT_
+     The implementation of the SERPENT cipher is based on the code in
+     libgcrypt, copyright owned by the Free Software Foundation.
+     Adapted to Nettle by Simon Josefsson and heavily modified by Niels
+     Möller. Assembly for x86_64 by Niels Möller. Released under the
+     LGPL.
+
+_SHA1_
+     The C implementation of the SHA1 message digest is written by Peter
+     Gutmann, and hacked some more by Andrew Kuchling and Niels Möller.
+     Released into the public domain. Assembler for x86 by Niels Möller,
+     released under the LGPL.
+
+_SHA224, SHA256, SHA384, and SHA512_
+     Written by Niels Möller, using Peter Gutmann's SHA1 code as a
+     model.  Released under the LGPL.
+
+_TWOFISH_
+     The implementation of the TWOFISH cipher is written by Ruud de
+     Rooij.  Released under the LGPL.
+
+_RSA_
+     Written by Niels Möller, released under the LGPL. Uses the GMP
+     library for bignum operations.
+
+_DSA_
+     Written by Niels Möller, released under the LGPL. Uses the GMP
+     library for bignum operations.
+
+\1f
+File: nettle.info,  Node: Conventions,  Next: Example,  Prev: Copyright,  Up: Top
+
+3 Conventions
+*************
+
+For each supported algorithm, there is an include file that defines a
+_context struct_, a few constants, and declares functions for operating
+on the context. The context struct encapsulates all information needed
+by the algorithm, and it can be copied or moved in memory with no
+unexpected effects.
+
+   For consistency, functions for different algorithms are very similar,
+but there are some differences, for instance reflecting if the key setup
+or encryption function differ for encryption and decryption, and whether
+or not key setup can fail. There are also differences between algorithms
+that don't show in function prototypes, but which the application must
+nevertheless be aware of. There is no big difference between the
+functions for stream ciphers and for block ciphers, although they should
+be used quite differently by the application.
+
+   If your application uses more than one algorithm of the same type,
+you should probably create an interface that is tailor-made for your
+needs, and then write a few lines of glue code on top of Nettle.
+
+   By convention, for an algorithm named `foo', the struct tag for the
+context struct is `foo_ctx', constants and functions uses prefixes like
+`FOO_BLOCK_SIZE' (a constant) and `foo_set_key' (a function).
+
+   In all functions, strings are represented with an explicit length, of
+type `unsigned', and a pointer of type `uint8_t *' or `const uint8_t
+*'. For functions that transform one string to another, the argument
+order is length, destination pointer and source pointer. Source and
+destination areas are of the same length. Source and destination may be
+the same, so that you can process strings in place, but they _must not_
+overlap in any other way.
+
+   Many of the functions lack return value and can never fail. Those
+functions which can fail, return one on success and zero on failure.
+
+\1f
+File: nettle.info,  Node: Example,  Next: Linking,  Prev: Conventions,  Up: Top
+
+4 Example
+*********
+
+A simple example program that reads a file from standard input and
+writes its SHA1 checksum on standard output should give the flavor of
+Nettle.
+
+     #include <stdio.h>
+     #include <stdlib.h>
+
+     #include <nettle/sha.h>
+
+     #define BUF_SIZE 1000
+
+     static void
+     display_hex(unsigned length, uint8_t *data)
+     {
+       unsigned i;
+
+       for (i = 0; i<length; i++)
+         printf("%02x ", data[i]);
+
+       printf("\n");
+     }
+
+     int
+     main(int argc, char **argv)
+     {
+       struct sha1_ctx ctx;
+       uint8_t buffer[BUF_SIZE];
+       uint8_t digest[SHA1_DIGEST_SIZE];
+
+       sha1_init(&ctx);
+       for (;;)
+       {
+         int done = fread(buffer, 1, sizeof(buffer), stdin);
+         sha1_update(&ctx, done, buffer);
+         if (done < sizeof(buffer))
+           break;
+       }
+       if (ferror(stdin))
+         return EXIT_FAILURE;
+
+       sha1_digest(&ctx, SHA1_DIGEST_SIZE, digest);
+
+       display_hex(SHA1_DIGEST_SIZE, digest);
+       return EXIT_SUCCESS;
+     }
+
+   On a typical Unix system, this program can be compiled and linked
+with the command line
+     cc sha-example.c -o sha-example -lnettle
+
+\1f
+File: nettle.info,  Node: Linking,  Next: Reference,  Prev: Example,  Up: Top
+
+5 Linking
+*********
+
+Nettle actually consists of two libraries, `libnettle' and
+`libhogweed'. The `libhogweed' library contains those functions of
+Nettle that uses bignum operations, and depends on the GMP library.
+With this division, linking works the same for both static and dynamic
+libraries.
+
+   If an application uses only the symmetric crypto algorithms of Nettle
+(i.e., block ciphers, hash functions, and the like), it's sufficient to
+link with `-lnettle'. If an application also uses public-key
+algorithms, the recommended linker flags are `-lhogweed -lnettle
+-lgmp'. If the involved libraries are installed as dynamic libraries, it
+may be sufficient to link with just `-lhogweed', and the loader will
+resolve the dependencies automatically.
+
+\1f
+File: nettle.info,  Node: Reference,  Next: Nettle soup,  Prev: Linking,  Up: Top
+
+6 Reference
+***********
+
+This chapter describes all the Nettle functions, grouped by family.
+
+* Menu:
+
+* Hash functions::
+* Cipher functions::
+* Cipher modes::
+* Keyed hash functions::
+* Public-key algorithms::
+* Randomness::
+* Miscellaneous functions::
+* Compatibility functions::
+
+\1f
+File: nettle.info,  Node: Hash functions,  Next: Cipher functions,  Prev: Reference,  Up: Reference
+
+6.1 Hash functions
+==================
+
+A cryptographic "hash function" is a function that takes variable size
+strings, and maps them to strings of fixed, short, length. There are
+naturally lots of collisions, as there are more possible 1MB files than
+20 byte strings. But the function is constructed such that is hard to
+find the collisions. More precisely, a cryptographic hash function `H'
+should have the following properties:
+
+_One-way_
+     Given a hash value `H(x)' it is hard to find a string `x' that
+     hashes to that value.
+
+_Collision-resistant_
+     It is hard to find two different strings, `x' and `y', such that
+     `H(x)' = `H(y)'.
+
+
+   Hash functions are useful as building blocks for digital signatures,
+message authentication codes, pseudo random generators, association of
+unique ids to documents, and many other things.
+
+   The most commonly used hash functions are MD5 and SHA1.
+Unfortunately, both these fail the collision-resistance requirement;
+cryptologists have found ways to construct colliding inputs. The
+recommended hash function for new applications is SHA256, even though
+it uses a structure similar to MD5 and SHA1. Constructing better hash
+functions is an urgent research problem.
+
+6.1.1 MD5
+---------
+
+MD5 is a message digest function constructed by Ronald Rivest, and
+described in `RFC 1321'. It outputs message digests of 128 bits, or 16
+octets. Nettle defines MD5 in `<nettle/md5.h>'.
+
+ -- Context struct: struct md5_ctx
+
+ -- Constant: MD5_DIGEST_SIZE
+     The size of an MD5 digest, i.e. 16.
+
+ -- Constant: MD5_DATA_SIZE
+     The internal block size of MD5. Useful for some special
+     constructions, in particular HMAC-MD5.
+
+ -- Function: void md5_init (struct md5_ctx *CTX)
+     Initialize the MD5 state.
+
+ -- Function: void md5_update (struct md5_ctx *CTX, unsigned LENGTH,
+          const uint8_t *DATA)
+     Hash some more data.
+
+ -- Function: void md5_digest (struct md5_ctx *CTX, unsigned LENGTH,
+          uint8_t *DIGEST)
+     Performs final processing and extracts the message digest, writing
+     it to DIGEST. LENGTH may be smaller than `MD5_DIGEST_SIZE', in
+     which case only the first LENGTH octets of the digest are written.
+
+     This function also resets the context in the same way as
+     `md5_init'.
+
+   The normal way to use MD5 is to call the functions in order: First
+`md5_init', then `md5_update' zero or more times, and finally
+`md5_digest'. After `md5_digest', the context is reset to its initial
+state, so you can start over calling `md5_update' to hash new data.
+
+   To start over, you can call `md5_init' at any time.
+
+6.1.2 MD2
+---------
+
+MD2 is another hash function of Ronald Rivest's, described in `RFC
+1319'. It outputs message digests of 128 bits, or 16 octets.  Nettle
+defines MD2 in `<nettle/md2.h>'.
+
+ -- Context struct: struct md2_ctx
+
+ -- Constant: MD2_DIGEST_SIZE
+     The size of an MD2 digest, i.e. 16.
+
+ -- Constant: MD2_DATA_SIZE
+     The internal block size of MD2.
+
+ -- Function: void md2_init (struct md2_ctx *CTX)
+     Initialize the MD2 state.
+
+ -- Function: void md2_update (struct md2_ctx *CTX, unsigned LENGTH,
+          const uint8_t *DATA)
+     Hash some more data.
+
+ -- Function: void md2_digest (struct md2_ctx *CTX, unsigned LENGTH,
+          uint8_t *DIGEST)
+     Performs final processing and extracts the message digest, writing
+     it to DIGEST. LENGTH may be smaller than `MD2_DIGEST_SIZE', in
+     which case only the first LENGTH octets of the digest are written.
+
+     This function also resets the context in the same way as
+     `md2_init'.
+
+6.1.3 MD4
+---------
+
+MD4 is a predecessor of MD5, described in `RFC 1320'. Like MD5, it is
+constructed by Ronald Rivest. It outputs message digests of 128 bits,
+or 16 octets. Nettle defines MD4 in `<nettle/md4.h>'. Use of MD4 is not
+recommended, but it is sometimes needed for compatibility with existing
+applications and protocols.
+
+ -- Context struct: struct md4_ctx
+
+ -- Constant: MD4_DIGEST_SIZE
+     The size of an MD4 digest, i.e. 16.
+
+ -- Constant: MD4_DATA_SIZE
+     The internal block size of MD4.
+
+ -- Function: void md4_init (struct md4_ctx *CTX)
+     Initialize the MD4 state.
+
+ -- Function: void md4_update (struct md4_ctx *CTX, unsigned LENGTH,
+          const uint8_t *DATA)
+     Hash some more data.
+
+ -- Function: void md4_digest (struct md4_ctx *CTX, unsigned LENGTH,
+          uint8_t *DIGEST)
+     Performs final processing and extracts the message digest, writing
+     it to DIGEST. LENGTH may be smaller than `MD4_DIGEST_SIZE', in
+     which case only the first LENGTH octets of the digest are written.
+
+     This function also resets the context in the same way as
+     `md4_init'.
+
+6.1.4 RIPEMD160
+---------------
+
+RIPEMD160 is a hash function designed by Hans Dobbertin, Antoon
+Bosselaers, and Bart Preneel, as a strengthened version of RIPEMD
+(which, like MD4 and MD5, fails the collision-resistance requirement).
+It produces message digests of 160 bits, or 20 octets. Nettle defined
+RIPEMD160 in `nettle/ripemd160.h'.
+
+ -- Context struct: struct ripemd160_ctx
+
+ -- Constant: RIPEMD160_DIGEST_SIZE
+     The size of an RIPEMD160 digest, i.e. 20.
+
+ -- Constant: RIPEMD160_DATA_SIZE
+     The internal block size of RIPEMD160.
+
+ -- Function: void ripemd160_init (struct ripemd160_ctx *CTX)
+     Initialize the RIPEMD160 state.
+
+ -- Function: void ripemd160_update (struct ripemd160_ctx *CTX,
+          unsigned LENGTH, const uint8_t *DATA)
+     Hash some more data.
+
+ -- Function: void ripemd160_digest (struct ripemd160_ctx *CTX,
+          unsigned LENGTH, uint8_t *DIGEST)
+     Performs final processing and extracts the message digest, writing
+     it to DIGEST. LENGTH may be smaller than `RIPEMD160_DIGEST_SIZE',
+     in which case only the first LENGTH octets of the digest are
+     written.
+
+     This function also resets the context in the same way as
+     `ripemd160_init'.
+
+6.1.5 SHA1
+----------
+
+SHA1 is a hash function specified by "NIST" (The U.S. National Institute
+for Standards and Technology). It outputs hash values of 160 bits, or 20
+octets. Nettle defines SHA1 in `<nettle/sha.h>'.
+
+   The functions are analogous to the MD5 ones.
+
+ -- Context struct: struct sha1_ctx
+
+ -- Constant: SHA1_DIGEST_SIZE
+     The size of an SHA1 digest, i.e. 20.
+
+ -- Constant: SHA1_DATA_SIZE
+     The internal block size of SHA1. Useful for some special
+     constructions, in particular HMAC-SHA1.
+
+ -- Function: void sha1_init (struct sha1_ctx *CTX)
+     Initialize the SHA1 state.
+
+ -- Function: void sha1_update (struct sha1_ctx *CTX, unsigned LENGTH,
+          const uint8_t *DATA)
+     Hash some more data.
+
+ -- Function: void sha1_digest (struct sha1_ctx *CTX, unsigned LENGTH,
+          uint8_t *DIGEST)
+     Performs final processing and extracts the message digest, writing
+     it to DIGEST. LENGTH may be smaller than `SHA1_DIGEST_SIZE', in
+     which case only the first LENGTH octets of the digest are written.
+
+     This function also resets the context in the same way as
+     `sha1_init'.
+
+6.1.6 SHA256
+------------
+
+SHA256 is another hash function specified by "NIST", intended as a
+replacement for SHA1, generating larger digests. It outputs hash values
+of 256 bits, or 32 octets. Nettle defines SHA256 in `<nettle/sha.h>'.
+
+   The functions are analogous to the MD5 ones.
+
+ -- Context struct: struct sha256_ctx
+
+ -- Constant: SHA256_DIGEST_SIZE
+     The size of an SHA256 digest, i.e. 32.
+
+ -- Constant: SHA256_DATA_SIZE
+     The internal block size of SHA256. Useful for some special
+     constructions, in particular HMAC-SHA256.
+
+ -- Function: void sha256_init (struct sha256_ctx *CTX)
+     Initialize the SHA256 state.
+
+ -- Function: void sha256_update (struct sha256_ctx *CTX, unsigned
+          LENGTH, const uint8_t *DATA)
+     Hash some more data.
+
+ -- Function: void sha256_digest (struct sha256_ctx *CTX, unsigned
+          LENGTH, uint8_t *DIGEST)
+     Performs final processing and extracts the message digest, writing
+     it to DIGEST. LENGTH may be smaller than `SHA256_DIGEST_SIZE', in
+     which case only the first LENGTH octets of the digest are written.
+
+     This function also resets the context in the same way as
+     `sha256_init'.
+
+6.1.7 SHA224
+------------
+
+SHA224 is a variant of SHA256, with a different initial state, and with
+the output truncated to 224 bits, or 28 octets. Nettle defines SHA224 in
+`<nettle/sha.h>'.
+
+   The functions are analogous to the MD5 ones.
+
+ -- Context struct: struct sha224_ctx
+
+ -- Constant: SHA224_DIGEST_SIZE
+     The size of an SHA224 digest, i.e. 28.
+
+ -- Constant: SHA224_DATA_SIZE
+     The internal block size of SHA224. Useful for some special
+     constructions, in particular HMAC-SHA224.
+
+ -- Function: void sha224_init (struct sha224_ctx *CTX)
+     Initialize the SHA224 state.
+
+ -- Function: void sha224_update (struct sha224_ctx *CTX, unsigned
+          LENGTH, const uint8_t *DATA)
+     Hash some more data.
+
+ -- Function: void sha224_digest (struct sha224_ctx *CTX, unsigned
+          LENGTH, uint8_t *DIGEST)
+     Performs final processing and extracts the message digest, writing
+     it to DIGEST. LENGTH may be smaller than `SHA224_DIGEST_SIZE', in
+     which case only the first LENGTH octets of the digest are written.
+
+     This function also resets the context in the same way as
+     `sha224_init'.
+
+6.1.8 SHA512
+------------
+
+SHA512 is a larger sibling to SHA256, with a very similar structure but
+with both the output and the internal variables of twice the size. The
+internal variables are 64 bits rather than 32, making it significantly
+slower on 32-bit computers. It outputs hash values of 512 bits, or 64
+octets. Nettle defines SHA512 in `<nettle/sha.h>'.
+
+   The functions are analogous to the MD5 ones.
+
+ -- Context struct: struct sha512_ctx
+
+ -- Constant: SHA512_DIGEST_SIZE
+     The size of an SHA512 digest, i.e. 64.
+
+ -- Constant: SHA512_DATA_SIZE
+     The internal block size of SHA512. Useful for some special
+     constructions, in particular HMAC-SHA512.
+
+ -- Function: void sha512_init (struct sha512_ctx *CTX)
+     Initialize the SHA512 state.
+
+ -- Function: void sha512_update (struct sha512_ctx *CTX, unsigned
+          LENGTH, const uint8_t *DATA)
+     Hash some more data.
+
+ -- Function: void sha512_digest (struct sha512_ctx *CTX, unsigned
+          LENGTH, uint8_t *DIGEST)
+     Performs final processing and extracts the message digest, writing
+     it to DIGEST. LENGTH may be smaller than `SHA512_DIGEST_SIZE', in
+     which case only the first LENGTH octets of the digest are written.
+
+     This function also resets the context in the same way as
+     `sha512_init'.
+
+6.1.9 SHA384
+------------
+
+SHA384 is a variant of SHA512, with a different initial state, and with
+the output truncated to 384 bits, or 48 octets. Nettle defines SHA384 in
+`<nettle/sha.h>'.
+
+   The functions are analogous to the MD5 ones.
+
+ -- Context struct: struct sha384_ctx
+
+ -- Constant: SHA384_DIGEST_SIZE
+     The size of an SHA384 digest, i.e. 48.
+
+ -- Constant: SHA384_DATA_SIZE
+     The internal block size of SHA384. Useful for some special
+     constructions, in particular HMAC-SHA384.
+
+ -- Function: void sha384_init (struct sha384_ctx *CTX)
+     Initialize the SHA384 state.
+
+ -- Function: void sha384_update (struct sha384_ctx *CTX, unsigned
+          LENGTH, const uint8_t *DATA)
+     Hash some more data.
+
+ -- Function: void sha384_digest (struct sha384_ctx *CTX, unsigned
+          LENGTH, uint8_t *DIGEST)
+     Performs final processing and extracts the message digest, writing
+     it to DIGEST. LENGTH may be smaller than `SHA384_DIGEST_SIZE', in
+     which case only the first LENGTH octets of the digest are written.
+
+     This function also resets the context in the same way as
+     `sha384_init'.
+
+6.1.10 `struct nettle_hash'
+---------------------------
+
+Nettle includes a struct including information about the supported hash
+functions. It is defined in `<nettle/nettle-meta.h>', and is used by
+Nettle's implementation of HMAC (*note Keyed hash functions::).
+
+ -- Meta struct: `struct nettle_hash' name context_size digest_size
+          block_size init update digest
+     The last three attributes are function pointers, of types
+     `nettle_hash_init_func', `nettle_hash_update_func', and
+     `nettle_hash_digest_func'. The first argument to these functions is
+     `void *' pointer to a context struct, which is of size
+     `context_size'.
+
+ -- Constant Struct: struct nettle_hash nettle_md2
+ -- Constant Struct: struct nettle_hash nettle_md4
+ -- Constant Struct: struct nettle_hash nettle_md5
+ -- Constant Struct: struct nettle_hash nettle_ripemd160
+ -- Constant Struct: struct nettle_hash nettle_sha1
+ -- Constant Struct: struct nettle_hash nettle_sha224
+ -- Constant Struct: struct nettle_hash nettle_sha256
+ -- Constant Struct: struct nettle_hash nettle_sha384
+ -- Constant Struct: struct nettle_hash nettle_sha512
+     These are all the hash functions that Nettle implements.
+
+     Nettle also exports a list of all these hashes.  This list can be
+     used to dynamically enumerate or search the supported algorithms:
+
+ -- Constant Struct: struct nettle_hash ** nettle_hashes
+
+\1f
+File: nettle.info,  Node: Cipher functions,  Next: Cipher modes,  Prev: Hash functions,  Up: Reference
+
+6.2 Cipher functions
+====================
+
+A "cipher" is a function that takes a message or "plaintext" and a
+secret "key" and transforms it to a "ciphertext". Given only the
+ciphertext, but not the key, it should be hard to find the plaintext.
+Given matching pairs of plaintext and ciphertext, it should be hard to
+find the key.
+
+   There are two main classes of ciphers: Block ciphers and stream
+ciphers.
+
+   A block cipher can process data only in fixed size chunks, called
+"blocks". Typical block sizes are 8 or 16 octets. To encrypt arbitrary
+messages, you usually have to pad it to an integral number of blocks,
+split it into blocks, and then process each block. The simplest way is
+to process one block at a time, independent of each other. That mode of
+operation is called "ECB", Electronic Code Book mode.  However, using
+ECB is usually a bad idea. For a start, plaintext blocks that are equal
+are transformed to ciphertext blocks that are equal; that leaks
+information about the plaintext. Usually you should apply the cipher is
+some "feedback mode", "CBC" (Cipher Block Chaining) and "CTR" (Counter
+mode) being two of of the most popular. See *Note Cipher modes::, for
+information on how to apply CBC and CTR with Nettle.
+
+   A stream cipher can be used for messages of arbitrary length. A
+typical stream cipher is a keyed pseudo-random generator. To encrypt a
+plaintext message of N octets, you key the generator, generate N octets
+of pseudo-random data, and XOR it with the plaintext. To decrypt,
+regenerate the same stream using the key, XOR it to the ciphertext, and
+the plaintext is recovered.
+
+   *Caution:* The first rule for this kind of cipher is the same as for
+a One Time Pad: _never_ ever use the same key twice.
+
+   A common misconception is that encryption, by itself, implies
+authentication. Say that you and a friend share a secret key, and you
+receive an encrypted message. You apply the key, and get a plaintext
+message that makes sense to you. Can you then be sure that it really was
+your friend that wrote the message you're reading? The answer is no. For
+example, if you were using a block cipher in ECB mode, an attacker may
+pick up the message on its way, and reorder, delete or repeat some of
+the blocks. Even if the attacker can't decrypt the message, he can
+change it so that you are not reading the same message as your friend
+wrote. If you are using a block cipher in CBC mode rather than ECB, or
+are using a stream cipher, the possibilities for this sort of attack
+are different, but the attacker can still make predictable changes to
+the message.
+
+   It is recommended to _always_ use an authentication mechanism in
+addition to encrypting the messages. Popular choices are Message
+Authentication Codes like HMAC-SHA1 (*note Keyed hash functions::), or
+digital signatures like RSA.
+
+   Some ciphers have so called "weak keys", keys that results in
+undesirable structure after the key setup processing, and should be
+avoided. In Nettle, most key setup functions have no return value, but
+for ciphers with weak keys, the return value indicates whether or not
+the given key is weak. For good keys, key setup returns 1, and for weak
+keys, it returns 0. When possible, avoid algorithms that have weak
+keys. There are several good ciphers that don't have any weak keys.
+
+   To encrypt a message, you first initialize a cipher context for
+encryption or decryption with a particular key. You then use the context
+to process plaintext or ciphertext messages. The initialization is known
+as "key setup". With Nettle, it is recommended to use each context
+struct for only one direction, even if some of the ciphers use a single
+key setup function that can be used for both encryption and decryption.
+
+6.2.1 AES
+---------
+
+AES is a block cipher, specified by NIST as a replacement for the older
+DES standard. The standard is the result of a competition between
+cipher designers. The winning design, also known as RIJNDAEL, was
+constructed by Joan Daemen and Vincent Rijnmen.
+
+   Like all the AES candidates, the winning design uses a block size of
+128 bits, or 16 octets, and variable key-size, 128, 192 and 256 bits
+(16, 24 and 32 octets) being the allowed key sizes. It does not have
+any weak keys. Nettle defines AES in `<nettle/aes.h>'.
+
+ -- Context struct: struct aes_ctx
+
+ -- Constant: AES_BLOCK_SIZE
+     The AES block-size, 16
+
+ -- Constant: AES_MIN_KEY_SIZE
+
+ -- Constant: AES_MAX_KEY_SIZE
+
+ -- Constant: AES_KEY_SIZE
+     Default AES key size, 32
+
+ -- Function: void aes_set_encrypt_key (struct aes_ctx *CTX, unsigned
+          LENGTH, const uint8_t *KEY)
+ -- Function: void aes_set_decrypt_key (struct aes_ctx *CTX, unsigned
+          LENGTH, const uint8_t *KEY)
+     Initialize the cipher, for encryption or decryption, respectively.
+
+ -- Function: void aes_invert_key (struct aes_ctx *DST, const struct
+          aes_ctx *SRC)
+     Given a context SRC initialized for encryption, initializes the
+     context struct DST for decryption, using the same key. If the same
+     context struct is passed for both `src' and `dst', it is converted
+     in place. Calling `aes_set_encrypt_key' and `aes_invert_key' is
+     more efficient than calling `aes_set_encrypt_key' and
+     `aes_set_decrypt_key'. This function is mainly useful for
+     applications which needs to both encrypt and decrypt using the
+     _same_ key.
+
+ -- Function: void aes_encrypt (struct aes_ctx *CTX, unsigned LENGTH,
+          uint8_t *DST, const uint8_t *SRC)
+     Encryption function. LENGTH must be an integral multiple of the
+     block size. If it is more than one block, the data is processed in
+     ECB mode. `src' and `dst' may be equal, but they must not overlap
+     in any other way.
+
+ -- Function: void aes_decrypt (struct aes_ctx *CTX, unsigned LENGTH,
+          uint8_t *DST, const uint8_t *SRC)
+     Analogous to `aes_encrypt'
+
+6.2.2 ARCFOUR
+-------------
+
+ARCFOUR is a stream cipher, also known under the trade marked name RC4,
+and it is one of the fastest ciphers around. A problem is that the key
+setup of ARCFOUR is quite weak, you should never use keys with
+structure, keys that are ordinary passwords, or sequences of keys like
+"secret:1", "secret:2", .... If you have keys that don't look like
+random bit strings, and you want to use ARCFOUR, always hash the key
+before feeding it to ARCFOUR. Furthermore, the initial bytes of the
+generated key stream leak information about the key; for this reason, it
+is recommended to discard the first 512 bytes of the key stream.
+
+     /* A more robust key setup function for ARCFOUR */
+     void
+     arcfour_set_key_hashed(struct arcfour_ctx *ctx,
+                            unsigned length, const uint8_t *key)
+     {
+       struct sha256_ctx hash;
+       uint8_t digest[SHA256_DIGEST_SIZE];
+       uint8_t buffer[0x200];
+
+       sha256_init(&hash);
+       sha256_update(&hash, length, key);
+       sha256_digest(&hash, SHA256_DIGEST_SIZE, digest);
+
+       arcfour_set_key(ctx, SHA256_DIGEST_SIZE, digest);
+       arcfour_crypt(ctx, sizeof(buffer), buffer, buffer);
+     }
+
+   Nettle defines ARCFOUR in `<nettle/arcfour.h>'.
+
+ -- Context struct: struct arcfour_ctx
+
+ -- Constant: ARCFOUR_MIN_KEY_SIZE
+     Minimum key size, 1
+
+ -- Constant: ARCFOUR_MAX_KEY_SIZE
+     Maximum key size, 256
+
+ -- Constant: ARCFOUR_KEY_SIZE
+     Default ARCFOUR key size, 16
+
+ -- Function: void arcfour_set_key (struct arcfour_ctx *CTX, unsigned
+          LENGTH, const uint8_t *KEY)
+     Initialize the cipher. The same function is used for both
+     encryption and decryption.
+
+ -- Function: void arcfour_crypt (struct arcfour_ctx *CTX, unsigned
+          LENGTH, uint8_t *DST, const uint8_t *SRC)
+     Encrypt some data. The same function is used for both encryption
+     and decryption. Unlike the block ciphers, this function modifies
+     the context, so you can split the data into arbitrary chunks and
+     encrypt them one after another. The result is the same as if you
+     had called `arcfour_crypt' only once with all the data.
+
+6.2.3 ARCTWO
+------------
+
+ARCTWO (also known as the trade marked name RC2) is a block cipher
+specified in RFC 2268. Nettle also include a variation of the ARCTWO
+set key operation that lack one step, to be compatible with the reverse
+engineered RC2 cipher description, as described in a Usenet post to
+`sci.crypt' by Peter Gutmann.
+
+   ARCTWO uses a block size of 64 bits, and variable key-size ranging
+from 1 to 128 octets. Besides the key, ARCTWO also has a second
+parameter to key setup, the number of effective key bits, `ekb'.  This
+parameter can be used to artificially reduce the key size. In practice,
+`ekb' is usually set equal to the input key size.  Nettle defines
+ARCTWO in `<nettle/arctwo.h>'.
+
+   We do not recommend the use of ARCTWO; the Nettle implementation is
+provided primarily for interoperability with existing applications and
+standards.
+
+ -- Context struct: struct arctwo_ctx
+
+ -- Constant: ARCTWO_BLOCK_SIZE
+     The ARCTWO block-size, 8
+
+ -- Constant: ARCTWO_MIN_KEY_SIZE
+
+ -- Constant: ARCTWO_MAX_KEY_SIZE
+
+ -- Constant: ARCTWO_KEY_SIZE
+     Default ARCTWO key size, 8
+
+ -- Function: void arctwo_set_key_ekb (struct arctwo_ctx *CTX, unsigned
+          LENGTH, const uint8_t *KEY, unsigned EKB)
+ -- Function: void arctwo_set_key (struct arctwo_ctx *CTX, unsigned
+          LENGTH, const uint8_t *KEY)
+ -- Function: void arctwo_set_key_gutmann (struct arctwo_ctx *CTX,
+          unsigned LENGTH, const uint8_t *KEY)
+     Initialize the cipher. The same function is used for both
+     encryption and decryption. The first function is the most general
+     one, which lets you provide both the variable size key, and the
+     desired effective key size (in bits). The maximum value for EKB is
+     1024, and for convenience, `ekb = 0' has the same effect as `ekb =
+     1024'.
+
+     `arctwo_set_key(ctx, length, key)' is equivalent to
+     `arctwo_set_key_ekb(ctx, length, key, 8*length)', and
+     `arctwo_set_key_gutmann(ctx, length, key)' is equivalent to
+     `arctwo_set_key_ekb(ctx, length, key, 1024)'
+
+ -- Function: void arctwo_encrypt (struct arctwo_ctx *CTX, unsigned
+          LENGTH, uint8_t *DST, const uint8_t *SRC)
+     Encryption function. LENGTH must be an integral multiple of the
+     block size. If it is more than one block, the data is processed in
+     ECB mode. `src' and `dst' may be equal, but they must not overlap
+     in any other way.
+
+ -- Function: void arctwo_decrypt (struct arctwo_ctx *CTX, unsigned
+          LENGTH, uint8_t *DST, const uint8_t *SRC)
+     Analogous to `arctwo_encrypt'
+
+6.2.4 BLOWFISH
+--------------
+
+BLOWFISH is a block cipher designed by Bruce Schneier. It uses a block
+size of 64 bits (8 octets), and a variable key size, up to 448 bits. It
+has some weak keys. Nettle defines BLOWFISH in `<nettle/blowfish.h>'.
+
+ -- Context struct: struct blowfish_ctx
+
+ -- Constant: BLOWFISH_BLOCK_SIZE
+     The BLOWFISH block-size, 8
+
+ -- Constant: BLOWFISH_MIN_KEY_SIZE
+     Minimum BLOWFISH key size, 8
+
+ -- Constant: BLOWFISH_MAX_KEY_SIZE
+     Maximum BLOWFISH key size, 56
+
+ -- Constant: BLOWFISH_KEY_SIZE
+     Default BLOWFISH key size, 16
+
+ -- Function: int blowfish_set_key (struct blowfish_ctx *CTX, unsigned
+          LENGTH, const uint8_t *KEY)
+     Initialize the cipher. The same function is used for both
+     encryption and decryption. Checks for weak keys, returning 1 for
+     good keys and 0 for weak keys. Applications that don't care about
+     weak keys can ignore the return value.
+
+     `blowfish_encrypt' or `blowfish_decrypt' with a weak key will
+     crash with an assert violation.
+
+ -- Function: void blowfish_encrypt (struct blowfish_ctx *CTX, unsigned
+          LENGTH, uint8_t *DST, const uint8_t *SRC)
+     Encryption function. LENGTH must be an integral multiple of the
+     block size. If it is more than one block, the data is processed in
+     ECB mode. `src' and `dst' may be equal, but they must not overlap
+     in any other way.
+
+ -- Function: void blowfish_decrypt (struct blowfish_ctx *CTX, unsigned
+          LENGTH, uint8_t *DST, const uint8_t *SRC)
+     Analogous to `blowfish_encrypt'
+
+6.2.5 Camellia
+--------------
+
+Camellia is a block cipher developed by Mitsubishi and Nippon Telegraph
+and Telephone Corporation, described in `RFC3713', and recommended by
+some Japanese and European authorities as an alternative to AES. The
+algorithm is patented. The implementation in Nettle is derived from the
+implementation released by NTT under the GNU LGPL (v2.1 or later), and
+relies on the implicit patent license of the LGPL. There is also a
+statement of royalty-free licensing for Camellia at
+`http://www.ntt.co.jp/news/news01e/0104/010417.html', but this
+statement has some limitations which seem problematic for free software.
+
+   Camellia uses a the same block size and key sizes as AES: The block
+size is 128 bits (16 octets), and the supported key sizes are 128, 192,
+and 256 bits. Nettle defines Camellia in `<nettle/camellia.h>'.
+
+ -- Context struct: struct camellia_ctx
+
+ -- Constant: CAMELLIA_BLOCK_SIZE
+     The CAMELLIA block-size, 16
+
+ -- Constant: CAMELLIA_MIN_KEY_SIZE
+
+ -- Constant: CAMELLIA_MAX_KEY_SIZE
+
+ -- Constant: CAMELLIA_KEY_SIZE
+     Default CAMELLIA key size, 32
+
+ -- Function: void camellia_set_encrypt_key (struct camellia_ctx *CTX,
+          unsigned LENGTH, const uint8_t *KEY)
+ -- Function: void camellia_set_decrypt_key (struct camellia_ctx *CTX,
+          unsigned LENGTH, const uint8_t *KEY)
+     Initialize the cipher, for encryption or decryption, respectively.
+
+ -- Function: void camellia_invert_key (struct camellia_ctx *DST, const
+          struct camellia_ctx *SRC)
+     Given a context SRC initialized for encryption, initializes the
+     context struct DST for decryption, using the same key. If the same
+     context struct is passed for both `src' and `dst', it is converted
+     in place. Calling `camellia_set_encrypt_key' and
+     `camellia_invert_key' is more efficient than calling
+     `camellia_set_encrypt_key' and `camellia_set_decrypt_key'. This
+     function is mainly useful for applications which needs to both
+     encrypt and decrypt using the _same_ key.
+
+ -- Function: void camellia_crypt (struct camellia_ctx *CTX, unsigned
+          LENGTH, uint8_t *DST, const uint8_t *SRC)
+     The same function is used for both encryption and decryption.
+     LENGTH must be an integral multiple of the block size. If it is
+     more than one block, the data is processed in ECB mode. `src' and
+     `dst' may be equal, but they must not overlap in any other way.
+
+6.2.6 CAST128
+-------------
+
+CAST-128 is a block cipher, specified in `RFC 2144'. It uses a 64 bit
+(8 octets) block size, and a variable key size of up to 128 bits.
+Nettle defines cast128 in `<nettle/cast128.h>'.
+
+ -- Context struct: struct cast128_ctx
+
+ -- Constant: CAST128_BLOCK_SIZE
+     The CAST128 block-size, 8
+
+ -- Constant: CAST128_MIN_KEY_SIZE
+     Minimum CAST128 key size, 5
+
+ -- Constant: CAST128_MAX_KEY_SIZE
+     Maximum CAST128 key size, 16
+
+ -- Constant: CAST128_KEY_SIZE
+     Default CAST128 key size, 16
+
+ -- Function: void cast128_set_key (struct cast128_ctx *CTX, unsigned
+          LENGTH, const uint8_t *KEY)
+     Initialize the cipher. The same function is used for both
+     encryption and decryption.
+
+ -- Function: void cast128_encrypt (struct cast128_ctx *CTX, unsigned
+          LENGTH, uint8_t *DST, const uint8_t *SRC)
+     Encryption function. LENGTH must be an integral multiple of the
+     block size. If it is more than one block, the data is processed in
+     ECB mode. `src' and `dst' may be equal, but they must not overlap
+     in any other way.
+
+ -- Function: void cast128_decrypt (struct cast128_ctx *CTX, unsigned
+          LENGTH, uint8_t *DST, const uint8_t *SRC)
+     Analogous to `cast128_encrypt'
+
+6.2.7 DES
+---------
+
+DES is the old Data Encryption Standard, specified by NIST. It uses a
+block size of 64 bits (8 octets), and a key size of 56 bits. However,
+the key bits are distributed over 8 octets, where the least significant
+bit of each octet may be used for parity. A common way to use DES is to
+generate 8 random octets in some way, then set the least significant bit
+of each octet to get odd parity, and initialize DES with the resulting
+key.
+
+   The key size of DES is so small that keys can be found by brute
+force, using specialized hardware or lots of ordinary work stations in
+parallel. One shouldn't be using plain DES at all today, if one uses
+DES at all one should be using "triple DES", see DES3 below.
+
+   DES also has some weak keys. Nettle defines DES in `<nettle/des.h>'.
+
+ -- Context struct: struct des_ctx
+
+ -- Constant: DES_BLOCK_SIZE
+     The DES block-size, 8
+
+ -- Constant: DES_KEY_SIZE
+     DES key size, 8
+
+ -- Function: int des_set_key (struct des_ctx *CTX, const uint8_t *KEY)
+     Initialize the cipher. The same function is used for both
+     encryption and decryption. Parity bits are ignored. Checks for
+     weak keys, returning 1 for good keys and 0 for weak keys.
+     Applications that don't care about weak keys can ignore the return
+     value.
+
+ -- Function: void des_encrypt (struct des_ctx *CTX, unsigned LENGTH,
+          uint8_t *DST, const uint8_t *SRC)
+     Encryption function. LENGTH must be an integral multiple of the
+     block size. If it is more than one block, the data is processed in
+     ECB mode. `src' and `dst' may be equal, but they must not overlap
+     in any other way.
+
+ -- Function: void des_decrypt (struct des_ctx *CTX, unsigned LENGTH,
+          uint8_t *DST, const uint8_t *SRC)
+     Analogous to `des_encrypt'
+
+ -- Function: int des_check_parity (unsigned LENGTH, const uint8_t
+          *KEY);
+     Checks that the given key has correct, odd, parity. Returns 1 for
+     correct parity, and 0 for bad parity.
+
+ -- Function: void des_fix_parity (unsigned LENGTH, uint8_t *DST, const
+          uint8_t *SRC)
+     Adjusts the parity bits to match DES's requirements. You need this
+     function if you have created a random-looking string by a key
+     agreement protocol, and want to use it as a DES key. DST and SRC
+     may be equal.
+
+6.2.8 DES3
+----------
+
+The inadequate key size of DES has already been mentioned. One way to
+increase the key size is to pipe together several DES boxes with
+independent keys. It turns out that using two DES ciphers is not as
+secure as one might think, even if the key size of the combination is a
+respectable 112 bits.
+
+   The standard way to increase DES's key size is to use three DES
+boxes.  The mode of operation is a little peculiar: the middle DES box
+is wired in the reverse direction. To encrypt a block with DES3, you
+encrypt it using the first 56 bits of the key, then _decrypt_ it using
+the middle 56 bits of the key, and finally encrypt it again using the
+last 56 bits of the key. This is known as "ede" triple-DES, for
+"encrypt-decrypt-encrypt".
+
+   The "ede" construction provides some backward compatibility, as you
+get plain single DES simply by feeding the same key to all three boxes.
+That should help keeping down the gate count, and the price, of hardware
+circuits implementing both plain DES and DES3.
+
+   DES3 has a key size of 168 bits, but just like plain DES, useless
+parity bits are inserted, so that keys are represented as 24 octets
+(192 bits).  As a 112 bit key is large enough to make brute force
+attacks impractical, some applications uses a "two-key" variant of
+triple-DES.  In this mode, the same key bits are used for the first and
+the last DES box in the pipe, while the middle box is keyed
+independently. The two-key variant is believed to be secure, i.e. there
+are no known attacks significantly better than brute force.
+
+   Naturally, it's simple to implement triple-DES on top of Nettle's DES
+functions. Nettle includes an implementation of three-key "ede"
+triple-DES, it is defined in the same place as plain DES,
+`<nettle/des.h>'.
+
+ -- Context struct: struct des3_ctx
+
+ -- Constant: DES3_BLOCK_SIZE
+     The DES3 block-size is the same as DES_BLOCK_SIZE, 8
+
+ -- Constant: DES3_KEY_SIZE
+     DES key size, 24
+
+ -- Function: int des3_set_key (struct des3_ctx *CTX, const uint8_t
+          *KEY)
+     Initialize the cipher. The same function is used for both
+     encryption and decryption. Parity bits are ignored. Checks for
+     weak keys, returning 1 if all three keys are good keys, and 0 if
+     one or more key is weak.  Applications that don't care about weak
+     keys can ignore the return value.
+
+   For random-looking strings, you can use `des_fix_parity' to adjust
+the parity bits before calling `des3_set_key'.
+
+ -- Function: void des3_encrypt (struct des3_ctx *CTX, unsigned LENGTH,
+          uint8_t *DST, const uint8_t *SRC)
+     Encryption function. LENGTH must be an integral multiple of the
+     block size. If it is more than one block, the data is processed in
+     ECB mode. `src' and `dst' may be equal, but they must not overlap
+     in any other way.
+
+ -- Function: void des3_decrypt (struct des3_ctx *CTX, unsigned LENGTH,
+          uint8_t *DST, const uint8_t *SRC)
+     Analogous to `des_encrypt'
+
+6.2.9 SERPENT
+-------------
+
+SERPENT is one of the AES finalists, designed by Ross Anderson, Eli
+Biham and Lars Knudsen. Thus, the interface and properties are similar
+to AES'. One peculiarity is that it is quite pointless to use it with
+anything but the maximum key size, smaller keys are just padded to
+larger ones. Nettle defines SERPENT in `<nettle/serpent.h>'.
+
+ -- Context struct: struct serpent_ctx
+
+ -- Constant: SERPENT_BLOCK_SIZE
+     The SERPENT block-size, 16
+
+ -- Constant: SERPENT_MIN_KEY_SIZE
+     Minimum SERPENT key size, 16
+
+ -- Constant: SERPENT_MAX_KEY_SIZE
+     Maximum SERPENT key size, 32
+
+ -- Constant: SERPENT_KEY_SIZE
+     Default SERPENT key size, 32
+
+ -- Function: void serpent_set_key (struct serpent_ctx *CTX, unsigned
+          LENGTH, const uint8_t *KEY)
+     Initialize the cipher. The same function is used for both
+     encryption and decryption.
+
+ -- Function: void serpent_encrypt (struct serpent_ctx *CTX, unsigned
+          LENGTH, uint8_t *DST, const uint8_t *SRC)
+     Encryption function. LENGTH must be an integral multiple of the
+     block size. If it is more than one block, the data is processed in
+     ECB mode. `src' and `dst' may be equal, but they must not overlap
+     in any other way.
+
+ -- Function: void serpent_decrypt (struct serpent_ctx *CTX, unsigned
+          LENGTH, uint8_t *DST, const uint8_t *SRC)
+     Analogous to `serpent_encrypt'
+
+6.2.10 TWOFISH
+--------------
+
+Another AES finalist, this one designed by Bruce Schneier and others.
+Nettle defines it in `<nettle/twofish.h>'.
+
+ -- Context struct: struct twofish_ctx
+
+ -- Constant: TWOFISH_BLOCK_SIZE
+     The TWOFISH block-size, 16
+
+ -- Constant: TWOFISH_MIN_KEY_SIZE
+     Minimum TWOFISH key size, 16
+
+ -- Constant: TWOFISH_MAX_KEY_SIZE
+     Maximum TWOFISH key size, 32
+
+ -- Constant: TWOFISH_KEY_SIZE
+     Default TWOFISH key size, 32
+
+ -- Function: void twofish_set_key (struct twofish_ctx *CTX, unsigned
+          LENGTH, const uint8_t *KEY)
+     Initialize the cipher. The same function is used for both
+     encryption and decryption.
+
+ -- Function: void twofish_encrypt (struct twofish_ctx *CTX, unsigned
+          LENGTH, uint8_t *DST, const uint8_t *SRC)
+     Encryption function. LENGTH must be an integral multiple of the
+     block size. If it is more than one block, the data is processed in
+     ECB mode. `src' and `dst' may be equal, but they must not overlap
+     in any other way.
+
+ -- Function: void twofish_decrypt (struct twofish_ctx *CTX, unsigned
+          LENGTH, uint8_t *DST, const uint8_t *SRC)
+     Analogous to `twofish_encrypt'
+
+6.2.11 `struct nettle_cipher'
+-----------------------------
+
+Nettle includes a struct including information about some of the more
+regular cipher functions. It should be considered a little experimental,
+but can be useful for applications that need a simple way to handle
+various algorithms. Nettle defines these structs in
+`<nettle/nettle-meta.h>'.
+
+ -- Meta struct: `struct nettle_cipher' name context_size block_size
+          key_size set_encrypt_key set_decrypt_key encrypt decrypt
+     The last four attributes are function pointers, of types
+     `nettle_set_key_func' and `nettle_crypt_func'. The first argument
+     to these functions is a `void *' pointer to a context struct,
+     which is of size `context_size'.
+
+ -- Constant Struct: struct nettle_cipher nettle_aes128
+ -- Constant Struct: struct nettle_cipher nettle_aes192
+ -- Constant Struct: struct nettle_cipher nettle_aes256
+ -- Constant Struct: struct nettle_cipher nettle_arctwo40;
+ -- Constant Struct: struct nettle_cipher nettle_arctwo64;
+ -- Constant Struct: struct nettle_cipher nettle_arctwo128;
+ -- Constant Struct: struct nettle_cipher nettle_arctwo_gutmann128;
+ -- Constant Struct: struct nettle_cipher nettle_arcfour128
+ -- Constant Struct: struct nettle_cipher nettle_camellia128
+ -- Constant Struct: struct nettle_cipher nettle_camellia192
+ -- Constant Struct: struct nettle_cipher nettle_camellia256
+ -- Constant Struct: struct nettle_cipher nettle_cast128
+ -- Constant Struct: struct nettle_cipher nettle_serpent128
+ -- Constant Struct: struct nettle_cipher nettle_serpent192
+ -- Constant Struct: struct nettle_cipher nettle_serpent256
+ -- Constant Struct: struct nettle_cipher nettle_twofish128
+ -- Constant Struct: struct nettle_cipher nettle_twofish192
+ -- Constant Struct: struct nettle_cipher nettle_twofish256
+     Nettle includes such structs for all the _regular_ ciphers, i.e.
+     ones without weak keys or other oddities.
+
+     Nettle also exports a list of all these ciphers without weak keys
+     or other oddities.  This list can be used to dynamically enumerate
+     or search the supported algorithms:
+
+ -- Constant Struct: struct nettle_cipher ** nettle_ciphers
+
+\1f
+File: nettle.info,  Node: Cipher modes,  Next: Keyed hash functions,  Prev: Cipher functions,  Up: Reference
+
+6.3 Cipher modes
+================
+
+Cipher modes of operation specifies the procedure to use when encrypting
+a message that is larger than the cipher's block size. As explained in
+*Note Cipher functions::, splitting the message into blocks and
+processing them independently with the block cipher (Electronic Code
+Book mode, ECB) leaks information. Besides ECB, Nettle provides three
+other modes of operation: Cipher Block Chaining (CBC), Counter mode
+(CTR), and Galois/Counter mode (gcm). CBC is widely used, but there are
+a few subtle issues of information leakage, see, e.g., SSH CBC
+vulnerability (http://www.kb.cert.org/vuls/id/958563). CTR and GCM were
+standardized more recently, and are believed to be more secure.  GCM
+includes message authentication; for the other modes, one should always
+use a MAC (*note Keyed hash functions::) or signature to authenticate
+the message.
+
+* Menu:
+
+* CBC::
+* CTR::
+* GCM::
+
+\1f
+File: nettle.info,  Node: CBC,  Next: CTR,  Prev: Cipher modes,  Up: Cipher modes
+
+6.3.1 Cipher Block Chaining
+---------------------------
+
+When using CBC mode, plaintext blocks are not encrypted independently
+of each other, like in Electronic Cook Book mode. Instead, when
+encrypting a block in CBC mode, the previous ciphertext block is XORed
+with the plaintext before it is fed to the block cipher.  When
+encrypting the first block, a random block called an "IV", or
+Initialization Vector, is used as the "previous ciphertext block". The
+IV should be chosen randomly, but it need not be kept secret, and can
+even be transmitted in the clear together with the encrypted data.
+
+   In symbols, if `E_k' is the encryption function of a block cipher,
+and `IV' is the initialization vector, then `n' plaintext blocks
+`M_1',... `M_n' are transformed into `n' ciphertext blocks `C_1',...
+`C_n' as follows:
+
+     C_1 = E_k(IV  XOR M_1)
+     C_2 = E_k(C_1 XOR M_2)
+
+     ...
+
+     C_n = E_k(C_(n-1) XOR M_n)
+
+   Nettle's includes two functions for applying a block cipher in Cipher
+Block Chaining (CBC) mode, one for encryption and one for decryption.
+These functions uses `void *' to pass cipher contexts around.
+
+ -- Function: void cbc_encrypt (void *CTX, nettle_crypt_func F,
+          unsigned BLOCK_SIZE, uint8_t *IV, unsigned LENGTH, uint8_t
+          *DST, const uint8_t *SRC)
+ -- Function: void cbc_decrypt (void *CTX, void (*F)(), unsigned
+          BLOCK_SIZE, uint8_t *IV, unsigned LENGTH, uint8_t *DST, const
+          uint8_t *SRC)
+     Applies the encryption or decryption function F in CBC mode. The
+     final ciphertext block processed is copied into IV before
+     returning, so that large message be processed be a sequence of
+     calls to `cbc_encrypt'. The function F is of type
+
+     `void f (void *CTX, unsigned LENGTH, uint8_t DST, const uint8_t
+     *SRC)',
+
+     and the `cbc_encrypt' and `cbc_decrypt' functions pass their
+     argument CTX on to F.
+
+   There are also some macros to help use these functions correctly.
+
+ -- Macro: CBC_CTX (CONTEXT_TYPE, BLOCK_SIZE)
+     Expands to
+          {
+             context_type ctx;
+             uint8_t iv[block_size];
+          }
+
+   It can be used to define a CBC context struct, either directly,
+
+     struct CBC_CTX(struct aes_ctx, AES_BLOCK_SIZE) ctx;
+
+   or to give it a struct tag,
+
+     struct aes_cbc_ctx CBC_CTX (struct aes_ctx, AES_BLOCK_SIZE);
+
+ -- Macro: CBC_SET_IV (CTX, IV)
+     First argument is a pointer to a context struct as defined by
+     `CBC_CTX', and the second is a pointer to an Initialization Vector
+     (IV) that is copied into that context.
+
+ -- Macro: CBC_ENCRYPT (CTX, F, LENGTH, DST, SRC)
+ -- Macro: CBC_DECRYPT (CTX, F, LENGTH, DST, SRC)
+     A simpler way to invoke `cbc_encrypt' and `cbc_decrypt'. The first
+     argument is a pointer to a context struct as defined by `CBC_CTX',
+     and the second argument is an encryption or decryption function
+     following Nettle's conventions. The last three arguments define
+     the source and destination area for the operation.
+
+   These macros use some tricks to make the compiler display a warning
+if the types of F and CTX don't match, e.g. if you try to use an
+`struct aes_ctx' context with the `des_encrypt' function.
+
+\1f
+File: nettle.info,  Node: CTR,  Next: GCM,  Prev: CBC,  Up: Cipher modes
+
+6.3.2 Counter mode
+------------------
+
+Counter mode (CTR) uses the block cipher as a keyed pseudo-random
+generator. The output of the generator is XORed with the data to be
+encrypted. It can be understood as a way to transform a block cipher to
+a stream cipher.
+
+   The message is divided into `n' blocks `M_1',...  `M_n', where `M_n'
+is of size `m' which may be smaller than the block size. Except for the
+last block, all the message blocks must be of size equal to the
+cipher's block size.
+
+   If `E_k' is the encryption function of a block cipher, `IC' is the
+initial counter, then the `n' plaintext blocks are transformed into `n'
+ciphertext blocks `C_1',...  `C_n' as follows:
+
+     C_1 = E_k(IC) XOR M_1
+     C_2 = E_k(IC + 1) XOR M_2
+
+     ...
+
+     C_(n-1) = E_k(IC + n - 2) XOR M_(n-1)
+     C_n = E_k(IC + n - 1) [1..m] XOR M_n
+
+   The IC is the initial value for the counter, it plays a similar role
+as the IV for CBC. When adding, `IC + x', IC is interpreted as an
+integer, in network byte order. For the last block, `E_k(IC + n - 1)
+[1..m]' means that the cipher output is truncated to `m' bytes.
+
+ -- Function: void ctr_crypt (void *CTX, nettle_crypt_func F, unsigned
+          BLOCK_SIZE, uint8_t *CTR, unsigned LENGTH, uint8_t *DST,
+          const uint8_t *SRC)
+     Applies the encryption function F in CTR mode. Note that for CTR
+     mode, encryption and decryption is the same operation, and hence F
+     should always be the encryption function for the underlying block
+     cipher.
+
+     When a message is encrypted using a sequence of calls to
+     `ctr_crypt', all but the last call _must_ use a length that is a
+     multiple of the block size.
+
+   Like for CBC, there are also a couple of helper macros.
+
+ -- Macro: CTR_CTX (CONTEXT_TYPE, BLOCK_SIZE)
+     Expands to
+          {
+             context_type ctx;
+             uint8_t ctr[block_size];
+          }
+
+ -- Macro: CTR_SET_COUNTER (CTX, IV)
+     First argument is a pointer to a context struct as defined by
+     `CTR_CTX', and the second is a pointer to an initial counter that
+     is copied into that context.
+
+ -- Macro: CTR_CRYPT (CTX, F, LENGTH, DST, SRC)
+     A simpler way to invoke `ctr_crypt'. The first argument is a
+     pointer to a context struct as defined by `CTR_CTX', and the second
+     argument is an encryption function following Nettle's conventions.
+     The last three arguments define the source and destination area
+     for the operation.
+
+\1f
+File: nettle.info,  Node: GCM,  Prev: CTR,  Up: Cipher modes
+
+6.3.3 Galois counter mode
+-------------------------
+
+Galois counter mode is the combination of counter mode with message
+authentication based on universal hashing. The main objective of the
+design is to provide high performance for hardware implementations,
+where other popular MAC algorithms (*note Keyed hash functions::
+becomes a bottleneck for high-speed hardware implementations.  It was
+proposed by David A. McGrew and John Viega in 2005, and recommended by
+NIST in 2007, NIST Special Publication 800-38D
+(http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf). It
+is constructed on top of a block cipher which must have a block size of
+128 bits.
+
+   GCM is applied to messages of arbitrary length. The inputs are:
+
+   * A key, which can be used for many messages.
+
+   * An initialization vector (IV) which _must_ be unique for each
+     message.
+
+   * Additional authenticated data, which is to be included in the
+     message authentication, but not encrypted. May be empty.
+
+   * The plaintext. Maybe empty.
+
+   The outputs are a ciphertext, of the same length as the plaintext,
+and a message digest of length 128 bits. Nettle's support for GCM
+consists of a low-level general interface, some convenience macros, and
+specific functions for GCM using AES as the underlying cipher. These
+interfaces are defined in `<nettle/gcm.h>'
+
+6.3.3.1 General GCM interface
+.............................
+
+ -- Context struct: struct gcm_key
+     Message independent hash subkey, and related tables.
+
+ -- Context struct: struct gcm_ctx
+     Holds state corresponding to a particular message.
+
+ -- Constant: GCM_BLOCK_SIZE
+     GCM's block size, 16.
+
+ -- Constant: GCM_IV_SIZE
+     Recommended size of the IV, 12. Other sizes are allowed.
+
+ -- Function: void gcm_set_key (struct gcm_key *KEY, void *CIPHER,
+          nettle_crypt_func *F)
+     Initializes KEY. CIPHER gives a context struct for the underlying
+     cipher, which must have been previously initialized for
+     encryption, and F is the encryption function.
+
+ -- Function: void gcm_set_iv (struct gcm_ctx *CTX, const struct
+          gcm_key *KEY, unsigned LENGTH, const uint8_t *IV)
+     Initializes CTX using the given IV. The KEY argument is actually
+     needed only if LENGTH differs from `GCM_IV_SIZE'.
+
+ -- Function: void gcm_update (struct gcm_ctx *CTX, const struct
+          gcm_key *KEY, unsigned LENGTH, const uint8_t *DATA)
+     Provides associated data to be authenticated. If used, must be
+     called before `gcm_encrypt' or `gcm_decrypt'. All but the last call
+     for each message _must_ use a length that is a multiple of the
+     block size.
+
+ -- Function: void gcm_encrypt (struct gcm_ctx *CTX, const struct
+          gcm_key *KEY void *CIPHER, nettle_crypt_func *F, unsigned
+          LENGTH, uint8_t *DST, const uint8_t *SRC)
+ -- Function: void gcm_decrypt (struct gcm_ctx *CTX, const struct
+          gcm_key *KEY, void *CIPHER, nettle_crypt_func *F, unsigned
+          LENGTH, uint8_t *DST, const uint8_t *SRC)
+     Encrypts or decrypts the data of a message. CIPHER is the context
+     struct for the underlying cipher and F is the encryption function.
+     All but the last call for each message _must_ use a length that is
+     a multiple of the block size.
+
+ -- Function: void gcm_digest (struct gcm_ctx *CTX, const struct
+          gcm_key *KEY, void *CIPHER, nettle_crypt_func *F, unsigned
+          LENGTH, uint8_t *DIGEST)
+     Extracts the message digest (also known "authentication tag").
+     This is the final operation when processing a message. LENGTH is
+     usually equal to `GCM_BLOCK_SIZE', but if you provide a smaller
+     value, only the first LENGTH octets of the digest are written.
+
+   To encrypt a message using GCM, first initialize a context for the
+underlying block cipher with a key to use for encryption. Then call the
+above functions in the following order: `gcm_set_key', `gcm_set_iv',
+`gcm_update', `gcm_encrypt', `gcm_digest'. The decryption procedure is
+analogous, just calling `gcm_decrypt' instead of `gcm_encrypt' (note
+that GCM decryption still uses the encryption function of the
+underlying block cipher). To process a new message, using the same key,
+call `gcm_set_iv' with a new iv.
+
+6.3.3.2 GCM helper macros
+.........................
+
+The following macros are defined.
+
+ -- Macro: GCM_CTX (CONTEXT_TYPE)
+     This defines an all-in-one context struct, including the context
+     of the underlying cipher, the hash subkey, and the per-message
+     state. It expands to
+          {
+             context_type cipher;
+             struct gcm_key key;
+             struct gcm_ctx gcm;
+          }
+
+   Example use:
+     struct gcm_aes_ctx GCM_CTX(struct aes_ctx);
+
+   The following macros operate on context structs of this form.
+
+ -- Macro: GCM_SET_KEY (CTX, SET_KEY, ENCRYPT, LENGTH, DATA)
+     First argument, CTX, is a context struct as defined by `GCM_CTX'.
+     SET_KEY and ENCRYPT are functions for setting the encryption key
+     and for encrypting data using the underlying cipher. LENGTH and
+     DATA give the key.
+
+ -- Macro: GCM_SET_IV (CTX, LENGTH, DATA)
+     First argument is a context struct as defined by `GCM_CTX'. LENGTH
+     and DATA give the initialization vector (IV).
+
+ -- Macro: GCM_UPDATE (CTX, LENGTH, DATA)
+     Simpler way to call `gcm_update'. First argument is a context
+     struct as defined by `GCM_CTX'
+
+ -- Macro: GCM_ENCRYPT (CTX, ENCRYPT, LENGTH, DST, SRC)
+ -- Macro: GCM_DECRYPT (CTX, ENCRYPT, LENGTH, DST, SRC)
+ -- Macro: GCM_DIGEST (CTX, ENCRYPT, LENGTH, DIGEST)
+     Simpler way to call `gcm_encrypt', `gcm_decrypt' or `gcm_digest'.
+     First argument is a context struct as defined by `GCM_CTX'. Second
+     argument, ENCRYPT, is a pointer to the encryption function of the
+     underlying cipher.
+
+6.3.3.3 GCM-AES interface
+.........................
+
+The following functions implement the common case of GCM using AES as
+the underlying cipher.
+
+ -- Context struct: struct gcm_aes_ctx
+     The context struct, defined using `GCM_CTX'.
+
+ -- Function: void gcm_aes_set_key (struct gcm_aes_ctx *CTX, unsigned
+          LENGTH, const uint8_t *KEY)
+     Initializes CTX using the given key. All valid AES key sizes can
+     be used.
+
+ -- Function: void gcm_aes_set_iv (struct gcm_aes_ctx *CTX, unsigned
+          LENGTH, const uint8_t *IV)
+     Initializes the per-message state, using the given IV.
+
+ -- Function: void gcm_aes_update (struct gcm_aes_ctx *CTX, unsigned
+          LENGTH, const uint8_t *DATA)
+     Provides associated data to be authenticated. If used, must be
+     called before `gcm_aes_encrypt' or `gcm_aes_decrypt'. All but the
+     last call for each message _must_ use a length that is a multiple
+     of the block size.
+
+ -- Function: void gcm_aes_encrypt (struct gcm_aes_ctx *CTX, unsigned
+          LENGTH, uint8_t *DST, const uint8_t *SRC)
+ -- Function: void gcm_aes_decrypt (struct gcm_aes_ctx *CTX, unsigned
+          LENGTH, uint8_t *DST, const uint8_t *SRC)
+     Encrypts or decrypts the data of a message. All but the last call
+     for each message _must_ use a length that is a multiple of the
+     block size.
+
+
+ -- Function: void gcm_aes_digest (struct gcm_aes_ctx *CTX, unsigned
+          LENGTH, uint8_t *DIGEST)
+     Extracts the message digest (also known "authentication tag").
+     This is the final operation when processing a message. LENGTH is
+     usually equal to `GCM_BLOCK_SIZE', but if you provide a smaller
+     value, only the first LENGTH octets of the digest are written.
+
+\1f
+File: nettle.info,  Node: Keyed hash functions,  Next: Public-key algorithms,  Prev: Cipher modes,  Up: Reference
+
+6.4 Keyed Hash Functions
+========================
+
+A "keyed hash function", or "Message Authentication Code" (MAC) is a
+function that takes a key and a message, and produces fixed size MAC.
+It should be hard to compute a message and a matching MAC without
+knowledge of the key. It should also be hard to compute the key given
+only messages and corresponding MACs.
+
+   Keyed hash functions are useful primarily for message authentication,
+when Alice and Bob shares a secret: The sender, Alice, computes the MAC
+and attaches it to the message. The receiver, Bob, also computes the
+MAC of the message, using the same key, and compares that to Alice's
+value. If they match, Bob can be assured that the message has not been
+modified on its way from Alice.
+
+   However, unlike digital signatures, this assurance is not
+transferable.  Bob can't show the message and the MAC to a third party
+and prove that Alice sent that message. Not even if he gives away the
+key to the third party. The reason is that the _same_ key is used on
+both sides, and anyone knowing the key can create a correct MAC for any
+message. If Bob believes that only he and Alice knows the key, and he
+knows that he didn't attach a MAC to a particular message, he knows it
+must be Alice who did it. However, the third party can't distinguish
+between a MAC created by Alice and one created by Bob.
+
+   Keyed hash functions are typically a lot faster than digital
+signatures as well.
+
+6.4.1 HMAC
+----------
+
+One can build keyed hash functions from ordinary hash functions. Older
+constructions simply concatenate secret key and message and hashes
+that, but such constructions have weaknesses. A better construction is
+HMAC, described in `RFC 2104'.
+
+   For an underlying hash function `H', with digest size `l' and
+internal block size `b', HMAC-H is constructed as follows: From a given
+key `k', two distinct subkeys `k_i' and `k_o' are constructed, both of
+length `b'. The HMAC-H of a message `m' is then computed as `H(k_o |
+H(k_i | m))', where `|' denotes string concatenation.
+
+   HMAC keys can be of any length, but it is recommended to use keys of
+length `l', the digest size of the underlying hash function `H'. Keys
+that are longer than `b' are shortened to length `l' by hashing with
+`H', so arbitrarily long keys aren't very useful.
+
+   Nettle's HMAC functions are defined in `<nettle/hmac.h>'.  There are
+abstract functions that use a pointer to a `struct nettle_hash' to
+represent the underlying hash function and `void *' pointers that point
+to three different context structs for that hash function. There are
+also concrete functions for HMAC-MD5, HMAC-RIPEMD160 HMAC-SHA1,
+HMAC-SHA256, and HMAC-SHA512. First, the abstract functions:
+
+ -- Function: void hmac_set_key (void *OUTER, void *INNER, void *STATE,
+          const struct nettle_hash *H, unsigned LENGTH, const uint8_t
+          *KEY)
+     Initializes the three context structs from the key. The OUTER and
+     INNER contexts corresponds to the subkeys `k_o' and `k_i'. STATE
+     is used for hashing the message, and is initialized as a copy of
+     the INNER context.
+
+ -- Function: void hmac_update (void *STATE, const struct nettle_hash
+          *H, unsigned LENGTH, const uint8_t *DATA)
+     This function is called zero or more times to process the message.
+     Actually, `hmac_update(state, H, length, data)' is equivalent to
+     `H->update(state, length, data)', so if you wish you can use the
+     ordinary update function of the underlying hash function instead.
+
+ -- Function: void hmac_digest (const void *OUTER, const void *INNER,
+          void *STATE, const struct nettle_hash *H, unsigned LENGTH,
+          uint8_t *DIGEST)
+     Extracts the MAC of the message, writing it to DIGEST.  OUTER and
+     INNER are not modified. LENGTH is usually equal to
+     `H->digest_size', but if you provide a smaller value, only the
+     first LENGTH octets of the MAC are written.
+
+     This function also resets the STATE context so that you can start
+     over processing a new message (with the same key).
+
+   Like for CBC, there are some macros to help use these functions
+correctly.
+
+ -- Macro: HMAC_CTX (TYPE)
+     Expands to
+          {
+             type outer;
+             type inner;
+             type state;
+          }
+
+   It can be used to define a HMAC context struct, either directly,
+
+     struct HMAC_CTX(struct md5_ctx) ctx;
+
+   or to give it a struct tag,
+
+     struct hmac_md5_ctx HMAC_CTX (struct md5_ctx);
+
+ -- Macro: HMAC_SET_KEY (CTX, H, LENGTH, KEY)
+     CTX is a pointer to a context struct as defined by `HMAC_CTX', H
+     is a pointer to a `const struct nettle_hash' describing the
+     underlying hash function (so it must match the type of the
+     components of CTX). The last two arguments specify the secret key.
+
+ -- Macro: HMAC_DIGEST (CTX, H, LENGTH, DIGEST)
+     CTX is a pointer to a context struct as defined by `HMAC_CTX', H
+     is a pointer to a `const struct nettle_hash' describing the
+     underlying hash function. The last two arguments specify where the
+     digest is written.
+
+   Note that there is no `HMAC_UPDATE' macro; simply call `hmac_update'
+function directly, or the update function of the underlying hash
+function.
+
+6.4.2 Concrete HMAC functions
+-----------------------------
+
+Now we come to the specialized HMAC functions, which are easier to use
+than the general HMAC functions.
+
+6.4.2.1 HMAC-MD5
+................
+
+ -- Context struct: struct hmac_md5_ctx
+
+ -- Function: void hmac_md5_set_key (struct hmac_md5_ctx *CTX, unsigned
+          KEY_LENGTH, const uint8_t *KEY)
+     Initializes the context with the key.
+
+ -- Function: void hmac_md5_update (struct hmac_md5_ctx *CTX, unsigned
+          LENGTH, const uint8_t *DATA)
+     Process some more data.
+
+ -- Function: void hmac_md5_digest (struct hmac_md5_ctx *CTX, unsigned
+          LENGTH, uint8_t *DIGEST)
+     Extracts the MAC, writing it to DIGEST. LENGTH may be smaller than
+     `MD5_DIGEST_SIZE', in which case only the first LENGTH octets of
+     the MAC are written.
+
+     This function also resets the context for processing new messages,
+     with the same key.
+
+6.4.2.2 HMAC-RIPEMD160
+......................
+
+ -- Context struct: struct hmac_ripemd160_ctx
+
+ -- Function: void hmac_ripemd160_set_key (struct hmac_ripemd160_ctx
+          *CTX, unsigned KEY_LENGTH, const uint8_t *KEY)
+     Initializes the context with the key.
+
+ -- Function: void hmac_ripemd160_update (struct hmac_ripemd160_ctx
+          *CTX, unsigned LENGTH, const uint8_t *DATA)
+     Process some more data.
+
+ -- Function: void hmac_ripemd160_digest (struct hmac_ripemd160_ctx
+          *CTX, unsigned LENGTH, uint8_t *DIGEST)
+     Extracts the MAC, writing it to DIGEST. LENGTH may be smaller than
+     `RIPEMD160_DIGEST_SIZE', in which case only the first LENGTH
+     octets of the MAC are written.
+
+     This function also resets the context for processing new messages,
+     with the same key.
+
+6.4.2.3 HMAC-SHA1
+.................
+
+ -- Context struct: struct hmac_sha1_ctx
+
+ -- Function: void hmac_sha1_set_key (struct hmac_sha1_ctx *CTX,
+          unsigned KEY_LENGTH, const uint8_t *KEY)
+     Initializes the context with the key.
+
+ -- Function: void hmac_sha1_update (struct hmac_sha1_ctx *CTX,
+          unsigned LENGTH, const uint8_t *DATA)
+     Process some more data.
+
+ -- Function: void hmac_sha1_digest (struct hmac_sha1_ctx *CTX,
+          unsigned LENGTH, uint8_t *DIGEST)
+     Extracts the MAC, writing it to DIGEST. LENGTH may be smaller than
+     `SHA1_DIGEST_SIZE', in which case only the first LENGTH octets of
+     the MAC are written.
+
+     This function also resets the context for processing new messages,
+     with the same key.
+
+6.4.2.4 HMAC-SHA256
+...................
+
+ -- Context struct: struct hmac_sha256_ctx
+
+ -- Function: void hmac_sha256_set_key (struct hmac_sha256_ctx *CTX,
+          unsigned KEY_LENGTH, const uint8_t *KEY)
+     Initializes the context with the key.
+
+ -- Function: void hmac_sha256_update (struct hmac_sha256_ctx *CTX,
+          unsigned LENGTH, const uint8_t *DATA)
+     Process some more data.
+
+ -- Function: void hmac_sha256_digest (struct hmac_sha256_ctx *CTX,
+          unsigned LENGTH, uint8_t *DIGEST)
+     Extracts the MAC, writing it to DIGEST. LENGTH may be smaller than
+     `SHA256_DIGEST_SIZE', in which case only the first LENGTH octets
+     of the MAC are written.
+
+     This function also resets the context for processing new messages,
+     with the same key.
+
+6.4.2.5 HMAC-SHA512
+...................
+
+ -- Context struct: struct hmac_sha512_ctx
+
+ -- Function: void hmac_sha512_set_key (struct hmac_sha512_ctx *CTX,
+          unsigned KEY_LENGTH, const uint8_t *KEY)
+     Initializes the context with the key.
+
+ -- Function: void hmac_sha512_update (struct hmac_sha512_ctx *CTX,
+          unsigned LENGTH, const uint8_t *DATA)
+     Process some more data.
+
+ -- Function: void hmac_sha512_digest (struct hmac_sha512_ctx *CTX,
+          unsigned LENGTH, uint8_t *DIGEST)
+     Extracts the MAC, writing it to DIGEST. LENGTH may be smaller than
+     `SHA512_DIGEST_SIZE', in which case only the first LENGTH octets
+     of the MAC are written.
+
+     This function also resets the context for processing new messages,
+     with the same key.
+
+\1f
+File: nettle.info,  Node: Public-key algorithms,  Next: Randomness,  Prev: Keyed hash functions,  Up: Reference
+
+6.5 Public-key algorithms
+=========================
+
+Nettle uses GMP, the GNU bignum library, for all calculations with
+large numbers. In order to use the public-key features of Nettle, you
+must install GMP, at least version 3.0, before compiling Nettle, and
+you need to link your programs with `-lhogweed -lnettle -lgmp'.
+
+   The concept of "Public-key" encryption and digital signatures was
+discovered by Whitfield Diffie and Martin E. Hellman and described in a
+paper 1976. In traditional, "symmetric", cryptography, sender and
+receiver share the same keys, and these keys must be distributed in a
+secure way. And if there are many users or entities that need to
+communicate, each _pair_ needs a shared secret key known by nobody else.
+
+   Public-key cryptography uses trapdoor one-way functions. A "one-way
+function" is a function `F' such that it is easy to compute the value
+`F(x)' for any `x', but given a value `y', it is hard to compute a
+corresponding `x' such that `y = F(x)'. Two examples are cryptographic
+hash functions, and exponentiation in certain groups.
+
+   A "trapdoor one-way function" is a function `F' that is one-way,
+unless one knows some secret information about `F'. If one knows the
+secret, it is easy to compute both `F' and it's inverse.  If this
+sounds strange, look at the RSA example below.
+
+   Two important uses for one-way functions with trapdoors are
+public-key encryption, and digital signatures. The public-key
+encryption functions in Nettle are not yet documented; the rest of this
+chapter is about digital signatures.
+
+   To use a digital signature algorithm, one must first create a
+"key-pair": A public key and a corresponding private key. The private
+key is used to sign messages, while the public key is used for verifying
+that that signatures and messages match. Some care must be taken when
+distributing the public key; it need not be kept secret, but if a bad
+guy is able to replace it (in transit, or in some user's list of known
+public keys), bad things may happen.
+
+   There are two operations one can do with the keys. The signature
+operation takes a message and a private key, and creates a signature for
+the message. A signature is some string of bits, usually at most a few
+thousand bits or a few hundred octets. Unlike paper-and-ink signatures,
+the digital signature depends on the message, so one can't cut it out of
+context and glue it to a different message.
+
+   The verification operation takes a public key, a message, and a
+string that is claimed to be a signature on the message, and returns
+true or false. If it returns true, that means that the three input
+values matched, and the verifier can be sure that someone went through
+with the signature operation on that very message, and that the
+"someone" also knows the private key corresponding to the public key.
+
+   The desired properties of a digital signature algorithm are as
+follows: Given the public key and pairs of messages and valid
+signatures on them, it should be hard to compute the private key, and
+it should also be hard to create a new message and signature that is
+accepted by the verification operation.
+
+   Besides signing meaningful messages, digital signatures can be used
+for authorization. A server can be configured with a public key, such
+that any client that connects to the service is given a random nonce
+message.  If the server gets a reply with a correct signature matching
+the nonce message and the configured public key, the client is granted
+access. So the configuration of the server can be understood as "grant
+access to whoever knows the private key corresponding to this
+particular public key, and to no others".
+
+* Menu:
+
+* RSA::                         The RSA public key algorithm.
+* DSA::                         The DSA digital signature algorithm.
+
+\1f
+File: nettle.info,  Node: RSA,  Next: DSA,  Prev: Public-key algorithms,  Up: Public-key algorithms
+
+6.5.1 RSA
+---------
+
+The RSA algorithm was the first practical digital signature algorithm
+that was constructed. It was described 1978 in a paper by Ronald
+Rivest, Adi Shamir and L.M. Adleman, and the technique was also
+patented in the USA in 1983. The patent expired on September 20, 2000,
+and since that day, RSA can be used freely, even in the USA.
+
+   It's remarkably simple to describe the trapdoor function behind RSA.
+The "one-way"-function used is
+
+     F(x) = x^e mod n
+
+   I.e. raise x to the `e':th power, while discarding all multiples of
+`n'. The pair of numbers `n' and `e' is the public key.  `e' can be
+quite small, even `e = 3' has been used, although slightly larger
+numbers are recommended. `n' should be about 1000 bits or larger.
+
+   If `n' is large enough, and properly chosen, the inverse of F, the
+computation of `e':th roots modulo `n', is very difficult.  But,
+where's the trapdoor?
+
+   Let's first look at how RSA key-pairs are generated. First `n' is
+chosen as the product of two large prime numbers `p' and `q' of roughly
+the same size (so if `n' is 1000 bits, `p' and `q' are about 500 bits
+each). One also computes the number `phi = (p-1)(q-1)', in mathematical
+speak, `phi' is the order of the multiplicative group of integers
+modulo n.
+
+   Next, `e' is chosen. It must have no factors in common with `phi' (in
+particular, it must be odd), but can otherwise be chosen more or less
+randomly. `e = 65537' is a popular choice, because it makes raising to
+the `e''th power particularly efficient, and being prime, it usually
+has no factors common with `phi'.
+
+   Finally, a number `d', `d < n' is computed such that `e d mod phi =
+1'. It can be shown that such a number exists (this is why `e' and
+`phi' must have no common factors), and that for all x,
+
+     (x^e)^d mod n = x^(ed) mod n = (x^d)^e mod n = x
+
+   Using Euclid's algorithm, `d' can be computed quite easily from
+`phi' and `e'. But it is still hard to get `d' without knowing `phi',
+which depends on the factorization of `n'.
+
+   So `d' is the trapdoor, if we know `d' and `y = F(x)', we can
+recover x as `y^d mod n'. `d' is also the private half of the RSA
+key-pair.
+
+   The most common signature operation for RSA is defined in `PKCS#1',
+a specification by RSA Laboratories. The message to be signed is first
+hashed using a cryptographic hash function, e.g.  MD5 or SHA1. Next,
+some padding, the ASN.1 "Algorithm Identifier" for the hash function,
+and the message digest itself, are concatenated and converted to a
+number `x'. The signature is computed from `x' and the private key as
+`s = x^d mod n'(1) (*note RSA-Footnote-1::). The signature, `s' is a
+number of about the same size of `n', and it usually encoded as a
+sequence of octets, most significant octet first.
+
+   The verification operation is straight-forward, `x' is computed from
+the message in the same way as above. Then `s^e mod n' is computed, the
+operation returns true if and only if the result equals `x'.
+
+6.5.2 Nettle's RSA support
+--------------------------
+
+Nettle represents RSA keys using two structures that contain large
+numbers (of type `mpz_t').
+
+ -- Context struct: rsa_public_key size n e
+     `size' is the size, in octets, of the modulo, and is used
+     internally.  `n' and `e' is the public key.
+
+ -- Context struct: rsa_private_key size d p q a b c
+     `size' is the size, in octets, of the modulo, and is used
+     internally.  `d' is the secret exponent, but it is not actually
+     used when signing. Instead, the factors `p' and `q', and the
+     parameters `a', `b' and `c' are used. They are computed from `p',
+     `q' and `e' such that `a e mod (p - 1) = 1, b e mod (q - 1) = 1, c
+     q mod p = 1'.
+
+   Before use, these structs must be initialized by calling one of
+
+ -- Function: void rsa_public_key_init (struct rsa_public_key *PUB)
+ -- Function: void rsa_private_key_init (struct rsa_private_key *KEY)
+     Calls `mpz_init' on all numbers in the key struct.
+
+   and when finished with them, the space for the numbers must be
+deallocated by calling one of
+
+ -- Function: void rsa_public_key_clear (struct rsa_public_key *PUB)
+ -- Function: void rsa_private_key_clear (struct rsa_private_key *KEY)
+     Calls `mpz_clear' on all numbers in the key struct.
+
+   In general, Nettle's RSA functions deviates from Nettle's "no memory
+allocation"-policy. Space for all the numbers, both in the key structs
+above, and temporaries, are allocated dynamically. For information on
+how to customize allocation, see *Note GMP Allocation: (gmp)Custom
+Allocation.
+
+   When you have assigned values to the attributes of a key, you must
+call
+
+ -- Function: int rsa_public_key_prepare (struct rsa_public_key *PUB)
+ -- Function: int rsa_private_key_prepare (struct rsa_private_key *KEY)
+     Computes the octet size of the key (stored in the `size' attribute,
+     and may also do other basic sanity checks. Returns one if
+     successful, or zero if the key can't be used, for instance if the
+     modulo is smaller than the minimum size needed for RSA operations
+     specified by PKCS#1.
+
+   Before signing or verifying a message, you first hash it with the
+appropriate hash function. You pass the hash function's context struct
+to the RSA signature function, and it will extract the message digest
+and do the rest of the work. There are also alternative functions that
+take the hash digest as argument.
+
+   There is currently no support for using SHA224 or SHA384 with RSA
+signatures, since there's no gain in either computation time nor
+message size compared to using SHA256 and SHA512, respectively.
+
+   Creation and verification of signatures is done with the following
+functions:
+
+ -- Function: int rsa_md5_sign (const struct rsa_private_key *KEY,
+          struct md5_ctx *HASH, mpz_t SIGNATURE)
+ -- Function: int rsa_sha1_sign (const struct rsa_private_key *KEY,
+          struct sha1_ctx *HASH, mpz_t SIGNATURE)
+ -- Function: int rsa_sha256_sign (const struct rsa_private_key *KEY,
+          struct sha256_ctx *HASH, mpz_t SIGNATURE)
+ -- Function: int rsa_sha512_sign (const struct rsa_private_key *KEY,
+          struct sha512_ctx *HASH, mpz_t SIGNATURE)
+     The signature is stored in SIGNATURE (which must have been
+     `mpz_init''ed earlier). The hash context is reset so that it can be
+     used for new messages. Returns one on success, or zero on failure.
+     Signing fails if the key is too small for the given hash size,
+     e.g., it's not possible to create a signature using SHA512 and a
+     512-bit RSA key.
+
+ -- Function: int rsa_md5_sign_digest (const struct rsa_private_key
+          *KEY, const uint8_t *DIGEST, mpz_t SIGNATURE)
+ -- Function: int rsa_sha1_sign_digest (const struct rsa_private_key
+          *KEY, const uint8_t *DIGEST, mpz_t SIGNATURE);
+ -- Function: int rsa_sha256_sign_digest (const struct rsa_private_key
+          *KEY, const uint8_t *DIGEST, mpz_t SIGNATURE);
+ -- Function: int rsa_sha512_sign_digest (const struct rsa_private_key
+          *KEY, const uint8_t *DIGEST, mpz_t SIGNATURE);
+     Creates a signature from the given hash digest. DIGEST should
+     point to a digest of size `MD5_DIGEST_SIZE', `SHA1_DIGEST_SIZE',
+     or `SHA256_DIGEST_SIZE', respectively. The signature is stored in
+     SIGNATURE (which must have been `mpz_init':ed earlier). Returns
+     one on success, or zero on failure.
+
+ -- Function: int rsa_md5_verify (const struct rsa_public_key *KEY,
+          struct md5_ctx *HASH, const mpz_t SIGNATURE)
+ -- Function: int rsa_sha1_verify (const struct rsa_public_key *KEY,
+          struct sha1_ctx *HASH, const mpz_t SIGNATURE)
+ -- Function: int rsa_sha256_verify (const struct rsa_public_key *KEY,
+          struct sha256_ctx *HASH, const mpz_t SIGNATURE)
+ -- Function: int rsa_sha512_verify (const struct rsa_public_key *KEY,
+          struct sha512_ctx *HASH, const mpz_t SIGNATURE)
+     Returns 1 if the signature is valid, or 0 if it isn't. In either
+     case, the hash context is reset so that it can be used for new
+     messages.
+
+ -- Function: int rsa_md5_verify_digest (const struct rsa_public_key
+          *KEY, const uint8_t *DIGEST, const mpz_t SIGNATURE)
+ -- Function: int rsa_sha1_verify_digest (const struct rsa_public_key
+          *KEY, const uint8_t *DIGEST, const mpz_t SIGNATURE)
+ -- Function: int rsa_sha256_verify_digest (const struct rsa_public_key
+          *KEY, const uint8_t *DIGEST, const mpz_t SIGNATURE)
+ -- Function: int rsa_sha512_verify_digest (const struct rsa_public_key
+          *KEY, const uint8_t *DIGEST, const mpz_t SIGNATURE)
+     Returns 1 if the signature is valid, or 0 if it isn't. DIGEST
+     should point to a digest of size `MD5_DIGEST_SIZE',
+     `SHA1_DIGEST_SIZE', or `SHA256_DIGEST_SIZE', respectively.
+
+   If you need to use the RSA trapdoor, the private key, in a way that
+isn't supported by the above functions Nettle also includes a function
+that computes `x^d mod n' and nothing more, using the CRT optimization.
+
+ -- Function: void rsa_compute_root (struct rsa_private_key *KEY, mpz_t
+          X, const mpz_t M)
+     Computes `x = m^d', efficiently.
+
+   At last, how do you create new keys?
+
+ -- Function: int rsa_generate_keypair (struct rsa_public_key *PUB,
+          struct rsa_private_key *KEY, void *RANDOM_CTX,
+          nettle_random_func RANDOM, void *PROGRESS_CTX,
+          nettle_progress_func PROGRESS, unsigned N_SIZE, unsigned
+          E_SIZE);
+     There are lots of parameters. PUB and KEY is where the resulting
+     key pair is stored. The structs should be initialized, but you
+     don't need to call `rsa_public_key_prepare' or
+     `rsa_private_key_prepare' after key generation.
+
+     RANDOM_CTX and RANDOM is a randomness generator.
+     `random(random_ctx, length, dst)' should generate `length' random
+     octets and store them at `dst'. For advice, see *Note Randomness::.
+
+     PROGRESS and PROGRESS_CTX can be used to get callbacks during the
+     key generation process, in order to uphold an illusion of
+     progress. PROGRESS can be NULL, in that case there are no
+     callbacks.
+
+     SIZE_N is the desired size of the modulo, in bits. If SIZE_E is
+     non-zero, it is the desired size of the public exponent and a
+     random exponent of that size is selected. But if E_SIZE is zero,
+     it is assumed that the caller has already chosen a value for `e',
+     and stored it in PUB.  Returns one on success, and zero on
+     failure. The function can fail for example if if N_SIZE is too
+     small, or if E_SIZE is zero and `pub->e' is an even number.
+
+\1f
+File: nettle.info,  Node: RSA-Footnotes,  Up: RSA
+
+   (1) Actually, the computation is not done like this, it is done more
+efficiently using `p', `q' and the Chinese remainder theorem (CRT). But
+the result is the same.
+
+\1f
+File: nettle.info,  Node: DSA,  Prev: RSA,  Up: Public-key algorithms
+
+6.5.3 Nettle's DSA support
+--------------------------
+
+The DSA digital signature algorithm is more complex than RSA. It was
+specified during the early 1990s, and in 1994 NIST published FIPS 186
+which is the authoritative specification.  Sometimes DSA is referred to
+using the acronym DSS, for Digital Signature Standard. The most recent
+revision of the specification, FIPS186-3, was issueed in 2009, and it
+adds support for larger hash functions than sha1.
+
+   For DSA, the underlying mathematical problem is the computation of
+discreet logarithms. The public key consists of a large prime `p', a
+small prime `q' which is a factor of `p-1', a number `g' which
+generates a subgroup of order `q' modulo `p', and an element `y' in
+that subgroup.
+
+   In the original DSA, the size of `q' is fixed to 160 bits, to match
+with the SHA1 hash algorithm. The size of `p' is in principle
+unlimited, but the standard specifies only nine specific sizes: `512 +
+l*64', where `l' is between 0 and 8. Thus, the maximum size of `p' is
+1024 bits, and sizes less than 1024 bits are considered obsolete and not
+secure.
+
+   The subgroup requirement means that if you compute
+
+     g^t mod p
+
+   for all possible integers `t', you will get precisely `q' distinct
+values.
+
+   The private key is a secret exponent `x', such that
+
+     g^x = y mod p
+
+   In mathematical speak, `x' is the "discrete logarithm" of `y' mod
+`p', with respect to the generator `g'. The size of `x' will also be
+about the same size as `q'. The security of the DSA algorithm relies on
+the difficulty of the discrete logarithm problem. Current algorithms to
+compute discrete logarithms in this setting, and hence crack DSA, are
+of two types. The first type works directly in the (multiplicative)
+group of integers mod `p'. The best known algorithm of this type is the
+Number Field Sieve, and it's complexity is similar to the complexity of
+factoring numbers of the same size as `p'. The other type works in the
+smaller `q'-sized subgroup generated by `g', which has a more difficult
+group structure. One good algorithm is Pollard-rho, which has
+complexity `sqrt(q)'.
+
+   The important point is that security depends on the size of _both_
+`p' and `q', and they should be choosen so that the difficulty of both
+discrete logarithm methods are comparable. Today, the security margin
+of the original DSA may be uncomfortably small. Using a `p' of 1024
+bits implies that cracking using the number field sieve is expected to
+take about the same time as factoring a 1024-bit RSA modulo, and using
+a `q' of size 160 bits implies that cracking using Pollard-rho will
+take roughly `2^80' group operations. With the size of `q' fixed, tied
+to the SHA1 digest size, it may be tempting to increase the size of `p'
+to, say, 4096 bits. This will provide excellent resistance against
+attacks like the number field sieve which works in the large group. But
+it will do very little to defend against Pollard-rho attacking the small
+subgroup; the attacker is slowed down at most by a single factor of 10
+due to the more expensive group operation. And the attacker will surely
+choose the latter attack.
+
+   The signature generation algorithm is randomized; in order to create
+a DSA signature, you need a good source for random numbers (*note
+Randomness::). Let us describe the common case of a 160-bit `q'.
+
+   To create a signature, one starts with the hash digest of the
+message, `h', which is a 160 bit number, and a random number `k,
+0<k<q', also 160 bits. Next, one computes
+
+     r = (g^k mod p) mod q
+     s = k^-1 (h + x r) mod q
+
+   The signature is the pair `(r, s)', two 160 bit numbers. Note the
+two different mod operations when computing `r', and the use of the
+secret exponent `x'.
+
+   To verify a signature, one first checks that `0 < r,s < q', and then
+one computes backwards,
+
+     w = s^-1 mod q
+     v = (g^(w h) y^(w r) mod p) mod q
+
+   The signature is valid if `v = r'. This works out because `w = s^-1
+mod q = k (h + x r)^-1 mod q', so that
+
+     g^(w h) y^(w r) = g^(w h) (g^x)^(w r) = g^(w (h + x r)) = g^k
+
+   When reducing mod `q' this yields `r'. Note that when verifying a
+signature, we don't know either `k' or `x': those numbers are secret.
+
+   If you can choose between RSA and DSA, which one is best? Both are
+believed to be secure. DSA gained popularity in the late 1990s, as a
+patent free alternative to RSA. Now that the RSA patents have expired,
+there's no compelling reason to want to use DSA. Today, the original
+DSA key size does not provide a large security margin, and it should
+probably be phased out together with RSA keys of 1024 bits. Using the
+revised DSA algorithm with a larger hash function, in particular,
+SHA256, a 256-bit `q', and `p' of size 2048 bits or more, should
+provide for a more comfortable security margin, but these variants are
+not yet in wide use.
+
+   DSA signatures are smaller than RSA signatures, which is important
+for some specialized applications.
+
+   From a practical point of view, DSA's need for a good randomness
+source is a serious disadvantage. If you ever use the same `k' (and
+`r') for two different message, you leak your private key.
+
+6.5.4 Nettle's DSA support
+--------------------------
+
+Like for RSA, Nettle represents DSA keys using two structures,
+containing values of type `mpz_t'. For information on how to customize
+allocation, see *Note GMP Allocation: (gmp)Custom Allocation.
+
+   Most of the DSA functions are very similar to the corresponding RSA
+functions, but there are a few differences pointed out below. For a
+start, there are no functions corresponding to `rsa_public_key_prepare'
+and `rsa_private_key_prepare'.
+
+ -- Context struct: dsa_public_key p q g y
+     The public parameters described above.
+
+ -- Context struct: dsa_private_key x
+     The private key `x'.
+
+   Before use, these structs must be initialized by calling one of
+
+ -- Function: void dsa_public_key_init (struct dsa_public_key *PUB)
+ -- Function: void dsa_private_key_init (struct dsa_private_key *KEY)
+     Calls `mpz_init' on all numbers in the key struct.
+
+   When finished with them, the space for the numbers must be
+deallocated by calling one of
+
+ -- Function: void dsa_public_key_clear (struct dsa_public_key *PUB)
+ -- Function: void dsa_private_key_clear (struct dsa_private_key *KEY)
+     Calls `mpz_clear' on all numbers in the key struct.
+
+   Signatures are represented using the structure below, and need to be
+initialized and cleared in the same way as the key structs.
+
+ -- Context struct: dsa_signature r s
+
+ -- Function: void dsa_signature_init (struct dsa_signature *SIGNATURE)
+ -- Function: void dsa_signature_clear (struct dsa_signature *SIGNATURE)
+     You must call `dsa_signature_init' before creating or using a
+     signature, and call `dsa_signature_clear' when you are finished
+     with it.
+
+   For signing, you need to provide both the public and the private key
+(unlike RSA, where the private key struct includes all information
+needed for signing), and a source for random numbers.  Signatures can
+use the SHA1 or the SHA256 hash function, although the implementation
+of DSA with SHA256 should be considered somewhat experimental due to
+lack of official test vectors and interoperability testing.
+
+ -- Function: int dsa_sha1_sign (const struct dsa_public_key *PUB,
+          const struct dsa_private_key *KEY, void *RANDOM_CTX,
+          nettle_random_func RANDOM, struct sha1_ctx *HASH, struct
+          dsa_signature *SIGNATURE)
+ -- Function: int dsa_sha1_sign_digest (const struct dsa_public_key
+          *PUB, const struct dsa_private_key *KEY, void *RANDOM_CTX,
+          nettle_random_func RANDOM, const uint8_t *DIGEST, struct
+          dsa_signature *SIGNATURE)
+ -- Function: int dsa_sha256_sign (const struct dsa_public_key *PUB,
+          const struct dsa_private_key *KEY, void *RANDOM_CTX,
+          nettle_random_func RANDOM, struct sha256_ctx *HASH, struct
+          dsa_signature *SIGNATURE)
+ -- Function: int dsa_sha256_sign_digest (const struct dsa_public_key
+          *PUB, const struct dsa_private_key *KEY, void *RANDOM_CTX,
+          nettle_random_func RANDOM, const uint8_t *DIGEST, struct
+          dsa_signature *SIGNATURE)
+     Creates a signature from the given hash context or digest.
+     RANDOM_CTX and RANDOM is a randomness generator.
+     `random(random_ctx, length, dst)' should generate `length' random
+     octets and store them at `dst'. For advice, see *Note
+     Randomness::. Returns one on success, or zero on failure.  Signing
+     fails if the key size and the hash size don't match.
+
+   Verifying signatures is a little easier, since no randomness
+generator is needed. The functions are
+
+ -- Function: int dsa_sha1_verify (const struct dsa_public_key *KEY,
+          struct sha1_ctx *HASH, const struct dsa_signature *SIGNATURE)
+ -- Function: int dsa_sha1_verify_digest (const struct dsa_public_key
+          *KEY, const uint8_t *DIGEST, const struct dsa_signature
+          *SIGNATURE)
+ -- Function: int dsa_sha256_verify (const struct dsa_public_key *KEY,
+          struct sha256_ctx *HASH, const struct dsa_signature
+          *SIGNATURE)
+ -- Function: int dsa_sha256_verify_digest (const struct dsa_public_key
+          *KEY, const uint8_t *DIGEST, const struct dsa_signature
+          *SIGNATURE)
+     Verifies a signature. Returns 1 if the signature is valid,
+     otherwise 0.
+
+   Key generation uses mostly the same parameters as the corresponding
+RSA function.
+
+ -- Function: int dsa_generate_keypair (struct dsa_public_key *PUB,
+          struct dsa_private_key *KEY, void *RANDOM_CTX,
+          nettle_random_func RANDOM, void *PROGRESS_CTX,
+          nettle_progress_func PROGRESS, unsigned P_BITS, unsigned
+          Q_BITS)
+     PUB and KEY is where the resulting key pair is stored. The structs
+     should be initialized before you call this function.
+
+     RANDOM_CTX and RANDOM is a randomness generator.
+     `random(random_ctx, length, dst)' should generate `length' random
+     octets and store them at `dst'. For advice, see *Note Randomness::.
+
+     PROGRESS and PROGRESS_CTX can be used to get callbacks during the
+     key generation process, in order to uphold an illusion of
+     progress. PROGRESS can be NULL, in that case there are no
+     callbacks.
+
+     P_BITS and Q_BITS are the desired sizes of `p' and `q'. To
+     generate keys that conform to the original DSA standard, you must
+     use `q_bits = 160' and select P_BITS of the form `p_bits = 512 +
+     l*64', for `0 <= l <= 8', where the smaller sizes are no longer
+     recommended, so you should most likely stick to `p_bits = 1024'.
+     Non-standard sizes are possible, in particular `p_bits' larger
+     than 1024, although DSA implementations can not in general be
+     expected to support such keys. Also note that using very large
+     P_BITS, with Q_BITS fixed at 160, doesn't make much sense, because
+     the security is also limited by the size of the smaller prime.
+     Using a larger `q_bits' requires switchign to a larger hash
+     function. To generate DSA keys for use with SHA256, use `q_bits =
+     256' and, e.g., `p_bits = 2048'.
+
+     Returns one on success, and zero on failure. The function will
+     fail if Q_BITS is neither 160 nor 256, or if P_BITS is unreasonably
+     small.
+
+\1f
+File: nettle.info,  Node: Randomness,  Next: Miscellaneous functions,  Prev: Public-key algorithms,  Up: Reference
+
+6.6 Randomness
+==============
+
+A crucial ingredient in many cryptographic contexts is randomness: Let
+`p' be a random prime, choose a random initialization vector `iv', a
+random key `k' and a random exponent `e', etc. In the theories, it is
+assumed that you have plenty of randomness around.  If this assumption
+is not true in practice, systems that are otherwise perfectly secure,
+can be broken. Randomness has often turned out to be the weakest link
+in the chain.
+
+   In non-cryptographic applications, such as games as well as
+scientific simulation, a good randomness generator usually means a
+generator that has good statistical properties, and is seeded by some
+simple function of things like the current time, process id, and host
+name.
+
+   However, such a generator is inadequate for cryptography, for at
+least two reasons:
+
+   * It's too easy for an attacker to guess the initial seed. Even if
+     it will take some 2^32 tries before he guesses right, that's far
+     too easy. For example, if the process id is 16 bits, the
+     resolution of "current time" is one second, and the attacker knows
+     what day the generator was seeded, there are only about 2^32
+     possibilities to try if all possible values for the process id and
+     time-of-day are tried.
+
+   * The generator output reveals too much. By observing only a small
+     segment of the generator's output, its internal state can be
+     recovered, and from there, all previous output and all future
+     output can be computed by the attacker.
+
+   A randomness generator that is used for cryptographic purposes must
+have better properties. Let's first look at the seeding, as the issues
+here are mostly independent of the rest of the generator. The initial
+state of the generator (its seed) must be unguessable by the attacker.
+So what's unguessable? It depends on what the attacker already knows.
+The concept used in information theory to reason about such things is
+called "entropy", or "conditional entropy" (not to be confused with the
+thermodynamic concept with the same name). A reasonable requirement is
+that the seed contains a conditional entropy of at least some 80-100
+bits. This property can be explained as follows: Allow the attacker to
+ask `n' yes-no-questions, of his own choice, about the seed. If the
+attacker, using this question-and-answer session, as well as any other
+information he knows about the seeding process, still can't guess the
+seed correctly, then the conditional entropy is more than `n' bits.
+
+   Let's look at an example. Say information about timing of received
+network packets is used in the seeding process. If there is some random
+network traffic going on, this will contribute some bits of entropy or
+"unguessability" to the seed. However, if the attacker can listen in to
+the local network, or if all but a small number of the packets were
+transmitted by machines that the attacker can monitor, this additional
+information makes the seed easier for the attacker to figure out. Even
+if the information is exactly the same, the conditional entropy, or
+unguessability, is smaller for an attacker that knows some of it already
+before the hypothetical question-and-answer session.
+
+   Seeding of good generators is usually based on several sources. The
+key point here is that the amount of unguessability that each source
+contributes, depends on who the attacker is. Some sources that have been
+used are:
+
+High resolution timing of i/o activities
+     Such as completed blocks from spinning hard disks, network
+     packets, etc.  Getting access to such information is quite system
+     dependent, and not all systems include suitable hardware. If
+     available, it's one of the better randomness source one can find
+     in a digital, mostly predictable, computer.
+
+User activity
+     Timing and contents of user interaction events is another popular
+     source that is available for interactive programs (even if I
+     suspect that it is sometimes used in order to make the user feel
+     good, not because the quality of the input is needed or used
+     properly). Obviously, not available when a machine is unattended.
+     Also beware of networks: User interaction that happens across a
+     long serial cable, TELNET session, or even SSH session may be
+     visible to an attacker, in full or partially.
+
+Audio input
+     Any room, or even a microphone input that's left unconnected, is a
+     source of some random background noise, which can be fed into the
+     seeding process.
+
+Specialized hardware
+     Hardware devices with the sole purpose of generating random data
+     have been designed. They range from radioactive samples with an
+     attached Geiger counter, to amplification of the inherent noise in
+     electronic components such as diodes and resistors, to
+     low-frequency sampling of chaotic systems. Hashing successive
+     images of a Lava lamp is a spectacular example of the latter type.
+
+Secret information
+     Secret information, such as user passwords or keys, or private
+     files stored on disk, can provide some unguessability. A problem
+     is that if the information is revealed at a later time, the
+     unguessability vanishes. Another problem is that this kind of
+     information tends to be fairly constant, so if you rely on it and
+     seed your generator regularly, you risk constructing almost
+     similar seeds or even constructing the same seed more than once.
+
+   For all practical sources, it's difficult but important to provide a
+reliable lower bound on the amount of unguessability that it provides.
+Two important points are to make sure that the attacker can't observe
+your sources (so if you like the Lava lamp idea, remember that you have
+to get your own lamp, and not put it by a window or anywhere else where
+strangers can see it), and that hardware failures are detected. What if
+the bulb in the Lava lamp, which you keep locked into a cupboard
+following the above advice, breaks after a few months?
+
+   So let's assume that we have been able to find an unguessable seed,
+which contains at least 80 bits of conditional entropy, relative to all
+attackers that we care about (typically, we must at the very least
+assume that no attacker has root privileges on our machine).
+
+   How do we generate output from this seed, and how much can we get?
+Some generators (notably the Linux `/dev/random' generator) tries to
+estimate available entropy and restrict the amount of output. The goal
+is that if you read 128 bits from `/dev/random', you should get 128
+"truly random" bits. This is a property that is useful in some
+specialized circumstances, for instance when generating key material for
+a one time pad, or when working with unconditional blinding, but in most
+cases, it doesn't matter much. For most application, there's no limit on
+the amount of useful "random" data that we can generate from a small
+seed; what matters is that the seed is unguessable and that the
+generator has good cryptographic properties.
+
+   At the heart of all generators lies its internal state. Future output
+is determined by the internal state alone. Let's call it the generator's
+key. The key is initialized from the unguessable seed. Important
+properties of a generator are:
+
+"Key-hiding"
+     An attacker observing the output should not be able to recover the
+     generator's key.
+
+"Independence of outputs"
+     Observing some of the output should not help the attacker to guess
+     previous or future output.
+
+"Forward secrecy"
+     Even if an attacker compromises the generator's key, he should not
+     be able to guess the generator output _before_ the key compromise.
+
+"Recovery from key compromise"
+     If an attacker compromises the generator's key, he can compute
+     _all_ future output. This is inevitable if the generator is seeded
+     only once, at startup. However, the generator can provide a
+     reseeding mechanism, to achieve recovery from key compromise. More
+     precisely: If the attacker compromises the key at a particular
+     time `t_1', there is another later time `t_2', such that if the
+     attacker observes all output generated between `t_1' and `t_2', he
+     still can't guess what output is generated after `t_2'.
+
+
+   Nettle includes one randomness generator that is believed to have all
+the above properties, and two simpler ones.
+
+   ARCFOUR, like any stream cipher, can be used as a randomness
+generator. Its output should be of reasonable quality, if the seed is
+hashed properly before it is used with `arcfour_set_key'. There's no
+single natural way to reseed it, but if you need reseeding, you should
+be using Yarrow instead.
+
+   The "lagged Fibonacci" generator in `<nettle/knuth-lfib.h>' is a
+fast generator with good statistical properties, but is *not* for
+cryptographic use, and therefore not documented here. It is included
+mostly because the Nettle test suite needs to generate some test data
+from a small seed.
+
+   The recommended generator to use is Yarrow, described below.
+
+6.6.1 Yarrow
+------------
+
+Yarrow is a family of pseudo-randomness generators, designed for
+cryptographic use, by John Kelsey, Bruce Schneier and Niels Ferguson.
+Yarrow-160 is described in a paper at
+`http://www.counterpane.com/yarrow.html', and it uses SHA1 and
+triple-DES, and has a 160-bit internal state. Nettle implements
+Yarrow-256, which is similar, but uses SHA256 and AES to get an
+internal state of 256 bits.
+
+   Yarrow was an almost finished project, the paper mentioned above is
+the closest thing to a specification for it, but some smaller details
+are left out. There is no official reference implementation or test
+cases.  This section includes an overview of Yarrow, but for the
+details of Yarrow-256, as implemented by Nettle, you have to consult
+the source code. Maybe a complete specification can be written later.
+
+   Yarrow can use many sources (at least two are needed for proper
+reseeding), and two randomness "pools", referred to as the "slow pool"
+and the "fast pool". Input from the sources is fed alternatingly into
+the two pools. When one of the sources has contributed 100 bits of
+entropy to the fast pool, a "fast reseed" happens and the fast pool is
+mixed into the internal state. When at least two of the sources have
+contributed at least 160 bits each to the slow pool, a "slow reseed"
+takes place. The contents of both pools are mixed into the internal
+state. These procedures should ensure that the generator will eventually
+recover after a key compromise.
+
+   The output is generated by using AES to encrypt a counter, using the
+generator's current key. After each request for output, another 256
+bits are generated which replace the key. This ensures forward secrecy.
+
+   Yarrow can also use a "seed file" to save state across restarts.
+Yarrow is seeded by either feeding it the contents of the previous seed
+file, or feeding it input from its sources until a slow reseed happens.
+
+   Nettle defines Yarrow-256 in `<nettle/yarrow.h>'.
+
+ -- Context struct: struct yarrow256_ctx
+
+ -- Context struct: struct yarrow_source
+     Information about a single source.
+
+ -- Constant: YARROW256_SEED_FILE_SIZE
+     Recommanded size of the Yarrow-256 seed file.
+
+ -- Function: void yarrow256_init (struct yarrow256_ctx *CTX, unsigned
+          NSOURCES, struct yarrow_source *SOURCES)
+     Initializes the yarrow context, and its NSOURCES sources. It's
+     possible to call it with NSOURCES=0 and SOURCES=NULL, if you don't
+     need the update features.
+
+ -- Function: void yarrow256_seed (struct yarrow256_ctx *CTX, unsigned
+          LENGTH, uint8_t *SEED_FILE)
+     Seeds Yarrow-256 from a previous seed file. LENGTH should be at
+     least `YARROW256_SEED_FILE_SIZE', but it can be larger.
+
+     The generator will trust you that the SEED_FILE data really is
+     unguessable. After calling this function, you _must_ overwrite the
+     old seed file with newly generated data from `yarrow256_random'.
+     If it's possible for several processes to read the seed file at
+     about the same time, access must be coordinated using some locking
+     mechanism.
+
+ -- Function: int yarrow256_update (struct yarrow256_ctx *CTX, unsigned
+          SOURCE, unsigned ENTROPY, unsigned LENGTH, const uint8_t
+          *DATA)
+     Updates the generator with data from source SOURCE (an index that
+     must be smaller than the number of sources). ENTROPY is your
+     estimated lower bound for the entropy in the data, measured in
+     bits.  Calling update with zero ENTROPY is always safe, no matter
+     if the data is random or not.
+
+     Returns 1 if a reseed happened, in which case an application using
+     a seed file may want to generate new seed data with
+     `yarrow256_random' and overwrite the seed file. Otherwise, the
+     function returns 0.
+
+ -- Function: void yarrow256_random (struct yarrow256_ctx *CTX,
+          unsigned LENGTH, uint8_t *DST)
+     Generates LENGTH octets of output. The generator must be seeded
+     before you call this function.
+
+     If you don't need forward secrecy, e.g. if you need non-secret
+     randomness for initialization vectors or padding, you can gain some
+     efficiency by buffering, calling this function for reasonably large
+     blocks of data, say 100-1000 octets at a time.
+
+ -- Function: int yarrow256_is_seeded (struct yarrow256_ctx *CTX)
+     Returns 1 if the generator is seeded and ready to generate output,
+     otherwise 0.
+
+ -- Function: unsigned yarrow256_needed_sources (struct yarrow256_ctx
+          *CTX)
+     Returns the number of sources that must reach the threshold before
+     a slow reseed will happen. Useful primarily when the generator is
+     unseeded.
+
+ -- Function: void yarrow256_fast_reseed (struct yarrow256_ctx *CTX)
+ -- Function: void yarrow256_slow_reseed (struct yarrow256_ctx *CTX)
+     Causes a fast or slow reseed to take place immediately, regardless
+     of the current entropy estimates of the two pools. Use with care.
+
+   Nettle includes an entropy estimator for one kind of input source:
+User keyboard input.
+
+ -- Context struct: struct yarrow_key_event_ctx
+     Information about recent key events.
+
+ -- Function: void yarrow_key_event_init (struct yarrow_key_event_ctx
+          *CTX)
+     Initializes the context.
+
+ -- Function: unsigned yarrow_key_event_estimate (struct
+          yarrow_key_event_ctx *CTX, unsigned KEY, unsigned TIME)
+     KEY is the id of the key (ASCII value, hardware key code, X
+     keysym, ..., it doesn't matter), and TIME is the timestamp of the
+     event. The time must be given in units matching the resolution by
+     which you read the clock. If you read the clock with microsecond
+     precision, TIME should be provided in units of microseconds. But
+     if you use `gettimeofday' on a typical Unix system where the clock
+     ticks 10 or so microseconds at a time, TIME should be given in
+     units of 10 microseconds.
+
+     Returns an entropy estimate, in bits, suitable for calling
+     `yarrow256_update'. Usually, 0, 1 or 2 bits.
+
+\1f
+File: nettle.info,  Node: Miscellaneous functions,  Next: Compatibility functions,  Prev: Randomness,  Up: Reference
+
+6.7 Miscellaneous functions
+===========================
+
+ -- Function: uint8_t * memxor (uint8_t *DST, const uint8_t *SRC,
+          size_t N)
+     XORs the source area on top of the destination area. The interface
+     doesn't follow the Nettle conventions, because it is intended to be
+     similar to the ANSI-C `memcpy' function.
+
+   `memxor' is declared in `<nettle/memxor.h>'.
+
+\1f
+File: nettle.info,  Node: Compatibility functions,  Prev: Miscellaneous functions,  Up: Reference
+
+6.8 Compatibility functions
+===========================
+
+For convenience, Nettle includes alternative interfaces to some
+algorithms, for compatibility with some other popular crypto toolkits.
+These are not fully documented here; refer to the source or to the
+documentation for the original implementation.
+
+   MD5 is defined in [RFC 1321], which includes a reference
+implementation.  Nettle defines a compatible interface to MD5 in
+`<nettle/md5-compat.h>'. This file defines the typedef `MD5_CTX', and
+declares the functions `MD5Init', `MD5Update' and `MD5Final'.
+
+   Eric Young's "libdes" (also part of OpenSSL) is a quite popular DES
+implementation. Nettle includes a subset if its interface in
+`<nettle/des-compat.h>'. This file defines the typedefs
+`des_key_schedule' and `des_cblock', two constants `DES_ENCRYPT' and
+`DES_DECRYPT', and declares one global variable `des_check_key', and
+the functions `des_cbc_cksum' `des_cbc_encrypt', `des_ecb2_encrypt',
+`des_ecb3_encrypt', `des_ecb_encrypt', `des_ede2_cbc_encrypt',
+`des_ede3_cbc_encrypt', `des_is_weak_key', `des_key_sched',
+`des_ncbc_encrypt' `des_set_key', and `des_set_odd_parity'.
+
+\1f
+File: nettle.info,  Node: Nettle soup,  Next: Installation,  Prev: Reference,  Up: Top
+
+7 Traditional Nettle Soup
+*************************
+
+For the serious nettle hacker, here is a recipe for nettle soup. 4
+servings.
+
+     1 liter fresh nettles (urtica dioica)
+
+     2 tablespoons butter
+
+     3 tablespoons flour
+
+     1 liter stock (meat or vegetable)
+
+     1/2 teaspoon salt
+
+     a tad white pepper
+
+     some cream or milk
+
+   Gather 1 liter fresh nettles. Use gloves! Small, tender shoots are
+preferable but the tops of larger nettles can also be used.
+
+   Rinse the nettles very well. Boil them for 10 minutes in lightly
+salted water. Strain the nettles and save the water. Hack the nettles.
+Melt the butter and mix in the flour. Dilute with stock and the
+nettle-water you saved earlier. Add the hacked nettles. If you wish you
+can add some milk or cream at this stage. Bring to a boil and let boil
+for a few minutes.  Season with salt and pepper.
+
+   Serve with boiled egg-halves.
+
+\1f
+File: nettle.info,  Node: Installation,  Next: Index,  Prev: Nettle soup,  Up: Top
+
+8 Installation
+**************
+
+Nettle uses `autoconf'. To build it, unpack the source and run
+
+     ./configure
+     make
+     make check
+     make install
+
+to install in the default location, `/usr/local'. The library files are
+installed in `/use/local/lib/libnettle.a' `/use/local/lib/libhogweed.a'
+and the include files are installed in `/use/local/include/nettle/'.
+
+   To get a list of configure options, use `./configure --help'.
+
+   By default, only static libraries are built and installed. To also
+build and install shared libraries, use the ` --enable-shared' option
+to `./configure'.
+
+   Using GNU make is recommended. For other make programs, in particular
+BSD make, you may have to use the `--disable-dependency-tracking'
+option to `./configure'.
+
+\1f
+File: nettle.info,  Node: Index,  Prev: Installation,  Up: Top
+
+Function and Concept Index
+**************************
+
+\0\b[index\0\b]
+* Menu:
+
+* aes_decrypt:                           Cipher functions.    (line 123)
+* aes_encrypt:                           Cipher functions.    (line 116)
+* aes_invert_key:                        Cipher functions.    (line 105)
+* aes_set_decrypt_key:                   Cipher functions.    (line 101)
+* aes_set_encrypt_key:                   Cipher functions.    (line  99)
+* arcfour_crypt:                         Cipher functions.    (line 175)
+* arcfour_set_key:                       Cipher functions.    (line 170)
+* arctwo_decrypt:                        Cipher functions.    (line 240)
+* arctwo_encrypt:                        Cipher functions.    (line 233)
+* arctwo_set_key:                        Cipher functions.    (line 217)
+* arctwo_set_key_ekb:                    Cipher functions.    (line 215)
+* arctwo_set_key_gutmann:                Cipher functions.    (line 219)
+* Block Cipher:                          Cipher functions.    (line  12)
+* blowfish_decrypt:                      Cipher functions.    (line 282)
+* blowfish_encrypt:                      Cipher functions.    (line 275)
+* blowfish_set_key:                      Cipher functions.    (line 265)
+* camellia_crypt:                        Cipher functions.    (line 332)
+* camellia_invert_key:                   Cipher functions.    (line 321)
+* camellia_set_decrypt_key:              Cipher functions.    (line 317)
+* camellia_set_encrypt_key:              Cipher functions.    (line 315)
+* cast128_decrypt:                       Cipher functions.    (line 372)
+* cast128_encrypt:                       Cipher functions.    (line 365)
+* cast128_set_key:                       Cipher functions.    (line 360)
+* CBC Mode:                              CBC.                 (line   6)
+* CBC_CTX:                               CBC.                 (line  51)
+* CBC_DECRYPT:                           CBC.                 (line  72)
+* cbc_decrypt:                           CBC.                 (line  37)
+* CBC_ENCRYPT:                           CBC.                 (line  71)
+* cbc_encrypt:                           CBC.                 (line  34)
+* CBC_SET_IV:                            CBC.                 (line  66)
+* Cipher:                                Cipher functions.    (line   6)
+* Cipher Block Chaining:                 CBC.                 (line   6)
+* Collision-resistant:                   Hash functions.      (line  18)
+* Conditional entropy:                   Randomness.          (line  51)
+* Counter Mode:                          CTR.                 (line   6)
+* CTR Mode:                              CTR.                 (line   6)
+* CTR_CRYPT:                             CTR.                 (line  60)
+* ctr_crypt:                             CTR.                 (line  36)
+* CTR_CTX:                               CTR.                 (line  48)
+* CTR_SET_COUNTER:                       CTR.                 (line  55)
+* des3_decrypt:                          Cipher functions.    (line 494)
+* des3_encrypt:                          Cipher functions.    (line 487)
+* des3_set_key:                          Cipher functions.    (line 476)
+* des_check_parity:                      Cipher functions.    (line 420)
+* des_decrypt:                           Cipher functions.    (line 416)
+* des_encrypt:                           Cipher functions.    (line 409)
+* des_fix_parity:                        Cipher functions.    (line 425)
+* des_set_key:                           Cipher functions.    (line 401)
+* dsa_generate_keypair:                  DSA.                 (line 210)
+* dsa_private_key_clear:                 DSA.                 (line 142)
+* dsa_private_key_init:                  DSA.                 (line 135)
+* dsa_public_key_clear:                  DSA.                 (line 141)
+* dsa_public_key_init:                   DSA.                 (line 134)
+* dsa_sha1_sign:                         DSA.                 (line 166)
+* dsa_sha1_sign_digest:                  DSA.                 (line 170)
+* dsa_sha1_verify:                       DSA.                 (line 190)
+* dsa_sha1_verify_digest:                DSA.                 (line 193)
+* dsa_sha256_sign:                       DSA.                 (line 174)
+* dsa_sha256_sign_digest:                DSA.                 (line 178)
+* dsa_sha256_verify:                     DSA.                 (line 196)
+* dsa_sha256_verify_digest:              DSA.                 (line 199)
+* dsa_signature_clear:                   DSA.                 (line 151)
+* dsa_signature_init:                    DSA.                 (line 150)
+* Entropy:                               Randomness.          (line  51)
+* Galois Counter Mode:                   GCM.                 (line   6)
+* GCM:                                   GCM.                 (line   6)
+* gcm_aes_decrypt:                       GCM.                 (line 167)
+* gcm_aes_digest:                        GCM.                 (line 174)
+* gcm_aes_encrypt:                       GCM.                 (line 165)
+* gcm_aes_set_iv:                        GCM.                 (line 154)
+* gcm_aes_set_key:                       GCM.                 (line 149)
+* gcm_aes_update:                        GCM.                 (line 158)
+* GCM_CTX:                               GCM.                 (line 102)
+* GCM_DECRYPT:                           GCM.                 (line 132)
+* gcm_decrypt:                           GCM.                 (line  74)
+* GCM_DIGEST:                            GCM.                 (line 133)
+* gcm_digest:                            GCM.                 (line  82)
+* GCM_ENCRYPT:                           GCM.                 (line 131)
+* gcm_encrypt:                           GCM.                 (line  71)
+* GCM_SET_IV:                            GCM.                 (line 123)
+* gcm_set_iv:                            GCM.                 (line  58)
+* GCM_SET_KEY:                           GCM.                 (line 117)
+* gcm_set_key:                           GCM.                 (line  52)
+* GCM_UPDATE:                            GCM.                 (line 127)
+* gcm_update:                            GCM.                 (line  63)
+* Hash function:                         Hash functions.      (line   6)
+* HMAC_CTX:                              Keyed hash functions.
+                                                              (line  88)
+* HMAC_DIGEST:                           Keyed hash functions.
+                                                              (line 110)
+* hmac_digest:                           Keyed hash functions.
+                                                              (line  76)
+* hmac_md5_digest:                       Keyed hash functions.
+                                                              (line 140)
+* hmac_md5_set_key:                      Keyed hash functions.
+                                                              (line 132)
+* hmac_md5_update:                       Keyed hash functions.
+                                                              (line 136)
+* hmac_ripemd160_digest:                 Keyed hash functions.
+                                                              (line 162)
+* hmac_ripemd160_set_key:                Keyed hash functions.
+                                                              (line 154)
+* hmac_ripemd160_update:                 Keyed hash functions.
+                                                              (line 158)
+* HMAC_SET_KEY:                          Keyed hash functions.
+                                                              (line 104)
+* hmac_set_key:                          Keyed hash functions.
+                                                              (line  61)
+* hmac_sha1_digest:                      Keyed hash functions.
+                                                              (line 184)
+* hmac_sha1_set_key:                     Keyed hash functions.
+                                                              (line 176)
+* hmac_sha1_update:                      Keyed hash functions.
+                                                              (line 180)
+* hmac_sha256_digest:                    Keyed hash functions.
+                                                              (line 206)
+* hmac_sha256_set_key:                   Keyed hash functions.
+                                                              (line 198)
+* hmac_sha256_update:                    Keyed hash functions.
+                                                              (line 202)
+* hmac_sha512_digest:                    Keyed hash functions.
+                                                              (line 228)
+* hmac_sha512_set_key:                   Keyed hash functions.
+                                                              (line 220)
+* hmac_sha512_update:                    Keyed hash functions.
+                                                              (line 224)
+* hmac_update:                           Keyed hash functions.
+                                                              (line  68)
+* Keyed Hash Function:                   Keyed hash functions.
+                                                              (line   6)
+* MAC:                                   Keyed hash functions.
+                                                              (line   6)
+* md2_digest:                            Hash functions.      (line  96)
+* md2_init:                              Hash functions.      (line  88)
+* md2_update:                            Hash functions.      (line  92)
+* md4_digest:                            Hash functions.      (line 129)
+* md4_init:                              Hash functions.      (line 121)
+* md4_update:                            Hash functions.      (line 125)
+* md5_digest:                            Hash functions.      (line  58)
+* md5_init:                              Hash functions.      (line  50)
+* md5_update:                            Hash functions.      (line  54)
+* memxor:                                Miscellaneous functions.
+                                                              (line   8)
+* Message Authentication Code:           Keyed hash functions.
+                                                              (line   6)
+* One-way:                               Hash functions.      (line  14)
+* One-way function:                      Public-key algorithms.
+                                                              (line  18)
+* Public Key Cryptography:               Public-key algorithms.
+                                                              (line  18)
+* Randomness:                            Randomness.          (line   6)
+* ripemd160_digest:                      Hash functions.      (line 162)
+* ripemd160_init:                        Hash functions.      (line 154)
+* ripemd160_update:                      Hash functions.      (line 158)
+* rsa_compute_root:                      RSA.                 (line 187)
+* rsa_generate_keypair:                  RSA.                 (line 196)
+* rsa_md5_sign:                          RSA.                 (line 130)
+* rsa_md5_sign_digest:                   RSA.                 (line 145)
+* rsa_md5_verify:                        RSA.                 (line 159)
+* rsa_md5_verify_digest:                 RSA.                 (line 171)
+* rsa_private_key_clear:                 RSA.                 (line  96)
+* rsa_private_key_init:                  RSA.                 (line  89)
+* rsa_private_key_prepare:               RSA.                 (line 109)
+* rsa_public_key_clear:                  RSA.                 (line  95)
+* rsa_public_key_init:                   RSA.                 (line  88)
+* rsa_public_key_prepare:                RSA.                 (line 108)
+* rsa_sha1_sign:                         RSA.                 (line 132)
+* rsa_sha1_sign_digest:                  RSA.                 (line 147)
+* rsa_sha1_verify:                       RSA.                 (line 161)
+* rsa_sha1_verify_digest:                RSA.                 (line 173)
+* rsa_sha256_sign:                       RSA.                 (line 134)
+* rsa_sha256_sign_digest:                RSA.                 (line 149)
+* rsa_sha256_verify:                     RSA.                 (line 163)
+* rsa_sha256_verify_digest:              RSA.                 (line 175)
+* rsa_sha512_sign:                       RSA.                 (line 136)
+* rsa_sha512_sign_digest:                RSA.                 (line 151)
+* rsa_sha512_verify:                     RSA.                 (line 165)
+* rsa_sha512_verify_digest:              RSA.                 (line 177)
+* serpent_decrypt:                       Cipher functions.    (line 533)
+* serpent_encrypt:                       Cipher functions.    (line 526)
+* serpent_set_key:                       Cipher functions.    (line 521)
+* sha1_digest:                           Hash functions.      (line 197)
+* sha1_init:                             Hash functions.      (line 189)
+* sha1_update:                           Hash functions.      (line 193)
+* sha224_digest:                         Hash functions.      (line 265)
+* sha224_init:                           Hash functions.      (line 257)
+* sha224_update:                         Hash functions.      (line 261)
+* sha256_digest:                         Hash functions.      (line 231)
+* sha256_init:                           Hash functions.      (line 223)
+* sha256_update:                         Hash functions.      (line 227)
+* sha384_digest:                         Hash functions.      (line 335)
+* sha384_init:                           Hash functions.      (line 327)
+* sha384_update:                         Hash functions.      (line 331)
+* sha512_digest:                         Hash functions.      (line 301)
+* sha512_init:                           Hash functions.      (line 293)
+* sha512_update:                         Hash functions.      (line 297)
+* Stream Cipher:                         Cipher functions.    (line  12)
+* twofish_decrypt:                       Cipher functions.    (line 569)
+* twofish_encrypt:                       Cipher functions.    (line 562)
+* twofish_set_key:                       Cipher functions.    (line 557)
+* yarrow256_fast_reseed:                 Randomness.          (line 277)
+* yarrow256_init:                        Randomness.          (line 226)
+* yarrow256_is_seeded:                   Randomness.          (line 267)
+* yarrow256_needed_sources:              Randomness.          (line 272)
+* yarrow256_random:                      Randomness.          (line 258)
+* yarrow256_seed:                        Randomness.          (line 232)
+* yarrow256_slow_reseed:                 Randomness.          (line 278)
+* yarrow256_update:                      Randomness.          (line 245)
+* yarrow_key_event_estimate:             Randomness.          (line 293)
+* yarrow_key_event_init:                 Randomness.          (line 289)
+
+
+\1f
+Tag Table:
+Node: Top\7f542
+Node: Introduction\7f2138
+Node: Copyright\7f3704
+Node: Conventions\7f7439
+Node: Example\7f9401
+Node: Linking\7f10648
+Node: Reference\7f11481
+Node: Hash functions\7f11849
+Node: Cipher functions\7f25050
+Node: Cipher modes\7f50940
+Node: CBC\7f51968
+Node: CTR\7f55242
+Node: GCM\7f57768
+Node: Keyed hash functions\7f65329
+Node: Public-key algorithms\7f74686
+Node: RSA\7f78606
+Node: RSA-Footnotes\7f89220
+Ref: RSA-Footnote-1\7f89273
+Node: DSA\7f89442
+Node: Randomness\7f100785
+Node: Miscellaneous functions\7f115898
+Node: Compatibility functions\7f116402
+Node: Nettle soup\7f117647
+Node: Installation\7f118640
+Node: Index\7f119487
+\1f
+End Tag Table
+
+\1f
+Local Variables:
+coding: iso-8859-1
+End:
diff --git a/nettle.pc.in b/nettle.pc.in
new file mode 100644 (file)
index 0000000..eb0020c
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Nettle
+Description: Nettle low-level cryptographic library (symmetric algorithms)
+URL: http://www.lysator.liu.se/~nisse/nettle
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -lnettle
+Cflags: -I${includedir}
diff --git a/nettle.pdf b/nettle.pdf
new file mode 100644 (file)
index 0000000..e112104
Binary files /dev/null and b/nettle.pdf differ
diff --git a/nettle.texinfo b/nettle.texinfo
new file mode 100644 (file)
index 0000000..51bfaea
--- /dev/null
@@ -0,0 +1,3052 @@
+\input texinfo          @c -*-texinfo-*-
+@c %**start of header
+@setfilename nettle.info
+@settitle Nettle: a low-level cryptographic library
+@documentencoding ISO-8859-1
+@footnotestyle separate
+@syncodeindex fn cp
+@c %**end of header
+
+@set UPDATED-FOR 2.3
+@set AUTHOR Niels Möller
+
+@copying
+This manual is for the Nettle library (version @value{UPDATED-FOR}), a
+low-level cryptographic library.
+
+Originally written 2001 by @value{AUTHOR}, updated 2011.
+
+@quotation
+This manual is placed in the public domain. You may freely copy it, in
+whole or in part, with or without modification. Attribution is
+appreciated, but not required.
+@end quotation
+@end copying
+
+@titlepage
+@title Nettle Manual
+@subtitle For the Nettle Library version @value{UPDATED-FOR}
+@author @value{AUTHOR}
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+@dircategory Encryption
+@direntry
+* Nettle: (nettle).             A low-level cryptographic library.
+@end direntry
+
+@contents
+
+@ifnottex
+@node     Top, Introduction, (dir), (dir)
+@comment  node-name,  next,  previous,  up
+@top Nettle
+
+This document describes the Nettle low-level cryptographic library. You
+can use the library directly from your C programs, or write or use an
+object-oriented wrapper for your favorite language or application.
+
+@insertcopying
+
+@menu
+* Introduction::                What is Nettle?
+* Copyright::                   Your rights.
+* Conventions::                 General interface conventions.
+* Example::                     An example program.
+* Linking::                     Linking with the libnettle and libhogweed.
+* Reference::                   All Nettle functions and features.
+* Nettle soup::                 For the serious nettle hacker.
+* Installation::                How to install Nettle.
+* Index::                       Function and concept index.
+
+@detailmenu
+ --- The Detailed Node Listing ---
+
+Reference
+
+* Hash functions::              
+* Cipher functions::            
+* Cipher modes::                
+* Keyed hash functions::        
+* Public-key algorithms::       
+* Randomness::                  
+* Miscellaneous functions::     
+* Compatibility functions::     
+
+Cipher modes
+
+* CBC::                         
+* CTR::                         
+* GCM::                         
+
+Public-key algorithms
+
+* RSA::                         The RSA public key algorithm.
+* DSA::                         The DSA digital signature algorithm.
+
+@end detailmenu
+@end menu
+
+@end ifnottex
+
+@node Introduction, Copyright, Top, Top
+@comment  node-name,  next,  previous,  up
+@chapter Introduction
+
+Nettle is a cryptographic library that is designed to fit easily in more
+or less any context: In crypto toolkits for object-oriented languages
+(C++, Python, Pike, ...), in applications like LSH or GNUPG, or even in
+kernel space. In most contexts, you need more than the basic
+cryptographic algorithms, you also need some way to keep track of available
+algorithms, their properties and variants. You often have some algorithm
+selection process, often dictated by a protocol you want to implement.
+
+And as the requirements of applications differ in subtle and not so
+subtle ways, an API that fits one application well can be a pain to use
+in a different context. And that is why there are so many different
+cryptographic libraries around.
+
+Nettle tries to avoid this problem by doing one thing, the low-level
+crypto stuff, and providing a @emph{simple} but general interface to it.
+In particular, Nettle doesn't do algorithm selection. It doesn't do
+memory allocation. It doesn't do any I/O.
+
+The idea is that one can build several application and context specific
+interfaces on top of Nettle, and share the code, test cases, benchmarks,
+documentation, etc. Examples are the Nettle module for the Pike
+language, and LSH, which both use an object-oriented abstraction on top
+of the library.
+
+This manual explains how to use the Nettle library. It also tries to
+provide some background on the cryptography, and advice on how to best
+put it to use.
+
+@node Copyright, Conventions, Introduction, Top
+@comment  node-name,  next,  previous,  up
+@chapter Copyright
+
+Nettle is distributed under the GNU Lesser General Public License
+(LGPL), see the file COPYING.LIB for details. A few of the individual
+files are in the public domain. To find the current status of particular
+files, you have to read the copyright notices at the top of the files.
+
+This manual is in the public domain. You may freely copy it in whole or
+in part, e.g., into documentation of programs that build on Nettle.
+Attribution, as well as contribution of improvements to the text, is of
+course appreciated, but it is not required.
+
+A list of the supported algorithms, their origins and licenses:
+
+@table @emph
+@item AES
+The implementation of the AES cipher (also known as rijndael) is written
+by Rafael Sevilla. Assembler for x86 by Rafael Sevilla and
+@value{AUTHOR}, Sparc assembler by @value{AUTHOR}. Released under the
+LGPL.
+
+@item ARCFOUR
+The implementation of the ARCFOUR (also known as RC4) cipher is written
+by @value{AUTHOR}. Released under the LGPL.
+
+@item ARCTWO
+The implementation of the ARCTWO (also known as RC2) cipher is written
+by Nikos Mavroyanopoulos and modified by Werner Koch and Simon
+Josefsson. Released under the LGPL.
+
+@item BLOWFISH
+The implementation of the BLOWFISH cipher is written by Werner Koch,
+copyright owned by the Free Software Foundation. Also hacked by Simon
+Josefsson and Niels Möller. Released under the LGPL.
+
+@item CAMELLIA
+The C implementation is by Nippon Telegraph and Telephone Corporation
+(NTT), heavily modified by @value{AUTHOR}. Assembler for x86 and x86_64
+by @value{AUTHOR}. Released under the LGPL.
+
+@item CAST128
+The implementation of the CAST128 cipher is written by Steve Reid.
+Released into the public domain.
+
+@item DES
+The implementation of the DES cipher is written by Dana L. How, and
+released under the LGPL.
+
+@item MD2
+The implementation of MD2 is written by Andrew Kuchling, and hacked
+some by Andreas Sigfridsson and @value{AUTHOR}. Python Cryptography
+Toolkit license (essentially public domain).
+
+@item MD4
+This is almost the same code as for MD5 below, with modifications by
+Marcus Comstedt. Released into the public domain.
+
+@item MD5
+The implementation of the MD5 message digest is written by Colin Plumb.
+It has been hacked some more by Andrew Kuchling and @value{AUTHOR}.
+Released into the public domain.
+
+@item RIPMED160
+The implementation of RIPEMD160 message digest is based on the code in
+libgcrypt, copyright owned by the Free Software Foundation. Ported to
+Nettle by Andres Mejia. Released under the LGPL.
+
+@item SERPENT
+The implementation of the SERPENT cipher is based on the code in libgcrypt,
+copyright owned by the Free Software Foundation. Adapted to Nettle by
+Simon Josefsson and heavily modified by Niels Möller. Assembly for
+x86_64 by Niels Möller. Released under the LGPL.
+
+@item SHA1
+The C implementation of the SHA1 message digest is written by Peter
+Gutmann, and hacked some more by Andrew Kuchling and @value{AUTHOR}.
+Released into the public domain. Assembler for x86 by @value{AUTHOR},
+released under the LGPL.
+
+@item SHA224, SHA256, SHA384, and SHA512
+Written by @value{AUTHOR}, using Peter Gutmann's SHA1 code as a model. 
+Released under the LGPL.
+
+@item TWOFISH
+The implementation of the TWOFISH cipher is written by Ruud de Rooij.
+Released under the LGPL.
+
+@item RSA
+Written by @value{AUTHOR}, released under the LGPL. Uses the GMP library
+for bignum operations.
+
+@item DSA
+Written by @value{AUTHOR}, released under the LGPL. Uses the GMP library
+for bignum operations.
+@end table
+
+@node Conventions, Example, Copyright, Top
+@comment  node-name,  next,  previous,  up
+@chapter Conventions
+
+For each supported algorithm, there is an include file that defines a
+@emph{context struct}, a few constants, and declares functions for
+operating on the context. The context struct encapsulates all information
+needed by the algorithm, and it can be copied or moved in memory with no
+unexpected effects.
+
+For consistency, functions for different algorithms are very similar,
+but there are some differences, for instance reflecting if the key setup
+or encryption function differ for encryption and decryption, and whether
+or not key setup can fail. There are also differences between algorithms
+that don't show in function prototypes, but which the application must
+nevertheless be aware of. There is no big difference between the
+functions for stream ciphers and for block ciphers, although they should
+be used quite differently by the application.
+
+If your application uses more than one algorithm of the same type, you
+should probably create an interface that is tailor-made for your needs,
+and then write a few lines of glue code on top of Nettle.
+
+By convention, for an algorithm named @code{foo}, the struct tag for the
+context struct is @code{foo_ctx}, constants and functions uses prefixes
+like @code{FOO_BLOCK_SIZE} (a constant) and @code{foo_set_key} (a
+function).
+
+In all functions, strings are represented with an explicit length, of
+type @code{unsigned}, and a pointer of type @code{uint8_t *} or
+@code{const uint8_t *}. For functions that transform one string to
+another, the argument order is length, destination pointer and source
+pointer. Source and destination areas are of the same length. Source and
+destination may be the same, so that you can process strings in place,
+but they @emph{must not} overlap in any other way.
+
+Many of the functions lack return value and can never fail. Those
+functions which can fail, return one on success and zero on failure.
+
+@c FIXME: Say something about the name mangling.
+
+@node Example, Linking, Conventions, Top
+@comment  node-name,  next,  previous,  up
+@chapter Example
+
+A simple example program that reads a file from standard input and
+writes its SHA1 checksum on standard output should give the flavor of
+Nettle.
+
+@example
+@verbatiminclude sha-example.c
+@end example
+
+On a typical Unix system, this program can be compiled and linked with
+the command line 
+@example
+cc sha-example.c -o sha-example -lnettle
+@end example
+
+@node Linking, Reference, Example, Top
+@comment  node-name,  next,  previous,  up
+@chapter Linking
+
+Nettle actually consists of two libraries, @file{libnettle} and
+@file{libhogweed}. The @file{libhogweed} library contains those
+functions of Nettle that uses bignum operations, and depends on the GMP
+library. With this division, linking works the same for both static and
+dynamic libraries.
+
+If an application uses only the symmetric crypto algorithms of Nettle
+(i.e., block ciphers, hash functions, and the like), it's sufficient to
+link with @code{-lnettle}. If an application also uses public-key
+algorithms, the recommended linker flags are @code{-lhogweed -lnettle
+-lgmp}. If the involved libraries are installed as dynamic libraries, it
+may be sufficient to link with just @code{-lhogweed}, and the loader
+will resolve the dependencies automatically.
+
+@node Reference, Nettle soup, Linking, Top
+@comment  node-name,  next,  previous,  up
+@chapter Reference
+
+This chapter describes all the Nettle functions, grouped by family.
+
+@menu
+* Hash functions::              
+* Cipher functions::            
+* Cipher modes::                
+* Keyed hash functions::        
+* Public-key algorithms::       
+* Randomness::                  
+* Miscellaneous functions::     
+* Compatibility functions::     
+@end menu
+
+@node Hash functions, Cipher functions, Reference, Reference
+@comment  node-name,  next,  previous,  up
+@section Hash functions
+@cindex Hash function
+A cryptographic @dfn{hash function} is a function that takes variable
+size strings, and maps them to strings of fixed, short, length. There
+are naturally lots of collisions, as there are more possible 1MB files
+than 20 byte strings. But the function is constructed such that is hard
+to find the collisions. More precisely, a cryptographic hash function
+@code{H} should have the following properties:
+
+@table @emph
+
+@item One-way
+@cindex One-way
+Given a hash value @code{H(x)} it is hard to find a string @code{x}
+that hashes to that value.
+
+@item Collision-resistant
+@cindex Collision-resistant
+It is hard to find two different strings, @code{x} and @code{y}, such
+that @code{H(x)} = @code{H(y)}.
+
+@end table
+
+Hash functions are useful as building blocks for digital signatures,
+message authentication codes, pseudo random generators, association of
+unique ids to documents, and many other things.
+
+The most commonly used hash functions are MD5 and SHA1. Unfortunately,
+both these fail the collision-resistance requirement; cryptologists have
+found ways to construct colliding inputs. The recommended hash function
+for new applications is SHA256, even though it uses a structure similar
+to MD5 and SHA1. Constructing better hash functions is an urgent research
+problem.
+
+@subsection @acronym{MD5}
+
+MD5 is a message digest function constructed by Ronald Rivest, and
+described in @cite{RFC 1321}. It outputs message digests of 128 bits, or
+16 octets. Nettle defines MD5 in @file{<nettle/md5.h>}.
+
+@deftp {Context struct} {struct md5_ctx}
+@end deftp
+
+@defvr Constant MD5_DIGEST_SIZE
+The size of an MD5 digest, i.e. 16.
+@end defvr
+
+@defvr Constant MD5_DATA_SIZE
+The internal block size of MD5. Useful for some special constructions,
+in particular HMAC-MD5.
+@end defvr
+
+@deftypefun void md5_init (struct md5_ctx *@var{ctx})
+Initialize the MD5 state.
+@end deftypefun
+
+@deftypefun void md5_update (struct md5_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data})
+Hash some more data.
+@end deftypefun
+
+@deftypefun void md5_digest (struct md5_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest})
+Performs final processing and extracts the message digest, writing it
+to @var{digest}. @var{length} may be smaller than
+@code{MD5_DIGEST_SIZE}, in which case only the first @var{length}
+octets of the digest are written.
+
+This function also resets the context in the same way as
+@code{md5_init}.
+@end deftypefun
+
+The normal way to use MD5 is to call the functions in order: First
+@code{md5_init}, then @code{md5_update} zero or more times, and finally
+@code{md5_digest}. After @code{md5_digest}, the context is reset to
+its initial state, so you can start over calling @code{md5_update} to
+hash new data.
+
+To start over, you can call @code{md5_init} at any time.
+
+@subsection @acronym{MD2}
+
+MD2 is another hash function of Ronald Rivest's, described in
+@cite{RFC 1319}. It outputs message digests of 128 bits, or 16 octets.
+Nettle defines MD2 in @file{<nettle/md2.h>}.
+
+@deftp {Context struct} {struct md2_ctx}
+@end deftp
+
+@defvr Constant MD2_DIGEST_SIZE
+The size of an MD2 digest, i.e. 16.
+@end defvr
+
+@defvr Constant MD2_DATA_SIZE
+The internal block size of MD2.
+@end defvr
+
+@deftypefun void md2_init (struct md2_ctx *@var{ctx})
+Initialize the MD2 state.
+@end deftypefun
+
+@deftypefun void md2_update (struct md2_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data})
+Hash some more data.
+@end deftypefun
+
+@deftypefun void md2_digest (struct md2_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest})
+Performs final processing and extracts the message digest, writing it
+to @var{digest}. @var{length} may be smaller than
+@code{MD2_DIGEST_SIZE}, in which case only the first @var{length}
+octets of the digest are written.
+
+This function also resets the context in the same way as
+@code{md2_init}.
+@end deftypefun
+
+@subsection @acronym{MD4}
+
+MD4 is a predecessor of MD5, described in @cite{RFC 1320}. Like MD5, it
+is constructed by Ronald Rivest. It outputs message digests of 128 bits,
+or 16 octets. Nettle defines MD4 in @file{<nettle/md4.h>}. Use of MD4 is
+not recommended, but it is sometimes needed for compatibility with
+existing applications and protocols.
+
+@deftp {Context struct} {struct md4_ctx}
+@end deftp
+
+@defvr Constant MD4_DIGEST_SIZE
+The size of an MD4 digest, i.e. 16.
+@end defvr
+
+@defvr Constant MD4_DATA_SIZE
+The internal block size of MD4.
+@end defvr
+
+@deftypefun void md4_init (struct md4_ctx *@var{ctx})
+Initialize the MD4 state.
+@end deftypefun
+
+@deftypefun void md4_update (struct md4_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data})
+Hash some more data.
+@end deftypefun
+
+@deftypefun void md4_digest (struct md4_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest})
+Performs final processing and extracts the message digest, writing it
+to @var{digest}. @var{length} may be smaller than
+@code{MD4_DIGEST_SIZE}, in which case only the first @var{length}
+octets of the digest are written.
+
+This function also resets the context in the same way as
+@code{md4_init}.
+@end deftypefun
+
+@subsection @acronym{RIPEMD160}
+
+RIPEMD160 is a hash function designed by Hans Dobbertin, Antoon
+Bosselaers, and Bart Preneel, as a strengthened version of RIPEMD
+(which, like MD4 and MD5, fails the collision-resistance requirement).
+It produces message digests of 160 bits, or 20 octets. Nettle defined
+RIPEMD160 in @file{nettle/ripemd160.h}.
+
+@deftp {Context struct} {struct ripemd160_ctx}
+@end deftp
+
+@defvr Constant RIPEMD160_DIGEST_SIZE
+The size of an RIPEMD160 digest, i.e. 20.
+@end defvr
+
+@defvr Constant RIPEMD160_DATA_SIZE
+The internal block size of RIPEMD160.
+@end defvr
+
+@deftypefun void ripemd160_init (struct ripemd160_ctx *@var{ctx})
+Initialize the RIPEMD160 state.
+@end deftypefun
+
+@deftypefun void ripemd160_update (struct ripemd160_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data})
+Hash some more data.
+@end deftypefun
+
+@deftypefun void ripemd160_digest (struct ripemd160_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest})
+Performs final processing and extracts the message digest, writing it
+to @var{digest}. @var{length} may be smaller than
+@code{RIPEMD160_DIGEST_SIZE}, in which case only the first @var{length}
+octets of the digest are written.
+
+This function also resets the context in the same way as
+@code{ripemd160_init}.
+@end deftypefun
+
+@subsection @acronym{SHA1}
+
+SHA1 is a hash function specified by @dfn{NIST} (The U.S. National Institute
+for Standards and Technology). It outputs hash values of 160 bits, or 20
+octets. Nettle defines SHA1 in @file{<nettle/sha.h>}.
+
+The functions are analogous to the MD5 ones.
+
+@deftp {Context struct} {struct sha1_ctx}
+@end deftp
+
+@defvr Constant SHA1_DIGEST_SIZE
+The size of an SHA1 digest, i.e. 20.
+@end defvr
+
+@defvr Constant SHA1_DATA_SIZE
+The internal block size of SHA1. Useful for some special constructions,
+in particular HMAC-SHA1.
+@end defvr
+
+@deftypefun void sha1_init (struct sha1_ctx *@var{ctx})
+Initialize the SHA1 state.
+@end deftypefun
+
+@deftypefun void sha1_update (struct sha1_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data})
+Hash some more data.
+@end deftypefun
+
+@deftypefun void sha1_digest (struct sha1_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest})
+Performs final processing and extracts the message digest, writing it
+to @var{digest}. @var{length} may be smaller than
+@code{SHA1_DIGEST_SIZE}, in which case only the first @var{length}
+octets of the digest are written.
+
+This function also resets the context in the same way as
+@code{sha1_init}.
+@end deftypefun
+
+@subsection @acronym{SHA256}
+
+SHA256 is another hash function specified by @dfn{NIST}, intended as a
+replacement for @acronym{SHA1}, generating larger digests. It outputs
+hash values of 256 bits, or 32 octets. Nettle defines SHA256 in
+@file{<nettle/sha.h>}.
+
+The functions are analogous to the MD5 ones.
+
+@deftp {Context struct} {struct sha256_ctx}
+@end deftp
+
+@defvr Constant SHA256_DIGEST_SIZE
+The size of an SHA256 digest, i.e. 32.
+@end defvr
+
+@defvr Constant SHA256_DATA_SIZE
+The internal block size of SHA256. Useful for some special constructions,
+in particular HMAC-SHA256.
+@end defvr
+
+@deftypefun void sha256_init (struct sha256_ctx *@var{ctx})
+Initialize the SHA256 state.
+@end deftypefun
+
+@deftypefun void sha256_update (struct sha256_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data})
+Hash some more data.
+@end deftypefun
+
+@deftypefun void sha256_digest (struct sha256_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest})
+Performs final processing and extracts the message digest, writing it
+to @var{digest}. @var{length} may be smaller than
+@code{SHA256_DIGEST_SIZE}, in which case only the first @var{length}
+octets of the digest are written.
+
+This function also resets the context in the same way as
+@code{sha256_init}.
+@end deftypefun
+
+@subsection @acronym{SHA224}
+
+SHA224 is a variant of SHA256, with a different initial state, and with
+the output truncated to 224 bits, or 28 octets. Nettle defines SHA224 in
+@file{<nettle/sha.h>}.
+
+The functions are analogous to the MD5 ones.
+
+@deftp {Context struct} {struct sha224_ctx}
+@end deftp
+
+@defvr Constant SHA224_DIGEST_SIZE
+The size of an SHA224 digest, i.e. 28.
+@end defvr
+
+@defvr Constant SHA224_DATA_SIZE
+The internal block size of SHA224. Useful for some special constructions,
+in particular HMAC-SHA224.
+@end defvr
+
+@deftypefun void sha224_init (struct sha224_ctx *@var{ctx})
+Initialize the SHA224 state.
+@end deftypefun
+
+@deftypefun void sha224_update (struct sha224_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data})
+Hash some more data.
+@end deftypefun
+
+@deftypefun void sha224_digest (struct sha224_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest})
+Performs final processing and extracts the message digest, writing it
+to @var{digest}. @var{length} may be smaller than
+@code{SHA224_DIGEST_SIZE}, in which case only the first @var{length}
+octets of the digest are written.
+
+This function also resets the context in the same way as
+@code{sha224_init}.
+@end deftypefun
+
+@subsection @acronym{SHA512}
+
+SHA512 is a larger sibling to SHA256, with a very similar structure but
+with both the output and the internal variables of twice the size. The
+internal variables are 64 bits rather than 32, making it significantly
+slower on 32-bit computers. It outputs hash values of 512 bits, or 64
+octets. Nettle defines SHA512 in @file{<nettle/sha.h>}.
+
+The functions are analogous to the MD5 ones.
+
+@deftp {Context struct} {struct sha512_ctx}
+@end deftp
+
+@defvr Constant SHA512_DIGEST_SIZE
+The size of an SHA512 digest, i.e. 64.
+@end defvr
+
+@defvr Constant SHA512_DATA_SIZE
+The internal block size of SHA512. Useful for some special constructions,
+in particular HMAC-SHA512.
+@end defvr
+
+@deftypefun void sha512_init (struct sha512_ctx *@var{ctx})
+Initialize the SHA512 state.
+@end deftypefun
+
+@deftypefun void sha512_update (struct sha512_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data})
+Hash some more data.
+@end deftypefun
+
+@deftypefun void sha512_digest (struct sha512_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest})
+Performs final processing and extracts the message digest, writing it
+to @var{digest}. @var{length} may be smaller than
+@code{SHA512_DIGEST_SIZE}, in which case only the first @var{length}
+octets of the digest are written.
+
+This function also resets the context in the same way as
+@code{sha512_init}.
+@end deftypefun
+
+@subsection @acronym{SHA384}
+
+SHA384 is a variant of SHA512, with a different initial state, and with
+the output truncated to 384 bits, or 48 octets. Nettle defines SHA384 in
+@file{<nettle/sha.h>}.
+
+The functions are analogous to the MD5 ones.
+
+@deftp {Context struct} {struct sha384_ctx}
+@end deftp
+
+@defvr Constant SHA384_DIGEST_SIZE
+The size of an SHA384 digest, i.e. 48.
+@end defvr
+
+@defvr Constant SHA384_DATA_SIZE
+The internal block size of SHA384. Useful for some special constructions,
+in particular HMAC-SHA384.
+@end defvr
+
+@deftypefun void sha384_init (struct sha384_ctx *@var{ctx})
+Initialize the SHA384 state.
+@end deftypefun
+
+@deftypefun void sha384_update (struct sha384_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data})
+Hash some more data.
+@end deftypefun
+
+@deftypefun void sha384_digest (struct sha384_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest})
+Performs final processing and extracts the message digest, writing it
+to @var{digest}. @var{length} may be smaller than
+@code{SHA384_DIGEST_SIZE}, in which case only the first @var{length}
+octets of the digest are written.
+
+This function also resets the context in the same way as
+@code{sha384_init}.
+@end deftypefun
+
+@subsection @code{struct nettle_hash}
+
+Nettle includes a struct including information about the supported hash
+functions. It is defined in @file{<nettle/nettle-meta.h>}, and is used
+by Nettle's implementation of @acronym{HMAC} (@pxref{Keyed hash
+functions}).
+
+@deftp {Meta struct} @code{struct nettle_hash} name context_size digest_size block_size init update digest
+The last three attributes are function pointers, of types
+@code{nettle_hash_init_func}, @code{nettle_hash_update_func}, and
+@code{nettle_hash_digest_func}. The first argument to these functions is
+@code{void *} pointer to a context struct, which is of size
+@code{context_size}. 
+@end deftp
+
+@deftypevr {Constant Struct} {struct nettle_hash} nettle_md2
+@deftypevrx {Constant Struct} {struct nettle_hash} nettle_md4
+@deftypevrx {Constant Struct} {struct nettle_hash} nettle_md5
+@deftypevrx {Constant Struct} {struct nettle_hash} nettle_ripemd160
+@deftypevrx {Constant Struct} {struct nettle_hash} nettle_sha1
+@deftypevrx {Constant Struct} {struct nettle_hash} nettle_sha224
+@deftypevrx {Constant Struct} {struct nettle_hash} nettle_sha256
+@deftypevrx {Constant Struct} {struct nettle_hash} nettle_sha384
+@deftypevrx {Constant Struct} {struct nettle_hash} nettle_sha512
+
+These are all the hash functions that Nettle implements.
+
+Nettle also exports a list of all these hashes.  This list can be used
+to dynamically enumerate or search the supported algorithms:
+
+@deftypevrx {Constant Struct} {struct nettle_hash **} nettle_hashes
+
+@end deftypevr
+
+@node Cipher functions, Cipher modes, Hash functions, Reference
+@comment  node-name,  next,  previous,  up
+@section Cipher functions
+@cindex Cipher
+
+A @dfn{cipher} is a function that takes a message or @dfn{plaintext}
+and a secret @dfn{key} and transforms it to a @dfn{ciphertext}. Given
+only the ciphertext, but not the key, it should be hard to find the
+plaintext. Given matching pairs of plaintext and ciphertext, it should
+be hard to find the key.
+
+@cindex Block Cipher
+@cindex Stream Cipher
+
+There are two main classes of ciphers: Block ciphers and stream ciphers.
+
+A block cipher can process data only in fixed size chunks, called
+@dfn{blocks}. Typical block sizes are 8 or 16 octets. To encrypt
+arbitrary messages, you usually have to pad it to an integral number of
+blocks, split it into blocks, and then process each block. The simplest
+way is to process one block at a time, independent of each other. That
+mode of operation is called @dfn{ECB}, Electronic Code Book mode.
+However, using @acronym{ECB} is usually a bad idea. For a start, plaintext blocks
+that are equal are transformed to ciphertext blocks that are equal; that
+leaks information about the plaintext. Usually you should apply the
+cipher is some ``feedback mode'', @dfn{CBC} (Cipher Block Chaining) and
+@dfn{CTR} (Counter mode) being two of
+of the most popular. See @xref{Cipher modes}, for information on
+how to apply @acronym{CBC} and @acronym{CTR} with Nettle.
+
+A stream cipher can be used for messages of arbitrary length. A typical
+stream cipher is a keyed pseudo-random generator. To encrypt a plaintext
+message of @var{n} octets, you key the generator, generate @var{n}
+octets of pseudo-random data, and XOR it with the plaintext. To decrypt,
+regenerate the same stream using the key, XOR it to the ciphertext, and
+the plaintext is recovered.
+
+@strong{Caution:} The first rule for this kind of cipher is the
+same as for a One Time Pad: @emph{never} ever use the same key twice.
+
+A common misconception is that encryption, by itself, implies
+authentication. Say that you and a friend share a secret key, and you
+receive an encrypted message. You apply the key, and get a plaintext
+message that makes sense to you. Can you then be sure that it really was
+your friend that wrote the message you're reading? The answer is no. For
+example, if you were using a block cipher in ECB mode, an attacker may
+pick up the message on its way, and reorder, delete or repeat some of
+the blocks. Even if the attacker can't decrypt the message, he can
+change it so that you are not reading the same message as your friend
+wrote. If you are using a block cipher in @acronym{CBC} mode rather than
+ECB, or are using a stream cipher, the possibilities for this sort of
+attack are different, but the attacker can still make predictable
+changes to the message.
+
+It is recommended to @emph{always} use an authentication mechanism in
+addition to encrypting the messages. Popular choices are Message
+Authentication Codes like @acronym{HMAC-SHA1} (@pxref{Keyed hash
+functions}), or digital signatures like @acronym{RSA}.
+
+Some ciphers have so called ``weak keys'', keys that results in
+undesirable structure after the key setup processing, and should be
+avoided. In Nettle, most key setup functions have no return value, but
+for ciphers with weak keys, the return value indicates whether or not
+the given key is weak. For good keys, key setup returns 1, and for weak
+keys, it returns 0. When possible, avoid algorithms that
+have weak keys. There are several good ciphers that don't have any weak
+keys.
+
+To encrypt a message, you first initialize a cipher context for
+encryption or decryption with a particular key. You then use the context
+to process plaintext or ciphertext messages. The initialization is known
+as @dfn{key setup}. With Nettle, it is recommended to use each
+context struct for only one direction, even if some of the ciphers use a
+single key setup function that can be used for both encryption and
+decryption.
+
+@subsection AES
+AES is a block cipher, specified by NIST as a replacement for
+the older DES standard. The standard is the result of a competition
+between cipher designers. The winning design, also known as RIJNDAEL,
+was constructed by Joan Daemen and Vincent Rijnmen.
+
+Like all the AES candidates, the winning design uses a block size of 128
+bits, or 16 octets, and variable key-size, 128, 192 and 256 bits (16, 24
+and 32 octets) being the allowed key sizes. It does not have any weak
+keys. Nettle defines AES in @file{<nettle/aes.h>}.
+@deftp {Context struct} {struct aes_ctx}
+@end deftp
+
+@defvr Constant AES_BLOCK_SIZE
+The AES block-size, 16
+@end defvr
+
+@defvr Constant AES_MIN_KEY_SIZE
+@end defvr
+
+@defvr Constant AES_MAX_KEY_SIZE
+@end defvr
+
+@defvr Constant AES_KEY_SIZE
+Default AES key size, 32
+@end defvr
+
+@deftypefun void aes_set_encrypt_key (struct aes_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key})
+@deftypefunx void aes_set_decrypt_key (struct aes_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key})
+Initialize the cipher, for encryption or decryption, respectively.
+@end deftypefun
+
+@deftypefun void aes_invert_key (struct aes_ctx *@var{dst}, const struct aes_ctx *@var{src})
+Given a context @var{src} initialized for encryption, initializes the
+context struct @var{dst} for decryption, using the same key. If the same
+context struct is passed for both @code{src} and @code{dst}, it is
+converted in place. Calling @code{aes_set_encrypt_key} and
+@code{aes_invert_key} is more efficient than calling
+@code{aes_set_encrypt_key} and @code{aes_set_decrypt_key}. This function
+is mainly useful for applications which needs to both encrypt and
+decrypt using the @emph{same} key.
+@end deftypefun
+
+@deftypefun void aes_encrypt (struct aes_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Encryption function. @var{length} must be an integral multiple of the
+block size. If it is more than one block, the data is processed in ECB
+mode. @code{src} and @code{dst} may be equal, but they must not overlap
+in any other way.
+@end deftypefun
+
+@deftypefun void aes_decrypt (struct aes_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Analogous to @code{aes_encrypt}
+@end deftypefun
+
+@subsection ARCFOUR
+ARCFOUR is a stream cipher, also known under the trade marked name RC4,
+and it is one of the fastest ciphers around. A problem is that the key
+setup of ARCFOUR is quite weak, you should never use keys with
+structure, keys that are ordinary passwords, or sequences of keys like
+``secret:1'', ``secret:2'', @enddots{}. If you have keys that don't look
+like random bit strings, and you want to use ARCFOUR, always hash the
+key before feeding it to ARCFOUR. Furthermore, the initial bytes of the
+generated key stream leak information about the key; for this reason, it
+is recommended to discard the first 512 bytes of the key stream.
+
+@example
+/* A more robust key setup function for ARCFOUR */
+void
+arcfour_set_key_hashed(struct arcfour_ctx *ctx,
+                       unsigned length, const uint8_t *key)
+@{
+  struct sha256_ctx hash;
+  uint8_t digest[SHA256_DIGEST_SIZE];
+  uint8_t buffer[0x200];
+
+  sha256_init(&hash);
+  sha256_update(&hash, length, key);
+  sha256_digest(&hash, SHA256_DIGEST_SIZE, digest);
+
+  arcfour_set_key(ctx, SHA256_DIGEST_SIZE, digest);
+  arcfour_crypt(ctx, sizeof(buffer), buffer, buffer);
+@}
+@end example
+
+Nettle defines ARCFOUR in @file{<nettle/arcfour.h>}.
+
+@deftp {Context struct} {struct arcfour_ctx}
+@end deftp
+
+@defvr Constant ARCFOUR_MIN_KEY_SIZE
+Minimum key size, 1
+@end defvr
+
+@defvr Constant ARCFOUR_MAX_KEY_SIZE
+Maximum key size, 256
+@end defvr
+
+@defvr Constant ARCFOUR_KEY_SIZE
+Default ARCFOUR key size, 16
+@end defvr
+
+@deftypefun void arcfour_set_key (struct arcfour_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key})
+Initialize the cipher. The same function is used for both encryption and
+decryption. 
+@end deftypefun
+
+@deftypefun void arcfour_crypt (struct arcfour_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Encrypt some data. The same function is used for both encryption and
+decryption. Unlike the block ciphers, this function modifies the
+context, so you can split the data into arbitrary chunks and encrypt
+them one after another. The result is the same as if you had called
+@code{arcfour_crypt} only once with all the data.
+@end deftypefun
+
+@subsection ARCTWO
+ARCTWO (also known as the trade marked name RC2) is a block cipher
+specified in RFC 2268. Nettle also include a variation of the ARCTWO
+set key operation that lack one step, to be compatible with the
+reverse engineered RC2 cipher description, as described in a Usenet
+post to @code{sci.crypt} by Peter Gutmann.
+
+ARCTWO uses a block size of 64 bits, and variable key-size ranging
+from 1 to 128 octets. Besides the key, ARCTWO also has a second
+parameter to key setup, the number of effective key bits, @code{ekb}.
+This parameter can be used to artificially reduce the key size. In
+practice, @code{ekb} is usually set equal to the input key size.
+Nettle defines ARCTWO in @file{<nettle/arctwo.h>}.
+
+We do not recommend the use of ARCTWO; the Nettle implementation is
+provided primarily for interoperability with existing applications and
+standards.
+
+@deftp {Context struct} {struct arctwo_ctx}
+@end deftp
+
+@defvr Constant ARCTWO_BLOCK_SIZE
+The ARCTWO block-size, 8
+@end defvr
+
+@defvr Constant ARCTWO_MIN_KEY_SIZE
+@end defvr
+
+@defvr Constant ARCTWO_MAX_KEY_SIZE
+@end defvr
+
+@defvr Constant ARCTWO_KEY_SIZE
+Default ARCTWO key size, 8
+@end defvr
+
+@deftypefun void arctwo_set_key_ekb (struct arctwo_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key}, unsigned @var{ekb})
+@deftypefunx void arctwo_set_key (struct arctwo_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key})
+@deftypefunx void arctwo_set_key_gutmann (struct arctwo_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key})
+Initialize the cipher. The same function is used for both encryption
+and decryption. The first function is the most general one, which lets
+you provide both the variable size key, and the desired effective key
+size (in bits). The maximum value for @var{ekb} is 1024, and for
+convenience, @code{ekb = 0} has the same effect as @code{ekb = 1024}.
+
+@code{arctwo_set_key(ctx, length, key)} is equivalent to
+@code{arctwo_set_key_ekb(ctx, length, key, 8*length)}, and
+@code{arctwo_set_key_gutmann(ctx, length, key)} is equivalent to
+@code{arctwo_set_key_ekb(ctx, length, key, 1024)}
+@end deftypefun
+
+@deftypefun void arctwo_encrypt (struct arctwo_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Encryption function. @var{length} must be an integral multiple of the
+block size. If it is more than one block, the data is processed in ECB
+mode. @code{src} and @code{dst} may be equal, but they must not
+overlap in any other way.
+@end deftypefun
+
+@deftypefun void arctwo_decrypt (struct arctwo_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Analogous to @code{arctwo_encrypt}
+@end deftypefun
+
+@subsection BLOWFISH
+
+BLOWFISH is a block cipher designed by Bruce Schneier. It uses a block
+size of 64 bits (8 octets), and a variable key size, up to 448 bits. It
+has some weak keys. Nettle defines BLOWFISH in @file{<nettle/blowfish.h>}.
+
+@deftp {Context struct} {struct blowfish_ctx}
+@end deftp
+
+@defvr Constant BLOWFISH_BLOCK_SIZE
+The BLOWFISH block-size, 8
+@end defvr
+
+@defvr Constant BLOWFISH_MIN_KEY_SIZE
+Minimum BLOWFISH key size, 8
+@end defvr
+
+@defvr Constant BLOWFISH_MAX_KEY_SIZE
+Maximum BLOWFISH key size, 56
+@end defvr
+
+@defvr Constant BLOWFISH_KEY_SIZE
+Default BLOWFISH key size, 16
+@end defvr
+
+@deftypefun int blowfish_set_key (struct blowfish_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key})
+Initialize the cipher. The same function is used for both encryption and
+decryption. Checks for weak keys, returning 1
+for good keys and 0 for weak keys. Applications that don't care about
+weak keys can ignore the return value.
+
+@code{blowfish_encrypt} or @code{blowfish_decrypt} with a weak key will
+crash with an assert violation.
+@end deftypefun
+
+@deftypefun void blowfish_encrypt (struct blowfish_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Encryption function. @var{length} must be an integral multiple of the
+block size. If it is more than one block, the data is processed in ECB
+mode. @code{src} and @code{dst} may be equal, but they must not overlap
+in any other way.
+@end deftypefun
+
+@deftypefun void blowfish_decrypt (struct blowfish_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Analogous to @code{blowfish_encrypt}
+@end deftypefun
+
+@subsection Camellia
+
+Camellia is a block cipher developed by Mitsubishi and Nippon Telegraph
+and Telephone Corporation, described in @cite{RFC3713}, and recommended
+by some Japanese and European authorities as an alternative to AES. The
+algorithm is patented. The implementation in Nettle is derived from the
+implementation released by NTT under the GNU LGPL (v2.1 or later), and
+relies on the implicit patent license of the LGPL. There is also a
+statement of royalty-free licensing for Camellia at
+@url{http://www.ntt.co.jp/news/news01e/0104/010417.html}, but this
+statement has some limitations which seem problematic for free software.
+
+Camellia uses a the same block size and key sizes as AES: The block size
+is 128 bits (16 octets), and the supported key sizes are 128, 192, and
+256 bits. Nettle defines Camellia in @file{<nettle/camellia.h>}.
+
+@deftp {Context struct} {struct camellia_ctx}
+@end deftp
+
+@defvr Constant CAMELLIA_BLOCK_SIZE
+The CAMELLIA block-size, 16
+@end defvr
+
+@defvr Constant CAMELLIA_MIN_KEY_SIZE
+@end defvr
+
+@defvr Constant CAMELLIA_MAX_KEY_SIZE
+@end defvr
+
+@defvr Constant CAMELLIA_KEY_SIZE
+Default CAMELLIA key size, 32
+@end defvr
+
+@deftypefun void camellia_set_encrypt_key (struct camellia_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key})
+@deftypefunx void camellia_set_decrypt_key (struct camellia_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key})
+Initialize the cipher, for encryption or decryption, respectively.
+@end deftypefun
+
+@deftypefun void camellia_invert_key (struct camellia_ctx *@var{dst}, const struct camellia_ctx *@var{src})
+Given a context @var{src} initialized for encryption, initializes the
+context struct @var{dst} for decryption, using the same key. If the same
+context struct is passed for both @code{src} and @code{dst}, it is
+converted in place. Calling @code{camellia_set_encrypt_key} and
+@code{camellia_invert_key} is more efficient than calling
+@code{camellia_set_encrypt_key} and @code{camellia_set_decrypt_key}. This function
+is mainly useful for applications which needs to both encrypt and
+decrypt using the @emph{same} key.
+@end deftypefun
+
+@deftypefun void camellia_crypt (struct camellia_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+The same function is used for both encryption and decryption.
+@var{length} must be an integral multiple of the block size. If it is
+more than one block, the data is processed in ECB mode. @code{src} and
+@code{dst} may be equal, but they must not overlap in any other way.
+@end deftypefun
+
+@subsection CAST128
+
+CAST-128 is a block cipher, specified in @cite{RFC 2144}. It uses a 64
+bit (8 octets) block size, and a variable key size of up to 128 bits.
+Nettle defines cast128 in @file{<nettle/cast128.h>}.
+
+@deftp {Context struct} {struct cast128_ctx}
+@end deftp
+
+@defvr Constant CAST128_BLOCK_SIZE
+The CAST128 block-size, 8
+@end defvr
+
+@defvr Constant CAST128_MIN_KEY_SIZE
+Minimum CAST128 key size, 5
+@end defvr
+
+@defvr Constant CAST128_MAX_KEY_SIZE
+Maximum CAST128 key size, 16
+@end defvr
+
+@defvr Constant CAST128_KEY_SIZE
+Default CAST128 key size, 16
+@end defvr
+
+@deftypefun void cast128_set_key (struct cast128_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key})
+Initialize the cipher. The same function is used for both encryption and
+decryption. 
+@end deftypefun
+
+@deftypefun void cast128_encrypt (struct cast128_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Encryption function. @var{length} must be an integral multiple of the
+block size. If it is more than one block, the data is processed in ECB
+mode. @code{src} and @code{dst} may be equal, but they must not overlap
+in any other way.
+@end deftypefun
+
+@deftypefun void cast128_decrypt (struct cast128_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Analogous to @code{cast128_encrypt}
+@end deftypefun
+
+@subsection DES
+DES is the old Data Encryption Standard, specified by NIST. It uses a
+block size of 64 bits (8 octets), and a key size of 56 bits. However,
+the key bits are distributed over 8 octets, where the least significant
+bit of each octet may be used for parity. A common way to use DES is to
+generate 8 random octets in some way, then set the least significant bit
+of each octet to get odd parity, and initialize DES with the resulting
+key.
+
+The key size of DES is so small that keys can be found by brute force,
+using specialized hardware or lots of ordinary work stations in
+parallel. One shouldn't be using plain DES at all today, if one uses
+DES at all one should be using ``triple DES'', see DES3 below.
+
+DES also has some weak keys. Nettle defines DES in @file{<nettle/des.h>}.
+
+@deftp {Context struct} {struct des_ctx}
+@end deftp
+
+@defvr Constant DES_BLOCK_SIZE
+The DES block-size, 8
+@end defvr
+
+@defvr Constant DES_KEY_SIZE
+DES key size, 8
+@end defvr
+
+@deftypefun int des_set_key (struct des_ctx *@var{ctx}, const uint8_t *@var{key})
+Initialize the cipher. The same function is used for both encryption and
+decryption. Parity bits are ignored. Checks for weak keys, returning 1
+for good keys and 0 for weak keys. Applications that don't care about
+weak keys can ignore the return value.
+@end deftypefun
+
+@deftypefun void des_encrypt (struct des_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Encryption function. @var{length} must be an integral multiple of the
+block size. If it is more than one block, the data is processed in ECB
+mode. @code{src} and @code{dst} may be equal, but they must not overlap
+in any other way.
+@end deftypefun
+
+@deftypefun void des_decrypt (struct des_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Analogous to @code{des_encrypt}
+@end deftypefun
+
+@deftypefun int des_check_parity (unsigned @var{length}, const uint8_t *@var{key});
+Checks that the given key has correct, odd, parity. Returns 1 for
+correct parity, and 0 for bad parity.
+@end deftypefun
+
+@deftypefun void des_fix_parity (unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Adjusts the parity bits to match DES's requirements. You need this
+function if you have created a random-looking string by a key agreement
+protocol, and want to use it as a DES key. @var{dst} and @var{src} may
+be equal.
+@end deftypefun
+
+@subsection DES3
+The inadequate key size of DES has already been mentioned. One way to
+increase the key size is to pipe together several DES boxes with
+independent keys. It turns out that using two DES ciphers is not as
+secure as one might think, even if the key size of the combination is a
+respectable 112 bits.
+
+The standard way to increase DES's key size is to use three DES boxes.
+The mode of operation is a little peculiar: the middle DES box is wired
+in the reverse direction. To encrypt a block with DES3, you encrypt it
+using the first 56 bits of the key, then @emph{decrypt} it using the
+middle 56 bits of the key, and finally encrypt it again using the last
+56 bits of the key. This is known as ``ede'' triple-DES, for
+``encrypt-decrypt-encrypt''.
+
+The ``ede'' construction provides some backward compatibility, as you get
+plain single DES simply by feeding the same key to all three boxes. That
+should help keeping down the gate count, and the price, of hardware
+circuits implementing both plain DES and DES3.
+
+DES3 has a key size of 168 bits, but just like plain DES, useless parity
+bits are inserted, so that keys are represented as 24 octets (192 bits).
+As a 112 bit key is large enough to make brute force attacks
+impractical, some applications uses a ``two-key'' variant of triple-DES.
+In this mode, the same key bits are used for the first and the last DES
+box in the pipe, while the middle box is keyed independently. The
+two-key variant is believed to be secure, i.e. there are no known
+attacks significantly better than brute force.
+
+Naturally, it's simple to implement triple-DES on top of Nettle's DES
+functions. Nettle includes an implementation of three-key ``ede''
+triple-DES, it is defined in the same place as plain DES,
+@file{<nettle/des.h>}.
+
+@deftp {Context struct} {struct des3_ctx}
+@end deftp
+
+@defvr Constant DES3_BLOCK_SIZE
+The DES3 block-size is the same as DES_BLOCK_SIZE, 8
+@end defvr
+
+@defvr Constant DES3_KEY_SIZE
+DES key size, 24
+@end defvr
+
+@deftypefun int des3_set_key (struct des3_ctx *@var{ctx}, const uint8_t *@var{key})
+Initialize the cipher. The same function is used for both encryption and
+decryption. Parity bits are ignored. Checks for weak keys, returning 1
+if all three keys are good keys, and 0 if one or more key is weak.
+Applications that don't care about weak keys can ignore the return
+value.
+@end deftypefun
+
+For random-looking strings, you can use @code{des_fix_parity} to adjust
+the parity bits before calling @code{des3_set_key}.
+
+@deftypefun void des3_encrypt (struct des3_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Encryption function. @var{length} must be an integral multiple of the
+block size. If it is more than one block, the data is processed in ECB
+mode. @code{src} and @code{dst} may be equal, but they must not overlap
+in any other way.
+@end deftypefun
+
+@deftypefun void des3_decrypt (struct des3_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Analogous to @code{des_encrypt}
+@end deftypefun
+
+@subsection SERPENT
+SERPENT is one of the AES finalists, designed by Ross Anderson, Eli
+Biham and Lars Knudsen. Thus, the interface and properties are similar
+to AES'. One peculiarity is that it is quite pointless to use it with
+anything but the maximum key size, smaller keys are just padded to
+larger ones. Nettle defines SERPENT in @file{<nettle/serpent.h>}.
+
+@deftp {Context struct} {struct serpent_ctx}
+@end deftp
+
+@defvr Constant SERPENT_BLOCK_SIZE
+The SERPENT block-size, 16
+@end defvr
+
+@defvr Constant SERPENT_MIN_KEY_SIZE
+Minimum SERPENT key size, 16
+@end defvr
+
+@defvr Constant SERPENT_MAX_KEY_SIZE
+Maximum SERPENT key size, 32
+@end defvr
+
+@defvr Constant SERPENT_KEY_SIZE
+Default SERPENT key size, 32
+@end defvr
+
+@deftypefun void serpent_set_key (struct serpent_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key})
+Initialize the cipher. The same function is used for both encryption and
+decryption. 
+@end deftypefun
+
+@deftypefun void serpent_encrypt (struct serpent_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Encryption function. @var{length} must be an integral multiple of the
+block size. If it is more than one block, the data is processed in ECB
+mode. @code{src} and @code{dst} may be equal, but they must not overlap
+in any other way.
+@end deftypefun
+
+@deftypefun void serpent_decrypt (struct serpent_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Analogous to @code{serpent_encrypt}
+@end deftypefun
+
+
+@subsection TWOFISH
+Another AES finalist, this one designed by Bruce Schneier and others.
+Nettle defines it in @file{<nettle/twofish.h>}.
+
+@deftp {Context struct} {struct twofish_ctx}
+@end deftp
+
+@defvr Constant TWOFISH_BLOCK_SIZE
+The TWOFISH block-size, 16
+@end defvr
+
+@defvr Constant TWOFISH_MIN_KEY_SIZE
+Minimum TWOFISH key size, 16
+@end defvr
+
+@defvr Constant TWOFISH_MAX_KEY_SIZE
+Maximum TWOFISH key size, 32
+@end defvr
+
+@defvr Constant TWOFISH_KEY_SIZE
+Default TWOFISH key size, 32
+@end defvr
+
+@deftypefun void twofish_set_key (struct twofish_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key})
+Initialize the cipher. The same function is used for both encryption and
+decryption. 
+@end deftypefun
+
+@deftypefun void twofish_encrypt (struct twofish_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Encryption function. @var{length} must be an integral multiple of the
+block size. If it is more than one block, the data is processed in ECB
+mode. @code{src} and @code{dst} may be equal, but they must not overlap
+in any other way.
+@end deftypefun
+
+@deftypefun void twofish_decrypt (struct twofish_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Analogous to @code{twofish_encrypt}
+@end deftypefun
+
+@c @node nettle_cipher, Cipher Block Chaining, Cipher functions, Reference
+@c @comment  node-name,  next,  previous,  up
+@subsection @code{struct nettle_cipher}
+
+Nettle includes a struct including information about some of the more
+regular cipher functions. It should be considered a little experimental,
+but can be useful for applications that need a simple way to handle
+various algorithms. Nettle defines these structs in
+@file{<nettle/nettle-meta.h>}. 
+
+@deftp {Meta struct} @code{struct nettle_cipher} name context_size block_size key_size set_encrypt_key set_decrypt_key encrypt decrypt
+The last four attributes are function pointers, of types
+@code{nettle_set_key_func} and @code{nettle_crypt_func}. The first
+argument to these functions is a @code{void *} pointer to a context
+struct, which is of size @code{context_size}.
+@end deftp
+
+@deftypevr {Constant Struct} {struct nettle_cipher} nettle_aes128
+@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_aes192
+@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_aes256
+
+@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_arctwo40;
+@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_arctwo64;
+@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_arctwo128;
+@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_arctwo_gutmann128;
+
+@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_arcfour128
+
+@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_camellia128
+@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_camellia192
+@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_camellia256
+
+@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_cast128
+
+@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_serpent128
+@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_serpent192
+@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_serpent256
+
+@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_twofish128
+@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_twofish192
+@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_twofish256
+
+Nettle includes such structs for all the @emph{regular} ciphers, i.e.
+ones without weak keys or other oddities.
+
+Nettle also exports a list of all these ciphers without weak keys or
+other oddities.  This list can be used to dynamically enumerate or
+search the supported algorithms:
+
+@deftypevrx {Constant Struct} {struct nettle_cipher **} nettle_ciphers
+
+@end deftypevr
+
+@node Cipher modes, Keyed hash functions, Cipher functions, Reference
+@comment  node-name,  next,  previous,  up
+@section Cipher modes
+
+Cipher modes of operation specifies the procedure to use when encrypting
+a message that is larger than the cipher's block size. As explained in
+@xref{Cipher functions}, splitting the message into blocks and
+processing them independently with the block cipher (Electronic Code
+Book mode, @acronym{ECB}) leaks information. Besides @acronym{ECB},
+Nettle provides three other modes of operation: Cipher Block Chaining
+(@acronym{CBC}), Counter mode (@acronym{CTR}), and Galois/Counter mode
+(@acronym{gcm}). @acronym{CBC} is widely used, but there are a few
+subtle issues of information leakage, see, e.g.,
+@uref{http://www.kb.cert.org/vuls/id/958563, @acronym{SSH} @acronym{CBC}
+vulnerability}. @acronym{CTR} and @acronym{GCM}
+were standardized more recently, and are believed to be more secure.
+@acronym{GCM} includes message authentication; for the other modes, one
+should always use a @acronym{MAC} (@pxref{Keyed hash functions}) or
+signature to authenticate the message.
+
+@menu
+* CBC::                         
+* CTR::                         
+* GCM::                         
+@end menu
+
+
+@node CBC, CTR, Cipher modes, Cipher modes
+@comment  node-name,  next,  previous,  up
+@subsection Cipher Block Chaining
+
+@cindex Cipher Block Chaining
+@cindex CBC Mode
+
+When using @acronym{CBC} mode, plaintext blocks are not encrypted
+independently of each other, like in Electronic Cook Book mode. Instead,
+when encrypting a block in @acronym{CBC} mode, the previous ciphertext
+block is XORed with the plaintext before it is fed to the block cipher.
+When encrypting the first block, a random block called an @dfn{IV}, or
+Initialization Vector, is used as the ``previous ciphertext block''. The
+IV should be chosen randomly, but it need not be kept secret, and can
+even be transmitted in the clear together with the encrypted data.
+
+In symbols, if @code{E_k} is the encryption function of a block cipher,
+and @code{IV} is the initialization vector, then @code{n} plaintext blocks
+@code{M_1},@dots{} @code{M_n} are transformed into @code{n} ciphertext blocks
+@code{C_1},@dots{} @code{C_n} as follows:
+
+@example
+C_1 = E_k(IV  XOR M_1)
+C_2 = E_k(C_1 XOR M_2)
+
+@dots{}
+
+C_n = E_k(C_(n-1) XOR M_n)
+@end example
+
+Nettle's includes two functions for applying a block cipher in Cipher
+Block Chaining (@acronym{CBC}) mode, one for encryption and one for
+decryption. These functions uses @code{void *} to pass cipher contexts
+around.
+
+@deftypefun {void} cbc_encrypt (void *@var{ctx}, nettle_crypt_func @var{f}, unsigned @var{block_size}, uint8_t *@var{iv}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+@deftypefunx {void} cbc_decrypt (void *@var{ctx}, void (*@var{f})(), unsigned @var{block_size}, uint8_t *@var{iv}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+
+Applies the encryption or decryption function @var{f} in @acronym{CBC}
+mode. The final ciphertext block processed is copied into @var{iv}
+before returning, so that large message be processed be a sequence of
+calls to @code{cbc_encrypt}. The function @var{f} is of type
+
+@code{void f (void *@var{ctx}, unsigned @var{length}, uint8_t @var{dst},
+const uint8_t *@var{src})},
+
+@noindent and the @code{cbc_encrypt} and @code{cbc_decrypt} functions pass their
+argument @var{ctx} on to @var{f}.
+@end deftypefun
+
+There are also some macros to help use these functions correctly.
+
+@deffn Macro CBC_CTX (@var{context_type}, @var{block_size})
+Expands to
+@example
+@{
+   context_type ctx;
+   uint8_t iv[block_size];
+@}
+@end example
+@end deffn
+
+It can be used to define a @acronym{CBC} context struct, either directly,
+
+@example
+struct CBC_CTX(struct aes_ctx, AES_BLOCK_SIZE) ctx;
+@end example
+
+or to give it a struct tag,
+
+@example
+struct aes_cbc_ctx CBC_CTX (struct aes_ctx, AES_BLOCK_SIZE);
+@end example
+
+@deffn Macro CBC_SET_IV (@var{ctx}, @var{iv})
+First argument is a pointer to a context struct as defined by @code{CBC_CTX},
+and the second is a pointer to an Initialization Vector (IV) that is
+copied into that context.
+@end deffn
+
+@deffn Macro CBC_ENCRYPT (@var{ctx}, @var{f}, @var{length}, @var{dst}, @var{src})
+@deffnx Macro CBC_DECRYPT (@var{ctx}, @var{f}, @var{length}, @var{dst}, @var{src})
+A simpler way to invoke @code{cbc_encrypt} and @code{cbc_decrypt}. The
+first argument is a pointer to a context struct as defined by
+@code{CBC_CTX}, and the second argument is an encryption or decryption
+function following Nettle's conventions. The last three arguments define
+the source and destination area for the operation.
+@end deffn
+
+These macros use some tricks to make the compiler display a warning if
+the types of @var{f} and @var{ctx} don't match, e.g. if you try to use
+an @code{struct aes_ctx} context with the @code{des_encrypt} function.
+
+@node CTR, GCM, CBC, Cipher modes
+@comment  node-name,  next,  previous,  up
+@subsection Counter mode
+
+@cindex Counter Mode
+@cindex CTR Mode
+
+Counter mode (@acronym{CTR}) uses the block cipher as a keyed
+pseudo-random generator. The output of the generator is XORed with the
+data to be encrypted. It can be understood as a way to transform a block
+cipher to a stream cipher.
+
+The message is divided into @code{n} blocks @code{M_1},@dots{}
+@code{M_n}, where @code{M_n} is of size @code{m} which may be smaller
+than the block size. Except for the last block, all the message blocks
+must be of size equal to the cipher's block size.
+
+If @code{E_k} is the encryption function of a block cipher, @code{IC} is
+the initial counter, then the @code{n} plaintext blocks are
+transformed into @code{n} ciphertext blocks @code{C_1},@dots{}
+@code{C_n} as follows:
+
+@example
+C_1 = E_k(IC) XOR M_1
+C_2 = E_k(IC + 1) XOR M_2
+
+@dots{}
+
+C_(n-1) = E_k(IC + n - 2) XOR M_(n-1)
+C_n = E_k(IC + n - 1) [1..m] XOR M_n
+@end example
+
+The @acronym{IC} is the initial value for the counter, it plays a
+similar role as the @acronym{IV} for @acronym{CBC}. When adding,
+@code{IC + x}, @acronym{IC} is interpreted as an integer, in network
+byte order. For the last block, @code{E_k(IC + n - 1) [1..m]} means that
+the cipher output is truncated to @code{m} bytes.
+
+@deftypefun {void} ctr_crypt (void *@var{ctx}, nettle_crypt_func @var{f}, unsigned @var{block_size}, uint8_t *@var{ctr}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+
+Applies the encryption function @var{f} in @acronym{CTR} mode. Note that
+for @acronym{CTR} mode, encryption and decryption is the same operation,
+and hence @var{f} should always be the encryption function for the
+underlying block cipher.
+
+When a message is encrypted using a sequence of calls to
+@code{ctr_crypt}, all but the last call @emph{must} use a length that is
+a multiple of the block size.
+@end deftypefun
+
+Like for @acronym{CBC}, there are also a couple of helper macros.
+
+@deffn Macro CTR_CTX (@var{context_type}, @var{block_size})
+Expands to
+@example
+@{
+   context_type ctx;
+   uint8_t ctr[block_size];
+@}
+@end example
+@end deffn
+
+@deffn Macro CTR_SET_COUNTER (@var{ctx}, @var{iv})
+First argument is a pointer to a context struct as defined by
+@code{CTR_CTX}, and the second is a pointer to an initial counter that
+is copied into that context.
+@end deffn
+
+@deffn Macro CTR_CRYPT (@var{ctx}, @var{f}, @var{length}, @var{dst}, @var{src})
+A simpler way to invoke @code{ctr_crypt}. The first argument is a
+pointer to a context struct as defined by @code{CTR_CTX}, and the second
+argument is an encryption function following Nettle's conventions. The
+last three arguments define the source and destination area for the
+operation.
+@end deffn
+
+@node GCM,  , CTR, Cipher modes
+@comment  node-name,  next,  previous,  up
+@subsection Galois counter mode
+
+@cindex Galois Counter Mode
+@cindex GCM
+
+Galois counter mode is the combination of counter mode with message
+authentication based on universal hashing. The main objective of the
+design is to provide high performance for hardware implementations,
+where other popular @acronym{MAC} algorithms (@pxref{Keyed hash
+functions} becomes a bottleneck for high-speed hardware implementations.
+It was proposed by David A. McGrew and John Viega in 2005, and
+recommended by NIST in 2007,
+@uref{http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf,
+NIST Special Publication 800-38D}. It is constructed on top of a block
+cipher which must have a block size of 128 bits.
+
+@acronym{GCM} is applied to messages of arbitrary length. The inputs
+are:
+
+@itemize
+@item 
+A key, which can be used for many messages.
+@item 
+An initialization vector (@acronym{IV}) which @emph{must} be unique for
+each message.
+@item
+Additional authenticated data, which is to be included in the message
+authentication, but not encrypted. May be empty.
+@item
+The plaintext. Maybe empty.
+@end itemize
+
+The outputs are a ciphertext, of the same length as the plaintext, and a
+message digest of length 128 bits. Nettle's support for @acronym{GCM}
+consists of a low-level general interface, some convenience macros, and
+specific functions for @acronym{GCM} using @acronym{AES} as the
+underlying cipher. These interfaces are defined in @file{<nettle/gcm.h>}
+
+@subsubsection General @acronym{GCM} interface
+
+@deftp {Context struct} {struct gcm_key}
+Message independent hash subkey, and related tables.
+@end deftp
+
+@deftp {Context struct} {struct gcm_ctx}
+Holds state corresponding to a particular message.
+@end deftp
+
+@defvr Constant GCM_BLOCK_SIZE
+@acronym{GCM}'s block size, 16.
+@end defvr
+
+@defvr Constant GCM_IV_SIZE
+Recommended size of the @acronym{IV}, 12. Other sizes are allowed.
+@end defvr
+
+@deftypefun void gcm_set_key (struct gcm_key *@var{key}, void *@var{cipher}, nettle_crypt_func *@var{f})
+Initializes @var{key}. @var{cipher} gives a context struct for the
+underlying cipher, which must have been previously initialized for
+encryption, and @var{f} is the encryption function.
+@end deftypefun
+
+@deftypefun void gcm_set_iv (struct gcm_ctx *@var{ctx}, const struct gcm_key *@var{key}, unsigned @var{length}, const uint8_t *@var{iv})
+Initializes @var{ctx} using the given @acronym{IV}. The @var{key}
+argument is actually needed only if @var{length} differs from
+@code{GCM_IV_SIZE}.
+@end deftypefun
+
+@deftypefun void gcm_update (struct gcm_ctx *@var{ctx}, const struct gcm_key *@var{key}, unsigned @var{length}, const uint8_t *@var{data})
+Provides associated data to be authenticated. If used, must be called
+before @code{gcm_encrypt} or @code{gcm_decrypt}. All but the last call
+for each message @emph{must} use a length that is a multiple of the
+block size.
+@end deftypefun
+
+@deftypefun void gcm_encrypt (struct gcm_ctx *@var{ctx}, const struct gcm_key *@var{key} void *@var{cipher}, nettle_crypt_func *@var{f}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+@deftypefunx void gcm_decrypt (struct gcm_ctx *@var{ctx}, const struct gcm_key *@var{key}, void *@var{cipher}, nettle_crypt_func *@var{f}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Encrypts or decrypts the data of a message. @var{cipher} is the context
+struct for the underlying cipher and @var{f} is the encryption function.
+All but the last call for each message @emph{must} use a length that is
+a multiple of the block size.
+@end deftypefun
+
+@deftypefun void gcm_digest (struct gcm_ctx *@var{ctx}, const struct gcm_key *@var{key}, void *@var{cipher}, nettle_crypt_func *@var{f}, unsigned @var{length}, uint8_t *@var{digest})
+Extracts the message digest (also known ``authentication tag''). This is
+the final operation when processing a message. @var{length} is usually
+equal to @code{GCM_BLOCK_SIZE}, but if you provide a smaller value,
+only the first @var{length} octets of the digest are written.
+@end deftypefun
+
+To encrypt a message using @acronym{GCM}, first initialize a context for
+the underlying block cipher with a key to use for encryption. Then call
+the above functions in the following order: @code{gcm_set_key},
+@code{gcm_set_iv}, @code{gcm_update}, @code{gcm_encrypt},
+@code{gcm_digest}. The decryption procedure is analogous, just calling
+@code{gcm_decrypt} instead of @code{gcm_encrypt} (note that
+@acronym{GCM} decryption still uses the encryption function of the
+underlying block cipher). To process a new message, using the same key,
+call @code{gcm_set_iv} with a new @acronym{iv}.
+
+@subsubsection @acronym{GCM} helper macros
+
+The following macros are defined.
+
+@deffn Macro GCM_CTX (@var{context_type})
+This defines an all-in-one context struct, including the context of the
+underlying cipher, the hash subkey, and the per-message state. It expands
+to
+@example
+@{
+   context_type cipher;
+   struct gcm_key key; 
+   struct gcm_ctx gcm;
+@}
+@end example
+@end deffn
+
+Example use:
+@example
+struct gcm_aes_ctx GCM_CTX(struct aes_ctx);
+@end example
+
+The following macros operate on context structs of this form.
+
+@deffn Macro GCM_SET_KEY (@var{ctx}, @var{set_key}, @var{encrypt}, @var{length}, @var{data})
+First argument, @var{ctx}, is a context struct as defined
+by @code{GCM_CTX}. @var{set_key} and @var{encrypt} are functions for
+setting the encryption key and for encrypting data using the underlying
+cipher. @var{length} and @var{data} give the key.
+@end deffn
+
+@deffn Macro GCM_SET_IV (@var{ctx}, @var{length}, @var{data})
+First argument is a context struct as defined by
+@code{GCM_CTX}. @var{length} and @var{data} give the initialization
+vector (@acronym{IV}).
+@end deffn
+
+@deffn Macro GCM_UPDATE (@var{ctx}, @var{length}, @var{data})
+Simpler way to call @code{gcm_update}. First argument is a context
+struct as defined by @code{GCM_CTX}
+@end deffn
+
+@deffn Macro GCM_ENCRYPT (@var{ctx}, @var{encrypt}, @var{length}, @var{dst}, @var{src})
+@deffnx Macro GCM_DECRYPT (@var{ctx}, @var{encrypt}, @var{length}, @var{dst}, @var{src})
+@deffnx Macro GCM_DIGEST (@var{ctx}, @var{encrypt}, @var{length}, @var{digest})
+Simpler way to call @code{gcm_encrypt}, @code{gcm_decrypt} or
+@code{gcm_digest}. First argument is a context struct as defined by
+@code{GCM_CTX}. Second argument, @var{encrypt}, is a pointer to the
+encryption function of the underlying cipher.
+@end deffn
+
+@subsubsection @acronym{GCM}-@acronym{AES} interface
+
+The following functions implement the common case of @acronym{GCM} using
+@acronym{AES} as the underlying cipher.
+
+@deftp {Context struct} {struct gcm_aes_ctx}
+The context struct, defined using @code{GCM_CTX}.
+@end deftp
+
+@deftypefun void gcm_aes_set_key (struct gcm_aes_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key})
+Initializes @var{ctx} using the given key. All valid @acronym{AES} key
+sizes can be used.
+@end deftypefun
+
+@deftypefun void gcm_aes_set_iv (struct gcm_aes_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{iv})
+Initializes the per-message state, using the given @acronym{IV}.
+@end deftypefun
+
+@deftypefun void gcm_aes_update (struct gcm_aes_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data})
+Provides associated data to be authenticated. If used, must be called
+before @code{gcm_aes_encrypt} or @code{gcm_aes_decrypt}. All but the last call
+for each message @emph{must} use a length that is a multiple of the
+block size.
+@end deftypefun
+
+@deftypefun void gcm_aes_encrypt (struct gcm_aes_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+@deftypefunx void gcm_aes_decrypt (struct gcm_aes_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Encrypts or decrypts the data of a message. All but the last call for
+each message @emph{must} use a length that is a multiple of the block
+size.
+
+@end deftypefun
+
+@deftypefun void gcm_aes_digest (struct gcm_aes_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest})
+Extracts the message digest (also known ``authentication tag''). This is
+the final operation when processing a message. @var{length} is usually
+equal to @code{GCM_BLOCK_SIZE}, but if you provide a smaller value,
+only the first @var{length} octets of the digest are written.
+@end deftypefun
+
+
+
+@node Keyed hash functions, Public-key algorithms, Cipher modes, Reference
+@comment  node-name,  next,  previous,  up
+@section Keyed Hash Functions
+
+@cindex Keyed Hash Function
+@cindex Message Authentication Code
+@cindex MAC
+
+A @dfn{keyed hash function}, or @dfn{Message Authentication Code}
+(@acronym{MAC}) is a function that takes a key and a message, and
+produces fixed size @acronym{MAC}. It should be hard to compute a
+message and a matching @acronym{MAC} without knowledge of the key. It
+should also be hard to compute the key given only messages and
+corresponding @acronym{MAC}s.
+
+Keyed hash functions are useful primarily for message authentication,
+when Alice and Bob shares a secret: The sender, Alice, computes the
+@acronym{MAC} and attaches it to the message. The receiver, Bob, also computes
+the @acronym{MAC} of the message, using the same key, and compares that
+to Alice's value. If they match, Bob can be assured that
+the message has not been modified on its way from Alice.
+
+However, unlike digital signatures, this assurance is not transferable.
+Bob can't show the message and the @acronym{MAC} to a third party and
+prove that Alice sent that message. Not even if he gives away the key to
+the third party. The reason is that the @emph{same} key is used on both
+sides, and anyone knowing the key can create a correct @acronym{MAC} for
+any message. If Bob believes that only he and Alice knows the key, and
+he knows that he didn't attach a @acronym{MAC} to a particular message,
+he knows it must be Alice who did it. However, the third party can't
+distinguish between a @acronym{MAC} created by Alice and one created by
+Bob.
+
+Keyed hash functions are typically a lot faster than digital signatures
+as well.
+
+@subsection @acronym{HMAC}
+
+One can build keyed hash functions from ordinary hash functions. Older
+constructions simply concatenate secret key and message and hashes that, but
+such constructions have weaknesses. A better construction is
+@acronym{HMAC}, described in @cite{RFC 2104}.
+
+For an underlying hash function @code{H}, with digest size @code{l} and
+internal block size @code{b}, @acronym{HMAC-H} is constructed as
+follows: From a given key @code{k}, two distinct subkeys @code{k_i} and
+@code{k_o} are constructed, both of length @code{b}. The
+@acronym{HMAC-H} of a message @code{m} is then computed as @code{H(k_o |
+H(k_i | m))}, where @code{|} denotes string concatenation.
+
+@acronym{HMAC} keys can be of any length, but it is recommended to use
+keys of length @code{l}, the digest size of the underlying hash function
+@code{H}. Keys that are longer than @code{b} are shortened to length
+@code{l} by hashing with @code{H}, so arbitrarily long keys aren't
+very useful. 
+
+Nettle's @acronym{HMAC} functions are defined in @file{<nettle/hmac.h>}.
+There are abstract functions that use a pointer to a @code{struct
+nettle_hash} to represent the underlying hash function and @code{void *}
+pointers that point to three different context structs for that hash
+function. There are also concrete functions for @acronym{HMAC-MD5},
+@acronym{HMAC-RIPEMD160} @acronym{HMAC-SHA1}, @acronym{HMAC-SHA256}, and
+@acronym{HMAC-SHA512}. First, the abstract functions:
+
+@deftypefun void hmac_set_key (void *@var{outer}, void *@var{inner}, void *@var{state}, const struct nettle_hash *@var{H}, unsigned @var{length}, const uint8_t *@var{key})
+Initializes the three context structs from the key. The @var{outer} and
+@var{inner} contexts corresponds to the subkeys @code{k_o} and
+@code{k_i}. @var{state} is used for hashing the message, and is
+initialized as a copy of the @var{inner} context.
+@end deftypefun
+
+@deftypefun void hmac_update (void *@var{state}, const struct nettle_hash *@var{H}, unsigned @var{length}, const uint8_t *@var{data})
+This function is called zero or more times to process the message.
+Actually, @code{hmac_update(state, H, length, data)} is equivalent to
+@code{H->update(state, length, data)}, so if you wish you can use the
+ordinary update function of the underlying hash function instead.
+@end deftypefun
+
+@deftypefun void hmac_digest (const void *@var{outer}, const void *@var{inner}, void *@var{state}, const struct nettle_hash *@var{H}, unsigned @var{length}, uint8_t *@var{digest})
+Extracts the @acronym{MAC} of the message, writing it to @var{digest}.
+@var{outer} and @var{inner} are not modified. @var{length} is usually
+equal to @code{H->digest_size}, but if you provide a smaller value,
+only the first @var{length} octets of the @acronym{MAC} are written.
+
+This function also resets the @var{state} context so that you can start
+over processing a new message (with the same key).
+@end deftypefun
+
+Like for @acronym{CBC}, there are some macros to help use these
+functions correctly.
+
+@deffn Macro HMAC_CTX (@var{type})
+Expands to
+@example
+@{
+   type outer;
+   type inner;
+   type state;
+@}
+@end example
+@end deffn
+
+It can be used to define a @acronym{HMAC} context struct, either
+directly,
+
+@example
+struct HMAC_CTX(struct md5_ctx) ctx;
+@end example
+
+or to give it a struct tag,
+
+@example
+struct hmac_md5_ctx HMAC_CTX (struct md5_ctx);
+@end example
+
+@deffn Macro HMAC_SET_KEY (@var{ctx}, @var{H}, @var{length}, @var{key})
+@var{ctx} is a pointer to a context struct as defined by
+@code{HMAC_CTX}, @var{H} is a pointer to a @code{const struct
+nettle_hash} describing the underlying hash function (so it must match
+the type of the components of @var{ctx}). The last two arguments specify
+the secret key.
+@end deffn
+
+@deffn Macro HMAC_DIGEST (@var{ctx}, @var{H}, @var{length}, @var{digest})
+@var{ctx} is a pointer to a context struct as defined by
+@code{HMAC_CTX}, @var{H} is a pointer to a @code{const struct
+nettle_hash} describing the underlying hash function. The last two
+arguments specify where the digest is written.
+@end deffn
+
+Note that there is no @code{HMAC_UPDATE} macro; simply call
+@code{hmac_update} function directly, or the update function of the
+underlying hash function.
+
+@subsection Concrete @acronym{HMAC} functions
+Now we come to the specialized @acronym{HMAC} functions, which are
+easier to use than the general @acronym{HMAC} functions.
+
+@subsubsection @acronym{HMAC-MD5}
+
+@deftp {Context struct} {struct hmac_md5_ctx}
+@end deftp
+
+@deftypefun void hmac_md5_set_key (struct hmac_md5_ctx *@var{ctx}, unsigned @var{key_length}, const uint8_t *@var{key})
+Initializes the context with the key.
+@end deftypefun
+
+@deftypefun void hmac_md5_update (struct hmac_md5_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data})
+Process some more data.
+@end deftypefun
+
+@deftypefun void hmac_md5_digest (struct hmac_md5_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest})
+Extracts the @acronym{MAC}, writing it to @var{digest}. @var{length} may be smaller than
+@code{MD5_DIGEST_SIZE}, in which case only the first @var{length}
+octets of the @acronym{MAC} are written.
+
+This function also resets the context for processing new messages, with
+the same key.
+@end deftypefun
+
+@subsubsection @acronym{HMAC-RIPEMD160}
+
+@deftp {Context struct} {struct hmac_ripemd160_ctx}
+@end deftp
+
+@deftypefun void hmac_ripemd160_set_key (struct hmac_ripemd160_ctx *@var{ctx}, unsigned @var{key_length}, const uint8_t *@var{key})
+Initializes the context with the key.
+@end deftypefun
+
+@deftypefun void hmac_ripemd160_update (struct hmac_ripemd160_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data})
+Process some more data.
+@end deftypefun
+
+@deftypefun void hmac_ripemd160_digest (struct hmac_ripemd160_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest})
+Extracts the @acronym{MAC}, writing it to @var{digest}. @var{length} may be smaller than
+@code{RIPEMD160_DIGEST_SIZE}, in which case only the first @var{length}
+octets of the @acronym{MAC} are written.
+
+This function also resets the context for processing new messages, with
+the same key.
+@end deftypefun
+
+@subsubsection @acronym{HMAC-SHA1}
+
+@deftp {Context struct} {struct hmac_sha1_ctx}
+@end deftp
+
+@deftypefun void hmac_sha1_set_key (struct hmac_sha1_ctx *@var{ctx}, unsigned @var{key_length}, const uint8_t *@var{key})
+Initializes the context with the key.
+@end deftypefun
+
+@deftypefun void hmac_sha1_update (struct hmac_sha1_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data})
+Process some more data.
+@end deftypefun
+
+@deftypefun void hmac_sha1_digest (struct hmac_sha1_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest})
+Extracts the @acronym{MAC}, writing it to @var{digest}. @var{length} may be smaller than
+@code{SHA1_DIGEST_SIZE}, in which case only the first @var{length}
+octets of the @acronym{MAC} are written.
+
+This function also resets the context for processing new messages, with
+the same key.
+@end deftypefun
+
+
+@subsubsection @acronym{HMAC-SHA256}
+
+@deftp {Context struct} {struct hmac_sha256_ctx}
+@end deftp
+
+@deftypefun void hmac_sha256_set_key (struct hmac_sha256_ctx *@var{ctx}, unsigned @var{key_length}, const uint8_t *@var{key})
+Initializes the context with the key.
+@end deftypefun
+
+@deftypefun void hmac_sha256_update (struct hmac_sha256_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data})
+Process some more data.
+@end deftypefun
+
+@deftypefun void hmac_sha256_digest (struct hmac_sha256_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest})
+Extracts the @acronym{MAC}, writing it to @var{digest}. @var{length} may be smaller than
+@code{SHA256_DIGEST_SIZE}, in which case only the first @var{length}
+octets of the @acronym{MAC} are written.
+
+This function also resets the context for processing new messages, with
+the same key.
+@end deftypefun
+
+
+@subsubsection @acronym{HMAC-SHA512}
+
+@deftp {Context struct} {struct hmac_sha512_ctx}
+@end deftp
+
+@deftypefun void hmac_sha512_set_key (struct hmac_sha512_ctx *@var{ctx}, unsigned @var{key_length}, const uint8_t *@var{key})
+Initializes the context with the key.
+@end deftypefun
+
+@deftypefun void hmac_sha512_update (struct hmac_sha512_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data})
+Process some more data.
+@end deftypefun
+
+@deftypefun void hmac_sha512_digest (struct hmac_sha512_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest})
+Extracts the @acronym{MAC}, writing it to @var{digest}. @var{length} may be smaller than
+@code{SHA512_DIGEST_SIZE}, in which case only the first @var{length}
+octets of the @acronym{MAC} are written.
+
+This function also resets the context for processing new messages, with
+the same key.
+@end deftypefun
+
+@node Public-key algorithms, Randomness, Keyed hash functions, Reference
+@comment  node-name,  next,  previous,  up
+@section Public-key algorithms
+
+Nettle uses @acronym{GMP}, the GNU bignum library, for all calculations
+with large numbers. In order to use the public-key features of Nettle,
+you must install @acronym{GMP}, at least version 3.0, before compiling
+Nettle, and you need to link your programs with @code{-lhogweed -lnettle
+-lgmp}.
+
+The concept of @dfn{Public-key} encryption and digital signatures was
+discovered by Whitfield Diffie and Martin E. Hellman and described in a
+paper 1976. In traditional, ``symmetric'', cryptography, sender and
+receiver share the same keys, and these keys must be distributed in a
+secure way. And if there are many users or entities that need to
+communicate, each @emph{pair} needs a shared secret key known by nobody
+else.
+
+@cindex Public Key Cryptography
+@cindex One-way function
+
+Public-key cryptography uses trapdoor one-way functions. A
+@dfn{one-way function} is a function @code{F} such that it is easy to
+compute the value @code{F(x)} for any @code{x}, but given a value
+@code{y}, it is hard to compute a corresponding @code{x} such that
+@code{y = F(x)}. Two examples are cryptographic hash functions, and
+exponentiation in certain groups.
+
+A @dfn{trapdoor one-way function} is a function @code{F} that is
+one-way, unless one knows some secret information about @code{F}. If one
+knows the secret, it is easy to compute both @code{F} and it's inverse.
+If this sounds strange, look at the @acronym{RSA} example below.
+
+Two important uses for one-way functions with trapdoors are public-key
+encryption, and digital signatures. The public-key encryption functions
+in Nettle are not yet documented; the rest of this chapter is about
+digital signatures.
+
+To use a digital signature algorithm, one must first create a
+@dfn{key-pair}: A public key and a corresponding private key. The private
+key is used to sign messages, while the public key is used for verifying
+that that signatures and messages match. Some care must be taken when
+distributing the public key; it need not be kept secret, but if a bad
+guy is able to replace it (in transit, or in some user's list of known
+public keys), bad things may happen.
+
+There are two operations one can do with the keys. The signature
+operation takes a message and a private key, and creates a signature for
+the message. A signature is some string of bits, usually at most a few
+thousand bits or a few hundred octets. Unlike paper-and-ink signatures,
+the digital signature depends on the message, so one can't cut it out of
+context and glue it to a different message.
+
+The verification operation takes a public key, a message, and a string
+that is claimed to be a signature on the message, and returns true or
+false. If it returns true, that means that the three input values
+matched, and the verifier can be sure that someone went through with the
+signature operation on that very message, and that the ``someone'' also
+knows the private key corresponding to the public key.
+
+The desired properties of a digital signature algorithm are as follows:
+Given the public key and pairs of messages and valid signatures on them,
+it should be hard to compute the private key, and it should also be hard
+to create a new message and signature that is accepted by the
+verification operation.
+
+Besides signing meaningful messages, digital signatures can be used for
+authorization. A server can be configured with a public key, such that
+any client that connects to the service is given a random nonce message.
+If the server gets a reply with a correct signature matching the nonce
+message and the configured public key, the client is granted access. So
+the configuration of the server can be understood as ``grant access to
+whoever knows the private key corresponding to this particular public
+key, and to no others''.
+
+
+@menu
+* RSA::                         The RSA public key algorithm.
+* DSA::                         The DSA digital signature algorithm.
+@end menu
+
+@node RSA, DSA, Public-key algorithms, Public-key algorithms
+@comment  node-name,  next,  previous,  up
+@subsection @acronym{RSA}
+
+The @acronym{RSA} algorithm was the first practical digital signature
+algorithm that was constructed. It was described 1978 in a paper by
+Ronald Rivest, Adi Shamir and L.M. Adleman, and the technique was also
+patented in the @acronym{USA} in 1983. The patent expired on September 20, 2000, and since
+that day, @acronym{RSA} can be used freely, even in the @acronym{USA}.
+
+It's remarkably simple to describe the trapdoor function behind
+@acronym{RSA}. The ``one-way''-function used is
+
+@example
+F(x) = x^e mod n
+@end example
+
+I.e. raise x to the @code{e}:th power, while discarding all multiples of
+@code{n}. The pair of numbers @code{n} and @code{e} is the public key.
+@code{e} can be quite small, even @code{e = 3} has been used, although
+slightly larger numbers are recommended. @code{n} should be about 1000
+bits or larger.
+
+If @code{n} is large enough, and properly chosen, the inverse of F,
+the computation of @code{e}:th roots modulo @code{n}, is very difficult.
+But, where's the trapdoor?
+
+Let's first look at how @acronym{RSA} key-pairs are generated. First
+@code{n} is chosen as the product of two large prime numbers @code{p}
+and @code{q} of roughly the same size (so if @code{n} is 1000 bits,
+@code{p} and @code{q} are about 500 bits each). One also computes the
+number @code{phi = (p-1)(q-1)}, in mathematical speak, @code{phi} is the
+order of the multiplicative group of integers modulo n.
+
+Next, @code{e} is chosen. It must have no factors in common with @code{phi} (in
+particular, it must be odd), but can otherwise be chosen more or less
+randomly. @code{e = 65537} is a popular choice, because it makes raising
+to the @code{e}'th power particularly efficient, and being prime, it
+usually has no factors common with @code{phi}.
+
+Finally, a number @code{d}, @code{d < n} is computed such that @code{e d
+mod phi = 1}. It can be shown that such a number exists (this is why
+@code{e} and @code{phi} must have no common factors), and that for all x,
+
+@example
+(x^e)^d mod n = x^(ed) mod n = (x^d)^e mod n = x
+@end example
+
+Using Euclid's algorithm, @code{d} can be computed quite easily from
+@code{phi} and @code{e}. But it is still hard to get @code{d} without
+knowing @code{phi}, which depends on the factorization of @code{n}.
+
+So @code{d} is the trapdoor, if we know @code{d} and @code{y = F(x)}, we can
+recover x as @code{y^d mod n}. @code{d} is also the private half of
+the @acronym{RSA} key-pair.
+
+The most common signature operation for @acronym{RSA} is defined in
+@cite{PKCS#1}, a specification by RSA Laboratories. The message to be
+signed is first hashed using a cryptographic hash function, e.g.
+@acronym{MD5} or @acronym{SHA1}. Next, some padding, the @acronym{ASN.1}
+``Algorithm Identifier'' for the hash function, and the message digest
+itself, are concatenated and converted to a number @code{x}. The
+signature is computed from @code{x} and the private key as @code{s = x^d
+mod n}@footnote{Actually, the computation is not done like this, it is
+done more efficiently using @code{p}, @code{q} and the Chinese remainder
+theorem (@acronym{CRT}). But the result is the same.}. The signature, @code{s} is a
+number of about the same size of @code{n}, and it usually encoded as a
+sequence of octets, most significant octet first.
+
+The verification operation is straight-forward, @code{x} is computed
+from the message in the same way as above. Then @code{s^e mod n} is
+computed, the operation returns true if and only if the result equals
+@code{x}.
+
+@subsection Nettle's @acronym{RSA} support
+
+Nettle represents @acronym{RSA} keys using two structures that contain
+large numbers (of type @code{mpz_t}).
+
+@deftp {Context struct} {rsa_public_key} size n e
+@code{size} is the size, in octets, of the modulo, and is used internally.
+@code{n} and @code{e} is the public key.
+@end deftp
+
+@deftp {Context struct} {rsa_private_key} size d p q a b c
+@code{size} is the size, in octets, of the modulo, and is used internally.
+@code{d} is the secret exponent, but it is not actually used when
+signing. Instead, the factors @code{p} and @code{q}, and the parameters
+@code{a}, @code{b} and @code{c} are used. They are computed from @code{p},
+@code{q} and @code{e} such that @code{a e mod (p - 1) = 1, b e mod (q -
+1) = 1, c q mod p = 1}.
+@end deftp
+
+Before use, these structs must be initialized by calling one of
+
+@deftypefun void rsa_public_key_init (struct rsa_public_key *@var{pub})
+@deftypefunx void rsa_private_key_init (struct rsa_private_key *@var{key})
+Calls @code{mpz_init} on all numbers in the key struct.
+@end deftypefun
+
+and when finished with them, the space for the numbers must be
+deallocated by calling one of
+
+@deftypefun void rsa_public_key_clear (struct rsa_public_key *@var{pub})
+@deftypefunx void rsa_private_key_clear (struct rsa_private_key *@var{key})
+Calls @code{mpz_clear} on all numbers in the key struct.
+@end deftypefun
+
+In general, Nettle's @acronym{RSA} functions deviates from Nettle's ``no
+memory allocation''-policy. Space for all the numbers, both in the key structs
+above, and temporaries, are allocated dynamically. For information on how
+to customize allocation, see
+@xref{Custom Allocation,,GMP Allocation,gmp, GMP Manual}.
+
+When you have assigned values to the attributes of a key, you must call
+
+@deftypefun int rsa_public_key_prepare (struct rsa_public_key *@var{pub})
+@deftypefunx int rsa_private_key_prepare (struct rsa_private_key *@var{key})
+Computes the octet size of the key (stored in the @code{size} attribute,
+and may also do other basic sanity checks. Returns one if successful, or
+zero if the key can't be used, for instance if the modulo is smaller
+than the minimum size needed for @acronym{RSA} operations specified by PKCS#1.
+@end deftypefun
+
+Before signing or verifying a message, you first hash it with the
+appropriate hash function. You pass the hash function's context struct
+to the @acronym{RSA} signature function, and it will extract the message
+digest and do the rest of the work. There are also alternative functions
+that take the hash digest as argument. 
+
+There is currently no support for using SHA224 or SHA384 with
+@acronym{RSA} signatures, since there's no gain in either computation
+time nor message size compared to using SHA256 and SHA512, respectively.
+
+Creation and verification of signatures is done with the following functions:
+
+@deftypefun int rsa_md5_sign (const struct rsa_private_key *@var{key}, struct md5_ctx *@var{hash}, mpz_t @var{signature})
+@deftypefunx int rsa_sha1_sign (const struct rsa_private_key *@var{key}, struct sha1_ctx *@var{hash}, mpz_t @var{signature})
+@deftypefunx int rsa_sha256_sign (const struct rsa_private_key *@var{key}, struct sha256_ctx *@var{hash}, mpz_t @var{signature})
+@deftypefunx int rsa_sha512_sign (const struct rsa_private_key *@var{key}, struct sha512_ctx *@var{hash}, mpz_t @var{signature})
+The signature is stored in @var{signature} (which must have been
+@code{mpz_init}'ed earlier). The hash context is reset so that it can be
+used for new messages. Returns one on success, or zero on failure.
+Signing fails if the key is too small for the given hash size, e.g.,
+it's not possible to create a signature using SHA512 and a 512-bit
+@acronym{RSA} key.
+@end deftypefun
+
+@deftypefun int rsa_md5_sign_digest (const struct rsa_private_key *@var{key}, const uint8_t *@var{digest}, mpz_t @var{signature})
+@deftypefunx int rsa_sha1_sign_digest (const struct rsa_private_key *@var{key}, const uint8_t *@var{digest}, mpz_t @var{signature});
+@deftypefunx int rsa_sha256_sign_digest (const struct rsa_private_key *@var{key}, const uint8_t *@var{digest}, mpz_t @var{signature});
+@deftypefunx int rsa_sha512_sign_digest (const struct rsa_private_key *@var{key}, const uint8_t *@var{digest}, mpz_t @var{signature});
+Creates a signature from the given hash digest. @var{digest} should
+point to a digest of size @code{MD5_DIGEST_SIZE},
+@code{SHA1_DIGEST_SIZE}, or @code{SHA256_DIGEST_SIZE}, respectively. The
+signature is stored in @var{signature} (which must have been
+@code{mpz_init}:ed earlier). Returns one on success, or zero on failure.
+@end deftypefun
+
+@deftypefun int rsa_md5_verify (const struct rsa_public_key *@var{key}, struct md5_ctx *@var{hash}, const mpz_t @var{signature})
+@deftypefunx int rsa_sha1_verify (const struct rsa_public_key *@var{key}, struct sha1_ctx *@var{hash}, const mpz_t @var{signature})
+@deftypefunx int rsa_sha256_verify (const struct rsa_public_key *@var{key}, struct sha256_ctx *@var{hash}, const mpz_t @var{signature})
+@deftypefunx int rsa_sha512_verify (const struct rsa_public_key *@var{key}, struct sha512_ctx *@var{hash}, const mpz_t @var{signature})
+Returns 1 if the signature is valid, or 0 if it isn't. In either case,
+the hash context is reset so that it can be used for new messages.
+@end deftypefun
+
+@deftypefun int rsa_md5_verify_digest (const struct rsa_public_key *@var{key}, const uint8_t *@var{digest}, const mpz_t @var{signature})
+@deftypefunx int rsa_sha1_verify_digest (const struct rsa_public_key *@var{key}, const uint8_t *@var{digest}, const mpz_t @var{signature})
+@deftypefunx int rsa_sha256_verify_digest (const struct rsa_public_key *@var{key}, const uint8_t *@var{digest}, const mpz_t @var{signature})
+@deftypefunx int rsa_sha512_verify_digest (const struct rsa_public_key *@var{key}, const uint8_t *@var{digest}, const mpz_t @var{signature})
+Returns 1 if the signature is valid, or 0 if it isn't. @var{digest} should
+point to a digest of size @code{MD5_DIGEST_SIZE},
+@code{SHA1_DIGEST_SIZE}, or @code{SHA256_DIGEST_SIZE}, respectively.
+@end deftypefun
+
+If you need to use the @acronym{RSA} trapdoor, the private key, in a way
+that isn't supported by the above functions Nettle also includes a
+function that computes @code{x^d mod n} and nothing more, using the
+@acronym{CRT} optimization.
+
+@deftypefun void rsa_compute_root (struct rsa_private_key *@var{key}, mpz_t @var{x}, const mpz_t @var{m})
+Computes @code{x = m^d}, efficiently.
+@end deftypefun
+
+At last, how do you create new keys?
+
+@deftypefun int rsa_generate_keypair (struct rsa_public_key *@var{pub}, struct rsa_private_key *@var{key}, void *@var{random_ctx}, nettle_random_func @var{random}, void *@var{progress_ctx}, nettle_progress_func @var{progress}, unsigned @var{n_size}, unsigned @var{e_size});
+There are lots of parameters. @var{pub} and @var{key} is where the
+resulting key pair is stored. The structs should be initialized, but you
+don't need to call @code{rsa_public_key_prepare} or
+@code{rsa_private_key_prepare} after key generation.
+
+@var{random_ctx} and @var{random} is a randomness generator.
+@code{random(random_ctx, length, dst)} should generate @code{length}
+random octets and store them at @code{dst}. For advice, see
+@xref{Randomness}.
+
+@var{progress} and @var{progress_ctx} can be used to get callbacks
+during the key generation process, in order to uphold an illusion of
+progress. @var{progress} can be NULL, in that case there are no
+callbacks.
+
+@var{size_n} is the desired size of the modulo, in bits. If @var{size_e}
+is non-zero, it is the desired size of the public exponent and a random
+exponent of that size is selected. But if @var{e_size} is zero, it is
+assumed that the caller has already chosen a value for @code{e}, and
+stored it in @var{pub}.
+Returns one on success, and zero on failure. The function can fail for
+example if if @var{n_size} is too small, or if @var{e_size} is zero and
+@code{pub->e} is an even number.
+@end deftypefun
+
+@node DSA,  , RSA, Public-key algorithms
+@comment  node-name,  next,  previous,  up
+@subsection Nettle's @acronym{DSA} support
+
+The @acronym{DSA} digital signature algorithm is more complex than
+@acronym{RSA}. It was specified during the early 1990s, and in 1994 NIST
+published @acronym{FIPS} 186 which is the authoritative specification.
+Sometimes @acronym{DSA} is referred to using the acronym @acronym{DSS},
+for Digital Signature Standard. The most recent revision of the
+specification, FIPS186-3, was issueed in 2009, and it adds support for
+larger hash functions than @acronym{sha1}.
+
+For @acronym{DSA}, the underlying mathematical problem is the
+computation of discreet logarithms. The public key consists of a large
+prime @code{p}, a small prime @code{q} which is a factor of @code{p-1},
+a number @code{g} which generates a subgroup of order @code{q} modulo
+@code{p}, and an element @code{y} in that subgroup.
+
+In the original @acronym{DSA}, the size of @code{q} is fixed to 160
+bits, to match with the @acronym{SHA1} hash algorithm. The size of
+@code{p} is in principle unlimited, but the
+standard specifies only nine specific sizes: @code{512 + l*64}, where
+@code{l} is between 0 and 8. Thus, the maximum size of @code{p} is 1024
+bits, and sizes less than 1024 bits are considered obsolete and not
+secure.
+
+The subgroup requirement means that if you compute 
+
+@example
+g^t mod p
+@end example
+
+for all possible integers @code{t}, you will get precisely @code{q}
+distinct values.
+
+The private key is a secret exponent @code{x}, such that
+
+@example
+g^x = y mod p
+@end example
+
+In mathematical speak, @code{x} is the @dfn{discrete logarithm} of
+@code{y} mod @code{p}, with respect to the generator @code{g}. The size
+of @code{x} will also be about the same size as @code{q}. The security of the
+@acronym{DSA} algorithm relies on the difficulty of the discrete
+logarithm problem. Current algorithms to compute discrete logarithms in
+this setting, and hence crack @acronym{DSA}, are of two types. The first
+type works directly in the (multiplicative) group of integers mod
+@code{p}. The best known algorithm of this type is the Number Field
+Sieve, and it's complexity is similar to the complexity of factoring
+numbers of the same size as @code{p}. The other type works in the
+smaller @code{q}-sized subgroup generated by @code{g}, which has a more
+difficult group structure. One good algorithm is Pollard-rho, which has
+complexity @code{sqrt(q)}.
+
+The important point is that security depends on the size of @emph{both}
+@code{p} and @code{q}, and they should be choosen so that the difficulty
+of both discrete logarithm methods are comparable. Today, the security
+margin of the original @acronym{DSA} may be uncomfortably small. Using a
+@code{p} of 1024 bits implies that cracking using the number field sieve
+is expected to take about the same time as factoring a 1024-bit
+@acronym{RSA} modulo, and using a @code{q} of size 160 bits implies
+that cracking using Pollard-rho will take roughly @code{2^80} group
+operations. With the size of @code{q} fixed, tied to the @acronym{SHA1}
+digest size, it may be tempting to increase the size of @code{p} to,
+say, 4096 bits. This will provide excellent resistance against attacks
+like the number field sieve which works in the large group. But it will
+do very little to defend against Pollard-rho attacking the small
+subgroup; the attacker is slowed down at most by a single factor of 10
+due to the more expensive group operation. And the attacker will surely
+choose the latter attack.
+
+The signature generation algorithm is randomized; in order to create a
+@acronym{DSA} signature, you need a good source for random numbers
+(@pxref{Randomness}). Let us describe the common case of a 160-bit
+@code{q}.
+
+To create a signature, one starts with the hash digest of the message,
+@code{h}, which is a 160 bit number, and a random number @code{k,
+0<k<q}, also 160 bits. Next, one computes 
+
+@example
+r = (g^k mod p) mod q
+s = k^-1 (h + x r) mod q
+@end example
+
+The signature is the pair @code{(r, s)}, two 160 bit numbers. Note the
+two different mod operations when computing @code{r}, and the use of the
+secret exponent @code{x}.
+
+To verify a signature, one first checks that @code{0 < r,s < q}, and
+then one computes backwards,
+
+@example
+w = s^-1 mod q
+v = (g^(w h) y^(w r) mod p) mod q
+@end example
+
+The signature is valid if @code{v = r}. This works out because @code{w =
+s^-1 mod q = k (h + x r)^-1 mod q}, so that
+
+@example
+g^(w h) y^(w r) = g^(w h) (g^x)^(w r) = g^(w (h + x r)) = g^k 
+@end example
+
+When reducing mod @code{q} this yields @code{r}. Note that when
+verifying a signature, we don't know either @code{k} or @code{x}: those
+numbers are secret.
+
+If you can choose between @acronym{RSA} and @acronym{DSA}, which one is
+best? Both are believed to be secure. @acronym{DSA} gained popularity in
+the late 1990s, as a patent free alternative to @acronym{RSA}. Now that
+the @acronym{RSA} patents have expired, there's no compelling reason to
+want to use @acronym{DSA}. Today, the original @acronym{DSA} key size
+does not provide a large security margin, and it should probably be
+phased out together with @acronym{RSA} keys of 1024 bits. Using the
+revised @acronym{DSA} algorithm with a larger hash function, in
+particular, @acronym{SHA256}, a 256-bit @code{q}, and @code{p} of size
+2048 bits or more, should provide for a more comfortable security
+margin, but these variants are not yet in wide use.
+
+@acronym{DSA} signatures are smaller than @acronym{RSA} signatures,
+which is important for some specialized applications.
+
+From a practical point of view, @acronym{DSA}'s need for a good
+randomness source is a serious disadvantage. If you ever use the same
+@code{k} (and @code{r}) for two different message, you leak your private
+key.
+
+@subsection Nettle's @acronym{DSA} support
+
+Like for @acronym{RSA}, Nettle represents @acronym{DSA} keys using two
+structures, containing values of type @code{mpz_t}. For information on
+how to customize allocation, see @xref{Custom Allocation,,GMP
+Allocation,gmp, GMP Manual}.
+
+Most of the @acronym{DSA} functions are very similar to the
+corresponding @acronym{RSA} functions, but there are a few differences
+pointed out below. For a start, there are no functions corresponding to
+@code{rsa_public_key_prepare} and @code{rsa_private_key_prepare}.
+
+@deftp {Context struct} {dsa_public_key} p q g y
+The public parameters described above.
+@end deftp
+
+@deftp {Context struct} {dsa_private_key} x
+The private key @code{x}.
+@end deftp
+
+Before use, these structs must be initialized by calling one of
+
+@deftypefun void dsa_public_key_init (struct dsa_public_key *@var{pub})
+@deftypefunx void dsa_private_key_init (struct dsa_private_key *@var{key})
+Calls @code{mpz_init} on all numbers in the key struct.
+@end deftypefun
+
+When finished with them, the space for the numbers must be
+deallocated by calling one of
+
+@deftypefun void dsa_public_key_clear (struct dsa_public_key *@var{pub})
+@deftypefunx void dsa_private_key_clear (struct dsa_private_key *@var{key})
+Calls @code{mpz_clear} on all numbers in the key struct.
+@end deftypefun
+
+Signatures are represented using the structure below, and need to be
+initialized and cleared in the same way as the key structs.
+
+@deftp {Context struct} {dsa_signature} r s
+@end deftp
+
+@deftypefun void dsa_signature_init (struct dsa_signature *@var{signature})
+@deftypefunx void dsa_signature_clear (struct dsa_signature *@var{signature})
+You must call @code{dsa_signature_init} before creating or using a
+signature, and call @code{dsa_signature_clear} when you are finished
+with it.
+@end deftypefun
+
+For signing, you need to provide both the public and the private key
+(unlike @acronym{RSA}, where the private key struct includes all
+information needed for signing), and a source for random numbers.
+Signatures can use the @acronym{SHA1} or the @acronym{SHA256} hash
+function, although the implementation of @acronym{DSA} with
+@acronym{SHA256} should be considered somewhat experimental due to lack
+of official test vectors and interoperability testing.
+
+@deftypefun int dsa_sha1_sign (const struct dsa_public_key *@var{pub}, const struct dsa_private_key *@var{key}, void *@var{random_ctx}, nettle_random_func @var{random}, struct sha1_ctx *@var{hash}, struct dsa_signature *@var{signature})
+@deftypefunx int dsa_sha1_sign_digest (const struct dsa_public_key *@var{pub}, const struct dsa_private_key *@var{key}, void *@var{random_ctx}, nettle_random_func @var{random}, const uint8_t *@var{digest}, struct dsa_signature *@var{signature})
+@deftypefunx int dsa_sha256_sign (const struct dsa_public_key *@var{pub}, const struct dsa_private_key *@var{key}, void *@var{random_ctx}, nettle_random_func @var{random}, struct sha256_ctx *@var{hash}, struct dsa_signature *@var{signature})
+@deftypefunx int dsa_sha256_sign_digest (const struct dsa_public_key *@var{pub}, const struct dsa_private_key *@var{key}, void *@var{random_ctx}, nettle_random_func @var{random}, const uint8_t *@var{digest}, struct dsa_signature *@var{signature})
+Creates a signature from the given hash context or digest.
+@var{random_ctx} and @var{random} is a randomness generator.
+@code{random(random_ctx, length, dst)} should generate @code{length}
+random octets and store them at @code{dst}. For advice, see
+@xref{Randomness}. Returns one on success, or zero on failure.
+Signing fails if the key size and the hash size don't match.
+@end deftypefun
+
+Verifying signatures is a little easier, since no randomness generator is
+needed. The functions are
+
+@deftypefun int dsa_sha1_verify (const struct dsa_public_key *@var{key}, struct sha1_ctx *@var{hash}, const struct dsa_signature *@var{signature})
+@deftypefunx int dsa_sha1_verify_digest (const struct dsa_public_key *@var{key}, const uint8_t *@var{digest}, const struct dsa_signature *@var{signature})
+@deftypefunx int dsa_sha256_verify (const struct dsa_public_key *@var{key}, struct sha256_ctx *@var{hash}, const struct dsa_signature *@var{signature})
+@deftypefunx int dsa_sha256_verify_digest (const struct dsa_public_key *@var{key}, const uint8_t *@var{digest}, const struct dsa_signature *@var{signature})
+Verifies a signature. Returns 1 if the signature is valid, otherwise 0.
+@end deftypefun
+
+Key generation uses mostly the same parameters as the corresponding
+@acronym{RSA} function.
+
+@deftypefun int dsa_generate_keypair (struct dsa_public_key *@var{pub}, struct dsa_private_key *@var{key}, void *@var{random_ctx}, nettle_random_func @var{random}, void *@var{progress_ctx}, nettle_progress_func @var{progress}, unsigned @var{p_bits}, unsigned @var{q_bits})
+@var{pub} and @var{key} is where the resulting key pair is stored. The
+structs should be initialized before you call this function. 
+
+@var{random_ctx} and @var{random} is a randomness generator.
+@code{random(random_ctx, length, dst)} should generate @code{length}
+random octets and store them at @code{dst}. For advice, see
+@xref{Randomness}.
+
+@var{progress} and @var{progress_ctx} can be used to get callbacks
+during the key generation process, in order to uphold an illusion of
+progress. @var{progress} can be NULL, in that case there are no
+callbacks.
+
+@var{p_bits} and @var{q_bits} are the desired sizes of @code{p} and
+@code{q}. To generate keys that conform to the original @acronym{DSA}
+standard, you must use @code{q_bits = 160} and select @var{p_bits} of
+the form @code{p_bits = 512 + l*64}, for @code{0 <= l <= 8}, where the
+smaller sizes are no longer recommended, so you should most likely stick
+to @code{p_bits = 1024}. Non-standard sizes are possible, in particular
+@code{p_bits} larger than 1024, although @acronym{DSA} implementations
+can not in general be expected to support such keys. Also note that
+using very large @var{p_bits}, with @var{q_bits} fixed at 160, doesn't
+make much sense, because the security is also limited by the size of the
+smaller prime. Using a larger @code{q_bits} requires switchign to a
+larger hash function. To generate @acronym{DSA} keys for use with
+@acronym{SHA256}, use @code{q_bits = 256} and, e.g., @code{p_bits =
+2048}.
+
+Returns one on success, and zero on failure. The function will fail if
+@var{q_bits} is neither 160 nor 256, or if @var{p_bits} is unreasonably
+small.
+@end deftypefun
+
+@node Randomness, Miscellaneous functions, Public-key algorithms, Reference
+@comment  node-name,  next,  previous,  up
+@section Randomness
+
+@cindex Randomness
+
+A crucial ingredient in many cryptographic contexts is randomness: Let
+@code{p} be a random prime, choose a random initialization vector
+@code{iv}, a random key @code{k} and a random exponent @code{e}, etc. In
+the theories, it is assumed that you have plenty of randomness around.
+If this assumption is not true in practice, systems that are otherwise
+perfectly secure, can be broken. Randomness has often turned out to be
+the weakest link in the chain.
+
+In non-cryptographic applications, such as games as well as scientific
+simulation, a good randomness generator usually means a generator that
+has good statistical properties, and is seeded by some simple function
+of things like the current time, process id, and host name.
+
+However, such a generator is inadequate for cryptography, for at least
+two reasons:
+
+
+@itemize
+
+@item
+It's too easy for an attacker to guess the initial seed. Even if it will
+take some 2^32 tries before he guesses right, that's far too easy. For
+example, if the process id is 16 bits, the resolution of ``current time''
+is one second, and the attacker knows what day the generator was seeded,
+there are only about 2^32 possibilities to try if all possible values
+for the process id and time-of-day are tried.
+
+@item
+The generator output reveals too much. By observing only a small segment
+of the generator's output, its internal state can be recovered, and from
+there, all previous output and all future output can be computed by the
+attacker. 
+@end itemize
+
+A randomness generator that is used for cryptographic purposes must have
+better properties. Let's first look at the seeding, as the issues here
+are mostly independent of the rest of the generator. The initial state
+of the generator (its seed) must be unguessable by the attacker. So
+what's unguessable? It depends on what the attacker already knows. The
+concept used in information theory to reason about such things is called
+``entropy'', or ``conditional entropy'' (not to be confused with the
+thermodynamic concept with the same name). A reasonable requirement is
+that the seed contains a conditional entropy of at least some 80-100
+bits. This property can be explained as follows: Allow the attacker to
+ask @code{n} yes-no-questions, of his own choice, about the seed. If
+the attacker, using this question-and-answer session, as well as any
+other information he knows about the seeding process, still can't guess
+the seed correctly, then the conditional entropy is more than @code{n}
+bits.
+
+@cindex Entropy
+@cindex Conditional entropy
+
+Let's look at an example. Say information about timing of received
+network packets is used in the seeding process. If there is some random
+network traffic going on, this will contribute some bits of entropy or
+``unguessability'' to the seed. However, if the attacker can listen in to
+the local network, or if all but a small number of the packets were
+transmitted by machines that the attacker can monitor, this additional
+information makes the seed easier for the attacker to figure out. Even
+if the information is exactly the same, the conditional entropy, or
+unguessability, is smaller for an attacker that knows some of it already
+before the hypothetical question-and-answer session.
+
+Seeding of good generators is usually based on several sources. The key
+point here is that the amount of unguessability that each source
+contributes, depends on who the attacker is. Some sources that have been
+used are:
+
+@table @asis
+@item High resolution timing of i/o activities
+Such as completed blocks from spinning hard disks, network packets, etc.
+Getting access to such information is quite system dependent, and not
+all systems include suitable hardware. If available, it's one of the
+better randomness source one can find in a digital, mostly predictable,
+computer.
+
+@item User activity
+Timing and contents of user interaction events is another popular source
+that is available for interactive programs (even if I suspect that it is
+sometimes used in order to make the user feel good, not because the
+quality of the input is needed or used properly). Obviously, not
+available when a machine is unattended. Also beware of networks: User
+interaction that happens across a long serial cable, @acronym{TELNET}
+session, or even @acronym{SSH} session may be visible to an attacker, in
+full or partially.
+
+@item Audio input
+Any room, or even a microphone input that's left unconnected, is a
+source of some random background noise, which can be fed into the
+seeding process.
+
+@item Specialized hardware
+Hardware devices with the sole purpose of generating random data have
+been designed. They range from radioactive samples with an attached
+Geiger counter, to amplification of the inherent noise in electronic
+components such as diodes and resistors, to low-frequency sampling of
+chaotic systems. Hashing successive images of a Lava lamp is a
+spectacular example of the latter type.
+
+@item Secret information
+Secret information, such as user passwords or keys, or private files
+stored on disk, can provide some unguessability. A problem is that if
+the information is revealed at a later time, the unguessability
+vanishes. Another problem is that this kind of information tends to be
+fairly constant, so if you rely on it and seed your generator regularly,
+you risk constructing almost similar seeds or even constructing the same
+seed more than once.
+@end table
+
+For all practical sources, it's difficult but important to provide a
+reliable lower bound on the amount of unguessability that it provides.
+Two important points are to make sure that the attacker can't observe
+your sources (so if you like the Lava lamp idea, remember that you have
+to get your own lamp, and not put it by a window or anywhere else where
+strangers can see it), and that hardware failures are detected. What if
+the bulb in the Lava lamp, which you keep locked into a cupboard
+following the above advice, breaks after a few months?
+
+So let's assume that we have been able to find an unguessable seed,
+which contains at least 80 bits of conditional entropy, relative to all
+attackers that we care about (typically, we must at the very least
+assume that no attacker has root privileges on our machine).
+
+How do we generate output from this seed, and how much can we get? Some
+generators (notably the Linux @file{/dev/random} generator) tries to
+estimate available entropy and restrict the amount of output. The goal
+is that if you read 128 bits from @file{/dev/random}, you should get 128
+``truly random'' bits. This is a property that is useful in some
+specialized circumstances, for instance when generating key material for
+a one time pad, or when working with unconditional blinding, but in most
+cases, it doesn't matter much. For most application, there's no limit on
+the amount of useful ``random'' data that we can generate from a small
+seed; what matters is that the seed is unguessable and that the
+generator has good cryptographic properties.
+
+At the heart of all generators lies its internal state. Future output
+is determined by the internal state alone. Let's call it the generator's
+key. The key is initialized from the unguessable seed. Important
+properties of a generator are:
+
+@table @dfn
+
+@item Key-hiding
+An attacker observing the output should not be able to recover the
+generator's key.
+
+@item Independence of outputs
+Observing some of the output should not help the attacker to guess
+previous or future output.
+
+@item Forward secrecy
+Even if an attacker compromises the generator's key, he should not be
+able to guess the generator output @emph{before} the key compromise.
+
+@item Recovery from key compromise
+If an attacker compromises the generator's key, he can compute
+@emph{all} future output. This is inevitable if the generator is seeded
+only once, at startup. However, the generator can provide a reseeding
+mechanism, to achieve recovery from key compromise. More precisely: If
+the attacker compromises the key at a particular time @code{t_1}, there
+is another later time @code{t_2}, such that if the attacker observes all
+output generated between @code{t_1} and @code{t_2}, he still can't guess
+what output is generated after @code{t_2}.
+
+@end table
+
+Nettle includes one randomness generator that is believed to have all
+the above properties, and two simpler ones.
+
+@acronym{ARCFOUR}, like any stream cipher, can be used as a randomness
+generator. Its output should be of reasonable quality, if the seed is
+hashed properly before it is used with @code{arcfour_set_key}. There's
+no single natural way to reseed it, but if you need reseeding, you
+should be using Yarrow instead.
+
+The ``lagged Fibonacci'' generator in @file{<nettle/knuth-lfib.h>} is a
+fast generator with good statistical properties, but is @strong{not} for
+cryptographic use, and therefore not documented here. It is included
+mostly because the Nettle test suite needs to generate some test data
+from a small seed.
+
+The recommended generator to use is Yarrow, described below.
+
+@subsection Yarrow
+
+Yarrow is a family of pseudo-randomness generators, designed for
+cryptographic use, by John Kelsey, Bruce Schneier and Niels Ferguson.
+Yarrow-160 is described in a paper at
+@url{http://www.counterpane.com/yarrow.html}, and it uses @acronym{SHA1}
+and triple-DES, and has a 160-bit internal state. Nettle implements
+Yarrow-256, which is similar, but uses @acronym{SHA256} and
+@acronym{AES} to get an internal state of 256 bits.
+
+Yarrow was an almost finished project, the paper mentioned above is the
+closest thing to a specification for it, but some smaller details are
+left out. There is no official reference implementation or test cases.
+This section includes an overview of Yarrow, but for the details of
+Yarrow-256, as implemented by Nettle, you have to consult the source
+code. Maybe a complete specification can be written later.
+
+Yarrow can use many sources (at least two are needed for proper
+reseeding), and two randomness ``pools'', referred to as the ``slow pool'' and
+the ``fast pool''. Input from the sources is fed alternatingly into the
+two pools. When one of the sources has contributed 100 bits of entropy
+to the fast pool, a ``fast reseed'' happens and the fast pool is mixed
+into the internal state. When at least two of the sources have
+contributed at least 160 bits each to the slow pool, a ``slow reseed''
+takes place. The contents of both pools are mixed into the internal
+state. These procedures should ensure that the generator will eventually
+recover after a key compromise.
+
+The output is generated by using @acronym{AES} to encrypt a counter,
+using the generator's current key. After each request for output,
+another 256 bits are generated which replace the key. This ensures
+forward secrecy.
+
+Yarrow can also use a @dfn{seed file} to save state across restarts.
+Yarrow is seeded by either feeding it the contents of the previous seed
+file, or feeding it input from its sources until a slow reseed happens.
+
+Nettle defines Yarrow-256 in @file{<nettle/yarrow.h>}. 
+
+@deftp {Context struct} {struct yarrow256_ctx}
+@end deftp
+
+@deftp {Context struct} {struct yarrow_source}
+Information about a single source.
+@end deftp
+
+@defvr Constant YARROW256_SEED_FILE_SIZE
+Recommanded size of the Yarrow-256 seed file.
+@end defvr
+
+@deftypefun void yarrow256_init (struct yarrow256_ctx *@var{ctx}, unsigned @var{nsources}, struct yarrow_source *@var{sources})
+Initializes the yarrow context, and its @var{nsources} sources. It's
+possible to call it with @var{nsources}=0 and @var{sources}=NULL, if
+you don't need the update features.
+@end deftypefun
+
+@deftypefun void yarrow256_seed (struct yarrow256_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{seed_file})
+Seeds Yarrow-256 from a previous seed file. @var{length} should be at least
+@code{YARROW256_SEED_FILE_SIZE}, but it can be larger.
+
+The generator will trust you that the @var{seed_file} data really is
+unguessable. After calling this function, you @emph{must} overwrite the old
+seed file with newly generated data from @code{yarrow256_random}. If it's
+possible for several processes to read the seed file at about the same
+time, access must be coordinated using some locking mechanism.
+@end deftypefun
+
+@deftypefun int yarrow256_update (struct yarrow256_ctx *@var{ctx}, unsigned @var{source}, unsigned @var{entropy}, unsigned @var{length}, const uint8_t *@var{data})
+Updates the generator with data from source @var{SOURCE} (an index that
+must be smaller than the number of sources). @var{entropy} is your
+estimated lower bound for the entropy in the data, measured in bits.
+Calling update with zero @var{entropy} is always safe, no matter if the
+data is random or not.
+
+Returns 1 if a reseed happened, in which case an application using a
+seed file may want to generate new seed data with
+@code{yarrow256_random} and overwrite the seed file. Otherwise, the
+function returns 0.
+@end deftypefun
+
+@deftypefun void yarrow256_random (struct yarrow256_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst})
+Generates @var{length} octets of output. The generator must be seeded
+before you call this function.
+
+If you don't need forward secrecy, e.g. if you need non-secret
+randomness for initialization vectors or padding, you can gain some
+efficiency by buffering, calling this function for reasonably large
+blocks of data, say 100-1000 octets at a time.
+@end deftypefun
+
+@deftypefun int yarrow256_is_seeded (struct yarrow256_ctx *@var{ctx})
+Returns 1 if the generator is seeded and ready to generate output,
+otherwise 0.
+@end deftypefun
+
+@deftypefun unsigned yarrow256_needed_sources (struct yarrow256_ctx *@var{ctx})
+Returns the number of sources that must reach the threshold before a
+slow reseed will happen. Useful primarily when the generator is unseeded.
+@end deftypefun
+
+@deftypefun void yarrow256_fast_reseed (struct yarrow256_ctx *@var{ctx})
+@deftypefunx void yarrow256_slow_reseed (struct yarrow256_ctx *@var{ctx})
+Causes a fast or slow reseed to take place immediately, regardless of the
+current entropy estimates of the two pools. Use with care.
+@end deftypefun
+
+Nettle includes an entropy estimator for one kind of input source: User
+keyboard input.
+
+@deftp {Context struct} {struct yarrow_key_event_ctx}
+Information about recent key events.
+@end deftp
+
+@deftypefun void yarrow_key_event_init (struct yarrow_key_event_ctx *@var{ctx})
+Initializes the context.
+@end deftypefun
+
+@deftypefun unsigned yarrow_key_event_estimate (struct yarrow_key_event_ctx *@var{ctx}, unsigned @var{key}, unsigned @var{time})
+@var{key} is the id of the key (ASCII value, hardware key code, X
+keysym, @dots{}, it doesn't matter), and @var{time} is the timestamp of
+the event. The time must be given in units matching the resolution by
+which you read the clock. If you read the clock with microsecond
+precision, @var{time} should be provided in units of microseconds. But
+if you use @code{gettimeofday} on a typical Unix system where the clock
+ticks 10 or so microseconds at a time, @var{time} should be given in
+units of 10 microseconds.
+
+Returns an entropy estimate, in bits, suitable for calling
+@code{yarrow256_update}. Usually, 0, 1 or 2 bits.
+@end deftypefun
+
+@node Miscellaneous functions, Compatibility functions, Randomness, Reference
+@comment  node-name,  next,  previous,  up
+@section Miscellaneous functions
+
+@deftypefun {uint8_t *} memxor (uint8_t *@var{dst}, const uint8_t *@var{src}, size_t @var{n})
+XORs the source area on top of the destination area. The interface
+doesn't follow the Nettle conventions, because it is intended to be
+similar to the ANSI-C @code{memcpy} function.
+@end deftypefun
+
+@code{memxor} is declared in @file{<nettle/memxor.h>}.
+
+@node Compatibility functions,  , Miscellaneous functions, Reference
+@comment  node-name,  next,  previous,  up
+@section Compatibility functions
+
+For convenience, Nettle includes alternative interfaces to some
+algorithms, for compatibility with some other popular crypto toolkits.
+These are not fully documented here; refer to the source or to the
+documentation for the original implementation.
+
+MD5 is defined in [RFC 1321], which includes a reference implementation.
+Nettle defines a compatible interface to MD5 in
+@file{<nettle/md5-compat.h>}. This file defines the typedef
+@code{MD5_CTX}, and declares the functions @code{MD5Init}, @code{MD5Update} and
+@code{MD5Final}.
+
+Eric Young's ``libdes'' (also part of OpenSSL) is a quite popular DES
+implementation. Nettle includes a subset if its interface in
+@file{<nettle/des-compat.h>}. This file defines the typedefs
+@code{des_key_schedule} and @code{des_cblock}, two constants
+@code{DES_ENCRYPT} and @code{DES_DECRYPT}, and declares one global
+variable @code{des_check_key}, and the functions @code{des_cbc_cksum}
+@code{des_cbc_encrypt}, @code{des_ecb2_encrypt},
+@code{des_ecb3_encrypt}, @code{des_ecb_encrypt},
+@code{des_ede2_cbc_encrypt}, @code{des_ede3_cbc_encrypt},
+@code{des_is_weak_key}, @code{des_key_sched}, @code{des_ncbc_encrypt}
+@code{des_set_key}, and @code{des_set_odd_parity}.
+
+@node Nettle soup, Installation, Reference, Top
+@comment  node-name,  next,  previous,  up
+@chapter Traditional Nettle Soup
+For the serious nettle hacker, here is a recipe for nettle soup. 4 servings.
+
+@itemize @w{}
+@item
+1 liter fresh nettles (urtica dioica)
+@item
+2 tablespoons butter
+@item
+3 tablespoons flour
+@item
+1 liter stock (meat or vegetable)
+@item
+1/2 teaspoon salt
+@item
+a tad white pepper
+@item
+some cream or milk
+@end itemize
+
+Gather 1 liter fresh nettles. Use gloves! Small, tender shoots are
+preferable but the tops of larger nettles can also be used.
+
+Rinse the nettles very well. Boil them for 10 minutes in lightly salted
+water. Strain the nettles and save the water. Hack the nettles. Melt the
+butter and mix in the flour. Dilute with stock and the nettle-water you
+saved earlier. Add the hacked nettles. If you wish you can add some milk
+or cream at this stage. Bring to a boil and let boil for a few minutes.
+Season with salt and pepper.
+
+Serve with boiled egg-halves.
+
+@c And the original Swedish version.
+@ignore
+
+Recept på nässelsoppa
+4 portioner
+
+1 l färska nässlor
+2 msk smör
+3 msk vetemjöl
+1 l kött- eller grönsaksbuljong
+1/2 tsk salt
+1-2 krm peppar
+(lite grädde eller mjölk)
+
+Plocka 1 liter färska nässlor. Använd handskar! Helst små och späda
+skott, men topparna av större nässlor går också bra.
+
+Skölj nässlorna väl. Förväll dem ca 10 minuter i lätt saltat vatten.
+Häll av och spara spadet. Hacka nässlorna. Smält smöret, rör i mjöl och
+späd med buljong och nässelspad. Lägg i de hackade nässlorna. Om så
+önskas, häll i en skvätt mjölk eller grädde. Koka några minuter, och
+smaksätt med salt och peppar.
+
+Servera med kokta ägghalvor.
+@end ignore
+
+@node Installation, Index, Nettle soup, Top
+@comment  node-name,  next,  previous,  up
+@chapter Installation
+
+Nettle uses @command{autoconf}. To build it, unpack the source and run
+
+@example
+./configure
+make
+make check
+make install
+@end example
+
+@noindent
+to install in the default location, @file{/usr/local}. The library files
+are installed in @file{/use/local/lib/libnettle.a}
+@file{/use/local/lib/libhogweed.a} and the include files are installed
+in @file{/use/local/include/nettle/}.
+
+To get a list of configure options, use @code{./configure --help}.
+
+By default, only static libraries are built and installed. To also build
+and install shared libraries, use the @option{ --enable-shared} option
+to @command{./configure}.
+
+Using GNU make is recommended. For other make programs, in particular
+BSD make, you may have to use the @option{--disable-dependency-tracking}
+option to @command{./configure}.
+
+@node Index,  , Installation, Top
+@comment  node-name,  next,  previous,  up
+@unnumbered Function and Concept Index
+
+@printindex cp
+
+@bye
+\f
+Local Variables:
+ispell-local-dictionary: "american"
+ispell-skip-region-alist: (
+ (ispell-words-keyword forward-line)
+ ("^@example" . "^@end.*example")
+ ("^@ignore" . "^@end.*ignore")
+ ("^@\\(end\\|syncodeindex\\|vskip\\|\\(un\\)?macro\\|node\\|deftp\\) .*$")
+ ("^@\\(printindex\\|set\\) .*$")
+ ("^@def.*$")
+ ;; Allows one level of nested braces in the argument 
+ ("@\\(uref\\|value\\|badspell\\|code\\|file\\|var\\|url\\){[^{}]*\\({[^{}]*}[^{}]*\\)*}")
+ ("@[a-z]+[{ ]")
+ ("@[a-z]+$")
+ ("\input texinfo.*$")
+ ("ispell-ignore" . "ispell-end-ignore")
+ ("^Local Variables:$" . "^End:$"))
+End:
+
+@c  LocalWords:  cryptographics crypto LSH GNUPG API GPL LGPL aes rijndael ller
+@c  LocalWords:  Sevilla arcfour RC Niels Dassen Colin Kuchling Biham sha Ruud
+@c  LocalWords:  Gutmann twofish de Rooij struct MB Rivest RFC Nettle's ECB CBC
+@c  LocalWords:  RSA Daemen Rijnmen Schneier DES's ede structs oddnesses HMAC
+@c  LocalWords:  NIST Alice's GMP bignum Diffie Adi Shamir Adleman Euclid's ASN
+@c  LocalWords:  PKCS callbacks Young's urtica dioica autoconf SSH tad
+@c  LocalWords:  unguessability reseeding reseed alternatingly keysym subkeys
+@c  LocalWords:  DSA gmp FIPS DSS libdes OpenSSL ARCTWO Josefsson Nikos Andreas
+@c  LocalWords:  Mavroyanopoulos Sigfridsson Comstedt interoperability Sparc IC
+@c  LocalWords:  DES FIXME Rivest's plaintext ciphertext CTR XORed timestamp
+@c  LocalWords:  XORs cryptologists
diff --git a/pgp-encode.c b/pgp-encode.c
new file mode 100644 (file)
index 0000000..0ac46d2
--- /dev/null
@@ -0,0 +1,413 @@
+/* pgp.c
+ *
+ * PGP related functions.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pgp.h"
+
+#include "base64.h"
+#include "buffer.h"
+#include "macros.h"
+#include "rsa.h"
+
+int
+pgp_put_uint32(struct nettle_buffer *buffer, uint32_t i)
+{
+  uint8_t *p = nettle_buffer_space(buffer, 4);
+  if (!p)
+    return 0;
+  
+  WRITE_UINT32(p, i);
+  return 1;
+}
+
+int
+pgp_put_uint16(struct nettle_buffer *buffer, unsigned i)
+{
+  uint8_t *p = nettle_buffer_space(buffer, 2);
+  if (!p)
+    return 0;
+  
+  WRITE_UINT16(p, i);
+  return 1;
+}
+
+int
+pgp_put_mpi(struct nettle_buffer *buffer, const mpz_t x)
+{
+  unsigned bits = mpz_sizeinbase(x, 2);
+  unsigned octets = (bits + 7) / 8;
+
+  uint8_t *p;
+
+  /* FIXME: What's the correct representation of zero? */
+  if (!pgp_put_uint16(buffer, bits))
+    return 0;
+  
+  p = nettle_buffer_space(buffer, octets);
+
+  if (!p)
+    return 0;
+  
+  nettle_mpz_get_str_256(octets, p, x);
+
+  return 1;
+}
+
+int
+pgp_put_string(struct nettle_buffer *buffer,
+              unsigned length,
+              const uint8_t *s)
+{
+  return nettle_buffer_write(buffer, length, s);
+}
+
+#if 0
+static unsigned
+length_field(unsigned length)
+{
+  if (length < PGP_LENGTH_TWO_OCTET)
+    return 1;
+  else if (length < PGP_LENGTH_FOUR_OCTETS)
+    return 2;
+  else return 4;
+}
+#endif
+
+/*   bodyLen = ((1st_octet - 192) << 8) + (2nd_octet) + 192
+ *   ==> bodyLen - 192 + 192 << 8 = (1st_octet << 8) + (2nd_octet) 
+ */
+
+#define LENGTH_TWO_OFFSET (192 * 255)
+
+int
+pgp_put_length(struct nettle_buffer *buffer,
+              unsigned length)
+{
+  if (length < PGP_LENGTH_TWO_OCTETS)
+    return NETTLE_BUFFER_PUTC(buffer, length);
+
+  else if (length < PGP_LENGTH_FOUR_OCTETS)
+    return pgp_put_uint16(buffer, length + LENGTH_TWO_OFFSET);
+  else
+    return NETTLE_BUFFER_PUTC(buffer, 0xff) && pgp_put_uint32(buffer, length);
+}
+
+/* Uses the "new" packet format */
+int
+pgp_put_header(struct nettle_buffer *buffer,
+              unsigned tag, unsigned length)
+{
+  assert(tag < 0x40);
+
+  return (NETTLE_BUFFER_PUTC(buffer, 0xC0 | tag)
+         && pgp_put_length(buffer, length));  
+}
+
+/* FIXME: Should we abort or return error if the length and the field
+ * size don't match? */
+void
+pgp_put_header_length(struct nettle_buffer *buffer,
+                     /* start of the header */
+                     unsigned start,
+                     unsigned field_size)
+{
+  unsigned length;
+  switch (field_size)
+    {
+    case 1:
+      length = buffer->size - (start + 2);
+      assert(length < PGP_LENGTH_TWO_OCTETS);
+      buffer->contents[start + 1] = length;
+      break;
+    case 2:
+      length = buffer->size - (start + 3);
+      assert(length < PGP_LENGTH_FOUR_OCTETS
+            && length >= PGP_LENGTH_TWO_OCTETS);
+      WRITE_UINT16(buffer->contents + start + 1, length + LENGTH_TWO_OFFSET);
+      break;
+    case 4:
+      length = buffer->size - (start + 5);
+      WRITE_UINT32(buffer->contents + start + 2, length);
+      break;
+    default:
+      abort();
+    }
+}
+
+int
+pgp_put_userid(struct nettle_buffer *buffer,
+              unsigned length,
+              const uint8_t *name)
+{
+  return (pgp_put_header(buffer, PGP_TAG_USERID, length)
+         && pgp_put_string(buffer, length, name));
+}
+
+unsigned
+pgp_sub_packet_start(struct nettle_buffer *buffer)
+{
+  return nettle_buffer_space(buffer, 2) ? buffer->size : 0;
+}
+
+int
+pgp_put_sub_packet(struct nettle_buffer *buffer,
+                  unsigned type,
+                  unsigned length,
+                  const uint8_t *data)
+{
+  return (pgp_put_length(buffer, length + 1)
+         && NETTLE_BUFFER_PUTC(buffer, type)
+         && pgp_put_string(buffer, length, data));
+}
+
+void
+pgp_sub_packet_end(struct nettle_buffer *buffer, unsigned start)
+{
+  unsigned length;
+  
+  assert(start >= 2);
+  assert(start <= buffer->size);
+
+  length = buffer->size - start;
+  WRITE_UINT32(buffer->contents + start - 2, length);
+}
+
+int
+pgp_put_public_rsa_key(struct nettle_buffer *buffer,
+                      const struct rsa_public_key *pub,
+                      time_t timestamp)
+{
+  /* Public key packet, version 4 */
+  unsigned start;
+  unsigned length;
+
+  /* Size of packet is 16 + the size of e and n */
+  length = (4 * 4
+         + nettle_mpz_sizeinbase_256_u(pub->n)
+         + nettle_mpz_sizeinbase_256_u(pub->e));
+
+  if (!pgp_put_header(buffer, PGP_TAG_PUBLIC_KEY, length))
+    return 0;
+
+  start = buffer->size;
+  
+  if (! (pgp_put_header(buffer, PGP_TAG_PUBLIC_KEY,
+                       /* Assume that we need two octets */
+                       PGP_LENGTH_TWO_OCTETS)
+        && pgp_put_uint32(buffer, 4)        /* Version */  
+        && pgp_put_uint32(buffer, timestamp)/* Time stamp */
+        && pgp_put_uint32(buffer, PGP_RSA)  /* Algorithm */
+        && pgp_put_mpi(buffer, pub->n)
+        && pgp_put_mpi(buffer, pub->e)) )
+    return 0;
+
+  assert(buffer->size == start + length);
+
+  return 1;
+}
+
+int
+pgp_put_rsa_sha1_signature(struct nettle_buffer *buffer,
+                          const struct rsa_private_key *key,
+                          const uint8_t *keyid,
+                          unsigned type,
+                          struct sha1_ctx *hash)
+{
+  unsigned signature_start = buffer->size;
+  unsigned hash_end;
+  unsigned sub_packet_start;
+  uint8_t trailer[6];
+  uint8_t digest16[2];
+  mpz_t s;
+  
+  /* Signature packet. The packet could reasonably be both smaller and
+   * larger than 192, so for simplicity we use the 4 octet header
+   * form. */
+
+  if (! (pgp_put_header(buffer, PGP_TAG_SIGNATURE, PGP_LENGTH_FOUR_OCTETS)
+        && NETTLE_BUFFER_PUTC(buffer, 4)  /* Version */
+        && NETTLE_BUFFER_PUTC(buffer, type)
+        /* Could also be PGP_RSA_SIGN */
+        && NETTLE_BUFFER_PUTC(buffer, PGP_RSA)
+        && NETTLE_BUFFER_PUTC(buffer, PGP_SHA1)
+        && pgp_put_uint16(buffer, 0)))  /* Hashed subpacket length */
+    return 0;
+
+  hash_end = buffer->size;
+
+  sha1_update(hash,
+             hash_end - signature_start,
+             buffer->contents + signature_start);
+
+  trailer[0] = 4; trailer[1] = 0xff;
+  WRITE_UINT32(trailer + 2, buffer->size - signature_start);
+
+  sha1_update(hash, sizeof(trailer), trailer);
+
+  {
+    struct sha1_ctx hcopy = *hash;
+    uint8_t *p = nettle_buffer_space(buffer, 2);
+    if (!p)
+      return 0;
+    
+    sha1_digest(&hcopy, 2, p);
+  }
+
+  /* One "sub-packet" field with the issuer keyid */
+  sub_packet_start = pgp_sub_packet_start(buffer);
+  if (!sub_packet_start)
+    return 0;
+
+  if (pgp_put_sub_packet(buffer, PGP_SUBPACKET_ISSUER_KEY_ID, 8, keyid))
+    {
+      pgp_sub_packet_end(buffer, sub_packet_start);
+      return 0;
+    }
+    
+  mpz_init(s);
+  if (!(rsa_sha1_sign(key, hash, s)
+       && pgp_put_mpi(buffer, s)))
+    {
+      mpz_clear(s);
+      return 0;
+    }
+
+  mpz_clear(s);
+  pgp_put_header_length(buffer, signature_start, 4);
+
+  return 1;
+}
+
+#define CRC24_INIT 0x0b704ceL
+#define CRC24_POLY 0x1864cfbL
+
+uint32_t
+pgp_crc24(unsigned length, const uint8_t *data)
+{
+  uint32_t crc = CRC24_INIT;
+
+  unsigned i;
+  for (i = 0; i<length; i++)
+    {
+      unsigned j;
+      crc ^= ((unsigned) (data[i]) << 16);
+      for (j = 0; j<8; j++)
+       {
+         crc <<= 1;
+         if (crc & 0x1000000)
+           crc ^= CRC24_POLY;
+       }
+    }
+  assert(crc < 0x1000000);
+  return crc;
+}
+
+
+#define WRITE(buffer, s) (nettle_buffer_write(buffer, strlen((s)), (s)))
+
+/* 15 base 64 groups data per line */
+#define BINARY_PER_LINE 45
+#define TEXT_PER_LINE BASE64_ENCODE_LENGTH(BINARY_PER_LINE)
+
+int
+pgp_armor(struct nettle_buffer *buffer,
+         const char *tag,
+         unsigned length,
+         const uint8_t *data)
+{
+  struct base64_encode_ctx ctx;
+  
+  unsigned crc = pgp_crc24(length, data);
+
+  base64_encode_init(&ctx);
+  
+  if (! (WRITE(buffer, "BEGIN PGP ")
+        && WRITE(buffer, tag)
+        && WRITE(buffer, "\nComment: Nettle\n\n")))
+    return 0;
+
+  for (;
+       length >= BINARY_PER_LINE;
+       length -= BINARY_PER_LINE, data += BINARY_PER_LINE)
+    {
+      unsigned done;
+      uint8_t *p
+       = nettle_buffer_space(buffer, TEXT_PER_LINE);
+      
+      if (!p)
+       return 0;
+
+      done = base64_encode_update(&ctx, p, BINARY_PER_LINE, data);
+      assert(done <= TEXT_PER_LINE);
+
+      /* FIXME: Create some official way to do this */
+      buffer->size -= (TEXT_PER_LINE - done);
+      
+      if (!NETTLE_BUFFER_PUTC(buffer, '\n'))
+       return 0;
+    }
+
+  if (length)
+    {
+      unsigned text_size = BASE64_ENCODE_LENGTH(length)
+       + BASE64_ENCODE_FINAL_LENGTH;
+      unsigned done;
+      
+      uint8_t *p
+       = nettle_buffer_space(buffer, text_size);
+      if (!p)
+       return 0;
+
+      done = base64_encode_update(&ctx, p, length, data);
+      done += base64_encode_final(&ctx, p + done);
+
+      /* FIXME: Create some official way to do this */
+      buffer->size -= (text_size - done);
+      
+      if (!NETTLE_BUFFER_PUTC(buffer, '\n'))
+       return 0;
+    }
+  /* Checksum */
+  if (!NETTLE_BUFFER_PUTC(buffer, '='))
+    return 0;
+
+  {
+    uint8_t *p = nettle_buffer_space(buffer, 4);
+    if (!p)
+      return 0;
+    base64_encode_group(p, crc);
+  }
+  
+  return (WRITE(buffer, "\nBEGIN PGP ")
+         && WRITE(buffer, tag)
+         && NETTLE_BUFFER_PUTC(buffer, '\n'));
+}
diff --git a/pgp.h b/pgp.h
new file mode 100644 (file)
index 0000000..c2e20fe
--- /dev/null
+++ b/pgp.h
@@ -0,0 +1,240 @@
+/* pgp.h
+ *
+ * PGP related functions.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_PGP_H_INCLUDED
+#define NETTLE_PGP_H_INCLUDED
+
+#include <time.h>
+
+#include "nettle-types.h"
+#include "bignum.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define pgp_put_uint32 nettle_pgp_put_uint32
+#define pgp_put_uint16 nettle_pgp_put_uint16
+#define pgp_put_mpi nettle_pgp_put_mpi
+#define pgp_put_string nettle_pgp_put_string
+#define pgp_put_length nettle_pgp_put_length
+#define pgp_put_header nettle_pgp_put_header
+#define pgp_put_header_length nettle_pgp_put_header_length
+#define pgp_sub_packet_start nettle_pgp_sub_packet_start
+#define pgp_put_sub_packet nettle_pgp_put_sub_packet
+#define pgp_sub_packet_end nettle_pgp_sub_packet_end
+#define pgp_put_public_rsa_key nettle_pgp_put_public_rsa_key
+#define pgp_put_rsa_sha1_signature nettle_pgp_put_rsa_sha1_signature
+#define pgp_put_userid nettle_pgp_put_userid
+#define pgp_crc24 nettle_pgp_crc24
+#define pgp_armor nettle_pgp_armor
+
+struct nettle_buffer;
+struct rsa_public_key;
+struct rsa_private_key;
+struct sha1_ctx;
+
+int
+pgp_put_uint32(struct nettle_buffer *buffer, uint32_t i);
+
+int
+pgp_put_uint16(struct nettle_buffer *buffer, unsigned i);
+
+int
+pgp_put_mpi(struct nettle_buffer *buffer, const mpz_t x);
+
+int
+pgp_put_string(struct nettle_buffer *buffer,
+              unsigned length,
+              const uint8_t *s);
+
+int
+pgp_put_length(struct nettle_buffer *buffer,
+              unsigned length);
+
+int
+pgp_put_header(struct nettle_buffer *buffer,
+              unsigned tag, unsigned length);
+
+void
+pgp_put_header_length(struct nettle_buffer *buffer,
+                     /* start of the header */
+                     unsigned start,
+                     unsigned field_size);
+
+unsigned
+pgp_sub_packet_start(struct nettle_buffer *buffer);
+
+int
+pgp_put_sub_packet(struct nettle_buffer *buffer,
+                  unsigned type,
+                  unsigned length,
+                  const uint8_t *data);
+
+void
+pgp_sub_packet_end(struct nettle_buffer *buffer, unsigned start);
+
+int
+pgp_put_public_rsa_key(struct nettle_buffer *,
+                      const struct rsa_public_key *key,
+                      time_t timestamp);
+
+int
+pgp_put_rsa_sha1_signature(struct nettle_buffer *buffer,
+                          const struct rsa_private_key *key,
+                          const uint8_t *keyid,
+                          unsigned type,
+                          struct sha1_ctx *hash);
+
+int
+pgp_put_userid(struct nettle_buffer *buffer,
+              unsigned length,
+              const uint8_t *name);
+
+uint32_t
+pgp_crc24(unsigned length, const uint8_t *data);
+
+int
+pgp_armor(struct nettle_buffer *buffer,
+         const char *tag,
+         unsigned length,
+         const uint8_t *data);
+
+/* Values that can be passed to pgp_put_header when the size of the
+ * length field, but not the length itself, is known. Also the minimum length
+ * for the given field size. */
+enum pgp_lengths
+  {
+    PGP_LENGTH_ONE_OCTET = 0,
+    PGP_LENGTH_TWO_OCTETS = 192,
+    PGP_LENGTH_FOUR_OCTETS = 8384,
+  };
+
+enum pgp_public_key_algorithm
+  {
+    PGP_RSA = 1,
+    PGP_RSA_ENCRYPT = 2,
+    PGP_RSA_SIGN = 3,
+    PGP_EL_GAMAL_ENCRYPT = 16,
+    PGP_DSA = 17,
+    PGP_EL_GAMAL = 20,
+  };
+
+enum pgp_symmetric_algorithm
+  {
+    PGP_PLAINTEXT = 0,
+    PGP_IDEA = 1,
+    PGP_3DES = 2,
+    PGP_CAST5 = 3,
+    PGP_BLOWFISH = 4,
+    PGP_SAFER_SK = 5,
+    PGP_AES128 = 7,
+    PGP_AES192 = 8,
+    PGP_AES256 = 9,
+  };
+
+enum pgp_compression_algorithm
+  {
+    PGP_UNCOMPRESSED = 0,
+    PGP_ZIP = 1,
+    PGP_ZLIB = 2,
+  };
+
+enum pgp_hash_algorithm
+  {
+    PGP_MD5 = 1,
+    PGP_SHA1 = 2,
+    PGP_RIPEMD = 3,
+    PGP_MD2 = 5,
+    PGP_TIGER192 = 6,
+    PGP_HAVAL = 7,
+  };
+
+enum pgp_tag
+  {
+    PGP_TAG_PUBLIC_SESSION_KEY = 1,
+    PGP_TAG_SIGNATURE = 2,
+    PGP_TAG_SYMMETRIC_SESSION_KEY = 3,
+    PGP_TAG_ONE_PASS_SIGNATURE = 4,
+    PGP_TAG_SECRET_KEY = 5,
+    PGP_TAG_PUBLIC_KEY = 6,
+    PGP_TAG_SECRET_SUBKEY = 7,
+    PGP_TAG_COMPRESSED = 8,
+    PGP_TAG_ENCRYPTED = 9,
+    PGP_TAG_MARKER = 10,
+    PGP_TAG_LITERAL = 11,
+    PGP_TAG_TRUST = 12,
+    PGP_TAG_USERID = 13,
+    PGP_TAG_PUBLIC_SUBKEY = 14,
+  };
+
+enum pgp_signature_type
+  {
+    PGP_SIGN_BINARY = 0,
+    PGP_SIGN_TEXT = 1,
+    PGP_SIGN_STANDALONE = 2,
+    PGP_SIGN_CERTIFICATION = 0x10,
+    PGP_SIGN_CERTIFICATION_PERSONA = 0x11,
+    PGP_SIGN_CERTIFICATION_CASUAL = 0x12,
+    PGP_SIGN_CERTIFICATION_POSITIVE = 0x13,
+    PGP_SIGN_SUBKEY = 0x18,
+    PGP_SIGN_KEY = 0x1f,
+    PGP_SIGN_REVOCATION = 0x20,
+    PGP_SIGN_REVOCATION_SUBKEY = 0x28,
+    PGP_SIGN_REVOCATION_CERTIFICATE = 0x30,
+    PGP_SIGN_TIMESTAMP = 0x40,
+  };
+
+enum pgp_subpacket_tag
+  {
+    PGP_SUBPACKET_CREATION_TIME = 2,
+    PGP_SUBPACKET_SIGNATURE_EXPIRATION_TIME = 3,
+    PGP_SUBPACKET_EXPORTABLE_CERTIFICATION = 4,
+    PGP_SUBPACKET_TRUST_SIGNATURE = 5,
+    PGP_SUBPACKET_REGULAR_EXPRESSION = 6,
+    PGP_SUBPACKET_REVOCABLE = 7,
+    PGP_SUBPACKET_KEY_EXPIRATION_TIME = 9,
+    PGP_SUBPACKET_PLACEHOLDER = 10 ,
+    PGP_SUBPACKET_PREFERRED_SYMMETRIC_ALGORITHMS = 11,
+    PGP_SUBPACKET_REVOCATION_KEY = 12,
+    PGP_SUBPACKET_ISSUER_KEY_ID = 16,
+    PGP_SUBPACKET_NOTATION_DATA = 20,
+    PGP_SUBPACKET_PREFERRED_HASH_ALGORITHMS = 21,
+    PGP_SUBPACKET_PREFERRED_COMPRESSION_ALGORITHMS = 22,
+    PGP_SUBPACKET_KEY_SERVER_PREFERENCES = 23,
+    PGP_SUBPACKET_PREFERRED_KEY_SERVER = 24,
+    PGP_SUBPACKET_PRIMARY_USER_ID = 25,
+    PGP_SUBPACKET_POLICY_URL = 26,
+    PGP_SUBPACKET_KEY_FLAGS = 27,
+    PGP_SUBPACKET_SIGNERS_USER_ID = 28,
+    PGP_SUBPACKET_REASON_FOR_REVOCATION = 29,
+  };
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_PGP_H_INCLUDED */
diff --git a/pkcs1-rsa-md5.c b/pkcs1-rsa-md5.c
new file mode 100644 (file)
index 0000000..eff25fa
--- /dev/null
@@ -0,0 +1,100 @@
+/* pkcs1-rsa-md5.c
+ *
+ * PKCS stuff for rsa-md5.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "rsa.h"
+
+#include "bignum.h"
+#include "pkcs1.h"
+
+#include "nettle-internal.h"
+
+/* From pkcs-1v2
+ *
+ *   md5 OBJECT IDENTIFIER ::=
+ *     {iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 5}
+ *
+ * The parameters part of the algorithm identifier is NULL:
+ *
+ *   md5Identifier ::= AlgorithmIdentifier {md5, NULL}
+ */
+
+static const uint8_t
+md5_prefix[] =
+{
+  /* 18 octets prefix, 16 octets hash, 34 total. */
+  0x30,       32, /* SEQUENCE */
+    0x30,     12, /* SEQUENCE */
+      0x06,    8, /* OBJECT IDENTIFIER */
+       0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05,
+      0x05,    0, /* NULL */
+    0x04,     16  /* OCTET STRING */
+      /* Here comes the raw hash value */
+};
+
+int
+pkcs1_rsa_md5_encode(mpz_t m, unsigned size, struct md5_ctx *hash)
+{
+  TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8);
+  TMP_ALLOC(em, size);
+
+  if (pkcs1_signature_prefix(size, em,
+                            sizeof(md5_prefix),
+                            md5_prefix,
+                            MD5_DIGEST_SIZE))
+    {
+      md5_digest(hash, MD5_DIGEST_SIZE, em + size - MD5_DIGEST_SIZE);
+      nettle_mpz_set_str_256_u(m, size, em);
+      return 1;
+    }
+  else
+    return 0;
+}
+
+int
+pkcs1_rsa_md5_encode_digest(mpz_t m, unsigned size, const uint8_t *digest)
+{
+  TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8);
+  TMP_ALLOC(em, size);
+
+  if (pkcs1_signature_prefix(size, em,
+                            sizeof(md5_prefix),
+                            md5_prefix,
+                            MD5_DIGEST_SIZE))
+    {
+      memcpy(em + size - MD5_DIGEST_SIZE, digest, MD5_DIGEST_SIZE);
+      nettle_mpz_set_str_256_u(m, size, em);
+      return 1;
+    }
+  else
+    return 0;
+}
diff --git a/pkcs1-rsa-sha1.c b/pkcs1-rsa-sha1.c
new file mode 100644 (file)
index 0000000..85395bd
--- /dev/null
@@ -0,0 +1,100 @@
+/* pkcs1-rsa-sha1.c
+ *
+ * PKCS stuff for rsa-sha1.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "rsa.h"
+
+#include "bignum.h"
+#include "pkcs1.h"
+
+#include "nettle-internal.h"
+
+/* From pkcs-1v2
+ *
+ *   id-sha1 OBJECT IDENTIFIER ::=
+ *     {iso(1) identified-organization(3) oiw(14) secsig(3)
+ *      algorithms(2) 26}
+ *   
+ *   The default hash function is SHA-1: 
+ *   sha1Identifier ::= AlgorithmIdentifier {id-sha1, NULL}
+ */
+
+static const uint8_t
+sha1_prefix[] =
+{
+  /* 15 octets prefix, 20 octets hash, total 35 */
+  0x30,       33, /* SEQUENCE */
+    0x30,      9, /* SEQUENCE */
+      0x06,    5, /* OBJECT IDENTIFIER */
+         0x2b, 0x0e, 0x03, 0x02, 0x1a,
+      0x05,    0, /* NULL */
+    0x04,     20  /* OCTET STRING */
+      /* Here comes the raw hash value */
+};
+
+int
+pkcs1_rsa_sha1_encode(mpz_t m, unsigned size, struct sha1_ctx *hash)
+{
+  TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8);
+  TMP_ALLOC(em, size);
+
+  if (pkcs1_signature_prefix(size, em,
+                            sizeof(sha1_prefix),
+                            sha1_prefix,
+                            SHA1_DIGEST_SIZE))
+    {
+      sha1_digest(hash, SHA1_DIGEST_SIZE, em + size - SHA1_DIGEST_SIZE);
+      nettle_mpz_set_str_256_u(m, size, em);
+      return 1;
+    }
+  else
+    return 0;
+}
+
+int
+pkcs1_rsa_sha1_encode_digest(mpz_t m, unsigned size, const uint8_t *digest)
+{
+  TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8);
+  TMP_ALLOC(em, size);
+
+  if (pkcs1_signature_prefix(size, em,
+                            sizeof(sha1_prefix),
+                            sha1_prefix,
+                            SHA1_DIGEST_SIZE))
+    {
+      memcpy(em + size - SHA1_DIGEST_SIZE, digest, SHA1_DIGEST_SIZE);
+      nettle_mpz_set_str_256_u(m, size, em);
+      return 1;
+    }
+  else
+    return 0;
+}
diff --git a/pkcs1-rsa-sha256.c b/pkcs1-rsa-sha256.c
new file mode 100644 (file)
index 0000000..363f784
--- /dev/null
@@ -0,0 +1,98 @@
+/* pkcs1-rsa-sha256.c
+ *
+ * PKCS stuff for rsa-sha256.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2003, 2006 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "rsa.h"
+
+#include "bignum.h"
+#include "pkcs1.h"
+
+#include "nettle-internal.h"
+
+/* From RFC 3447, Public-Key Cryptography Standards (PKCS) #1: RSA
+ * Cryptography Specifications Version 2.1.
+ *
+ *     id-sha256    OBJECT IDENTIFIER ::=
+ *       {joint-iso-itu-t(2) country(16) us(840) organization(1)
+ *         gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1}
+ */
+
+static const uint8_t
+sha256_prefix[] =
+{
+  /* 19 octets prefix, 32 octets hash, total 51 */
+  0x30,      49, /* SEQUENCE */
+    0x30,    13, /* SEQUENCE */
+      0x06,   9, /* OBJECT IDENTIFIER */
+        0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
+      0x05,   0, /* NULL */
+    0x04,    32  /* OCTET STRING */
+      /* Here comes the raw hash value */
+};
+
+int
+pkcs1_rsa_sha256_encode(mpz_t m, unsigned size, struct sha256_ctx *hash)
+{
+  TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8);
+  TMP_ALLOC(em, size);
+
+  if (pkcs1_signature_prefix(size, em,
+                            sizeof(sha256_prefix),
+                            sha256_prefix,
+                            SHA256_DIGEST_SIZE))
+    {
+      sha256_digest(hash, SHA256_DIGEST_SIZE, em + size - SHA256_DIGEST_SIZE);
+      nettle_mpz_set_str_256_u(m, size, em);
+      return 1;
+    }
+  else
+    return 0;  
+}
+
+int
+pkcs1_rsa_sha256_encode_digest(mpz_t m, unsigned size, const uint8_t *digest)
+{
+  TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8);
+  TMP_ALLOC(em, size);
+
+  if (pkcs1_signature_prefix(size, em,
+                            sizeof(sha256_prefix),
+                            sha256_prefix,
+                            SHA256_DIGEST_SIZE))
+    {
+      memcpy(em + size - SHA256_DIGEST_SIZE, digest, SHA256_DIGEST_SIZE);
+      nettle_mpz_set_str_256_u(m, size, em);
+      return 1;
+    }
+  else
+    return 0;
+}
diff --git a/pkcs1-rsa-sha512.c b/pkcs1-rsa-sha512.c
new file mode 100644 (file)
index 0000000..8eb4377
--- /dev/null
@@ -0,0 +1,99 @@
+/* pkcs1-rsa-sha512.c
+ *
+ * PKCS stuff for rsa-sha512.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2003, 2006, 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "rsa.h"
+
+#include "bignum.h"
+#include "pkcs1.h"
+
+#include "nettle-internal.h"
+
+/* From RFC 3447, Public-Key Cryptography Standards (PKCS) #1: RSA
+ * Cryptography Specifications Version 2.1.
+ *
+ *     id-sha512    OBJECT IDENTIFIER ::=
+ *       {joint-iso-itu-t(2) country(16) us(840) organization(1)
+ *         gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3}
+ */
+
+static const uint8_t
+sha512_prefix[] =
+{
+  /* 19 octets prefix, 64 octets hash, total 83 */
+  0x30,      81, /* SEQUENCE */
+    0x30,    13, /* SEQUENCE */
+      0x06,   9, /* OBJECT IDENTIFIER */
+        0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
+      0x05,   0, /* NULL */
+    0x04,    64  /* OCTET STRING */
+      /* Here comes the raw hash value, 64 octets */
+};
+
+int
+pkcs1_rsa_sha512_encode(mpz_t m, unsigned size, struct sha512_ctx *hash)
+{
+  TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8);
+  TMP_ALLOC(em, size);
+
+  if (pkcs1_signature_prefix(size, em,
+                            sizeof(sha512_prefix),
+                            sha512_prefix,
+                            SHA512_DIGEST_SIZE))
+    {
+      sha512_digest(hash, SHA512_DIGEST_SIZE,
+                   em + size - SHA512_DIGEST_SIZE);
+      nettle_mpz_set_str_256_u(m, size, em);
+      return 1;
+    }
+  else
+    return 0;
+}
+
+int
+pkcs1_rsa_sha512_encode_digest(mpz_t m, unsigned size, const uint8_t *digest)
+{
+  TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8);
+  TMP_ALLOC(em, size);
+
+  if (pkcs1_signature_prefix(size, em,
+                            sizeof(sha512_prefix),
+                            sha512_prefix,
+                            SHA512_DIGEST_SIZE))
+    {
+      memcpy(em + size - SHA512_DIGEST_SIZE, digest, SHA512_DIGEST_SIZE);
+      nettle_mpz_set_str_256_u(m, size, em);
+      return 1;
+    }
+  else
+    return 0;
+}
diff --git a/pkcs1.c b/pkcs1.c
new file mode 100644 (file)
index 0000000..786ee63
--- /dev/null
+++ b/pkcs1.c
@@ -0,0 +1,64 @@
+/* pkcs1.c
+ *
+ * PKCS1 embedding.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <string.h>
+
+#include "pkcs1.h"
+
+/* Formats the PKCS#1 padding, of the form
+ *
+ *   0x01 0xff ... 0xff 0x00 id ...digest...
+ *
+ * where the 0xff ... 0xff part consists of at least 8 octets. The 
+ * total size should be one less than the octet size of n.
+ */
+int
+pkcs1_signature_prefix(unsigned size,
+                      uint8_t *buffer,
+                      unsigned id_size,
+                      const uint8_t *id,
+                      unsigned digest_size)
+{
+  unsigned j;
+  
+  if (size < 10 + id_size + digest_size)
+    return 0;
+
+  j = size - digest_size - id_size;
+
+  memcpy (buffer + j, id, id_size);
+  buffer[0] = 1;
+  buffer[--j] = 0;
+
+  assert(j >= 9);
+  memset(buffer + 1, 0xff, j - 1);
+
+  return 1;
+}
diff --git a/pkcs1.h b/pkcs1.h
new file mode 100644 (file)
index 0000000..a2d00ee
--- /dev/null
+++ b/pkcs1.h
@@ -0,0 +1,87 @@
+/* pkcs1.h
+ *
+ * PKCS1 embedding.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_PKCS1_H_INCLUDED
+#define NETTLE_PKCS1_H_INCLUDED
+
+#include <gmp.h>
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define pkcs1_signature_prefix nettle_pkcs1_signature_prefix
+#define pkcs1_rsa_md5_encode nettle_pkcs1_rsa_md5_encode
+#define pkcs1_rsa_md5_encode_digest nettle_pkcs1_rsa_md5_encode_digest
+#define pkcs1_rsa_sha1_encode nettle_pkcs1_rsa_sha1_encode
+#define pkcs1_rsa_sha1_encode_digest nettle_pkcs1_rsa_sha1_encode_digest
+#define pkcs1_rsa_sha256_encode nettle_pkcs1_rsa_sha256_encode
+#define pkcs1_rsa_sha256_encode_digest nettle_pkcs1_rsa_sha256_encode_digest
+#define pkcs1_rsa_sha512_encode nettle_pkcs1_rsa_sha512_encode
+#define pkcs1_rsa_sha512_encode_digest nettle_pkcs1_rsa_sha512_encode_digest
+
+struct md5_ctx;
+struct sha1_ctx;
+struct sha256_ctx;
+struct sha512_ctx;
+
+int
+pkcs1_signature_prefix(unsigned size,
+                      uint8_t *buffer,
+                      unsigned id_size,
+                      const uint8_t *id,
+                      unsigned digest_size);
+
+int
+pkcs1_rsa_md5_encode(mpz_t m, unsigned length, struct md5_ctx *hash);
+
+int
+pkcs1_rsa_md5_encode_digest(mpz_t m, unsigned length, const uint8_t *digest);
+
+int
+pkcs1_rsa_sha1_encode(mpz_t m, unsigned length, struct sha1_ctx *hash);
+
+int
+pkcs1_rsa_sha1_encode_digest(mpz_t m, unsigned length, const uint8_t *digest);
+
+int
+pkcs1_rsa_sha256_encode(mpz_t m, unsigned length, struct sha256_ctx *hash);
+
+int
+pkcs1_rsa_sha256_encode_digest(mpz_t m, unsigned length, const uint8_t *digest);
+
+int
+pkcs1_rsa_sha512_encode(mpz_t m, unsigned length, struct sha512_ctx *hash);
+
+int
+pkcs1_rsa_sha512_encode_digest(mpz_t m, unsigned length, const uint8_t *digest);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_PKCS1_H_INCLUDED */
diff --git a/prime-list.h b/prime-list.h
new file mode 100644 (file)
index 0000000..3645926
--- /dev/null
@@ -0,0 +1,656 @@
+
+3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 
+37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 
+79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 
+131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 
+181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 
+239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 
+293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 
+359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 
+421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 
+479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 
+557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 
+613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 
+673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 
+743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 
+821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 
+881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 
+953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 
+1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 
+1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 
+1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 
+1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 
+1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 
+1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 
+1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 
+1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 
+1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 
+1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 
+1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 
+1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 
+1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 
+1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 
+2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 
+2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 
+2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 
+2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 
+2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 
+2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 
+2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 
+2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 
+2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 
+2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 
+2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 
+2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 
+3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 
+3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 
+3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 
+3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 
+3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 
+3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 
+3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 
+3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3659, 
+3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 
+3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 
+3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 
+3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 
+4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 
+4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 
+4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 
+4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 
+4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 
+4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 
+4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 
+4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, 4663, 
+4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 
+4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 
+4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 
+4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 
+5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 
+5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 
+5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 
+5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 
+5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 
+5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 
+5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 
+5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, 
+5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, 
+5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 
+5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 
+5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 
+6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 
+6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 
+6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311, 
+6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 
+6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 
+6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 
+6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 
+6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 
+6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 
+6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 
+6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 
+7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 
+7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 
+7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 7307, 
+7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 
+7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 
+7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 
+7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 
+7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 
+7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 
+7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927, 
+7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 
+8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 
+8123, 8147, 8161, 8167, 8171, 8179, 8191, 8209, 8219, 8221, 
+8231, 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, 8293, 
+8297, 8311, 8317, 8329, 8353, 8363, 8369, 8377, 8387, 8389, 
+8419, 8423, 8429, 8431, 8443, 8447, 8461, 8467, 8501, 8513, 
+8521, 8527, 8537, 8539, 8543, 8563, 8573, 8581, 8597, 8599, 
+8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, 8681, 
+8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741, 8747, 
+8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831, 8837, 
+8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933, 
+8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 9013, 
+9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 
+9133, 9137, 9151, 9157, 9161, 9173, 9181, 9187, 9199, 9203, 
+9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283, 9293, 
+9311, 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, 9391, 
+9397, 9403, 9413, 9419, 9421, 9431, 9433, 9437, 9439, 9461, 
+9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 9533, 9539, 
+9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631, 9643, 
+9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, 9739, 
+9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817, 
+9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, 9901, 
+9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973, 10007, 10009, 
+10037, 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, 10103, 
+10111, 10133, 10139, 10141, 10151, 10159, 10163, 10169, 10177, 10181, 
+10193, 10211, 10223, 10243, 10247, 10253, 10259, 10267, 10271, 10273, 
+10289, 10301, 10303, 10313, 10321, 10331, 10333, 10337, 10343, 10357, 
+10369, 10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459, 10463, 
+10477, 10487, 10499, 10501, 10513, 10529, 10531, 10559, 10567, 10589, 
+10597, 10601, 10607, 10613, 10627, 10631, 10639, 10651, 10657, 10663, 
+10667, 10687, 10691, 10709, 10711, 10723, 10729, 10733, 10739, 10753, 
+10771, 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, 10861, 
+10867, 10883, 10889, 10891, 10903, 10909, 10937, 10939, 10949, 10957, 
+10973, 10979, 10987, 10993, 11003, 11027, 11047, 11057, 11059, 11069, 
+11071, 11083, 11087, 11093, 11113, 11117, 11119, 11131, 11149, 11159, 
+11161, 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251, 11257, 
+11261, 11273, 11279, 11287, 11299, 11311, 11317, 11321, 11329, 11351, 
+11353, 11369, 11383, 11393, 11399, 11411, 11423, 11437, 11443, 11447, 
+11467, 11471, 11483, 11489, 11491, 11497, 11503, 11519, 11527, 11549, 
+11551, 11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657, 11677, 
+11681, 11689, 11699, 11701, 11717, 11719, 11731, 11743, 11777, 11779, 
+11783, 11789, 11801, 11807, 11813, 11821, 11827, 11831, 11833, 11839, 
+11863, 11867, 11887, 11897, 11903, 11909, 11923, 11927, 11933, 11939, 
+11941, 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, 12037, 
+12041, 12043, 12049, 12071, 12073, 12097, 12101, 12107, 12109, 12113, 
+12119, 12143, 12149, 12157, 12161, 12163, 12197, 12203, 12211, 12227, 
+12239, 12241, 12251, 12253, 12263, 12269, 12277, 12281, 12289, 12301, 
+12323, 12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401, 12409, 
+12413, 12421, 12433, 12437, 12451, 12457, 12473, 12479, 12487, 12491, 
+12497, 12503, 12511, 12517, 12527, 12539, 12541, 12547, 12553, 12569, 
+12577, 12583, 12589, 12601, 12611, 12613, 12619, 12637, 12641, 12647, 
+12653, 12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739, 12743, 
+12757, 12763, 12781, 12791, 12799, 12809, 12821, 12823, 12829, 12841, 
+12853, 12889, 12893, 12899, 12907, 12911, 12917, 12919, 12923, 12941, 
+12953, 12959, 12967, 12973, 12979, 12983, 13001, 13003, 13007, 13009, 
+13033, 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, 13121, 
+13127, 13147, 13151, 13159, 13163, 13171, 13177, 13183, 13187, 13217, 
+13219, 13229, 13241, 13249, 13259, 13267, 13291, 13297, 13309, 13313, 
+13327, 13331, 13337, 13339, 13367, 13381, 13397, 13399, 13411, 13417, 
+13421, 13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499, 13513, 
+13523, 13537, 13553, 13567, 13577, 13591, 13597, 13613, 13619, 13627, 
+13633, 13649, 13669, 13679, 13681, 13687, 13691, 13693, 13697, 13709, 
+13711, 13721, 13723, 13729, 13751, 13757, 13759, 13763, 13781, 13789, 
+13799, 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879, 13883, 
+13901, 13903, 13907, 13913, 13921, 13931, 13933, 13963, 13967, 13997, 
+13999, 14009, 14011, 14029, 14033, 14051, 14057, 14071, 14081, 14083, 
+14087, 14107, 14143, 14149, 14153, 14159, 14173, 14177, 14197, 14207, 
+14221, 14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, 14327, 
+14341, 14347, 14369, 14387, 14389, 14401, 14407, 14411, 14419, 14423, 
+14431, 14437, 14447, 14449, 14461, 14479, 14489, 14503, 14519, 14533, 
+14537, 14543, 14549, 14551, 14557, 14561, 14563, 14591, 14593, 14621, 
+14627, 14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699, 14713, 
+14717, 14723, 14731, 14737, 14741, 14747, 14753, 14759, 14767, 14771, 
+14779, 14783, 14797, 14813, 14821, 14827, 14831, 14843, 14851, 14867, 
+14869, 14879, 14887, 14891, 14897, 14923, 14929, 14939, 14947, 14951, 
+14957, 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, 15077, 
+15083, 15091, 15101, 15107, 15121, 15131, 15137, 15139, 15149, 15161, 
+15173, 15187, 15193, 15199, 15217, 15227, 15233, 15241, 15259, 15263, 
+15269, 15271, 15277, 15287, 15289, 15299, 15307, 15313, 15319, 15329, 
+15331, 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401, 15413, 
+15427, 15439, 15443, 15451, 15461, 15467, 15473, 15493, 15497, 15511, 
+15527, 15541, 15551, 15559, 15569, 15581, 15583, 15601, 15607, 15619, 
+15629, 15641, 15643, 15647, 15649, 15661, 15667, 15671, 15679, 15683, 
+15727, 15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773, 15787, 
+15791, 15797, 15803, 15809, 15817, 15823, 15859, 15877, 15881, 15887, 
+15889, 15901, 15907, 15913, 15919, 15923, 15937, 15959, 15971, 15973, 
+15991, 16001, 16007, 16033, 16057, 16061, 16063, 16067, 16069, 16073, 
+16087, 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, 16187, 
+16189, 16193, 16217, 16223, 16229, 16231, 16249, 16253, 16267, 16273, 
+16301, 16319, 16333, 16339, 16349, 16361, 16363, 16369, 16381, 16411, 
+16417, 16421, 16427, 16433, 16447, 16451, 16453, 16477, 16481, 16487, 
+16493, 16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603, 16607, 
+16619, 16631, 16633, 16649, 16651, 16657, 16661, 16673, 16691, 16693, 
+16699, 16703, 16729, 16741, 16747, 16759, 16763, 16787, 16811, 16823, 
+16829, 16831, 16843, 16871, 16879, 16883, 16889, 16901, 16903, 16921, 
+16927, 16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993, 17011, 
+17021, 17027, 17029, 17033, 17041, 17047, 17053, 17077, 17093, 17099, 
+17107, 17117, 17123, 17137, 17159, 17167, 17183, 17189, 17191, 17203, 
+17207, 17209, 17231, 17239, 17257, 17291, 17293, 17299, 17317, 17321, 
+17327, 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, 17393, 
+17401, 17417, 17419, 17431, 17443, 17449, 17467, 17471, 17477, 17483, 
+17489, 17491, 17497, 17509, 17519, 17539, 17551, 17569, 17573, 17579, 
+17581, 17597, 17599, 17609, 17623, 17627, 17657, 17659, 17669, 17681, 
+17683, 17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783, 17789, 
+17791, 17807, 17827, 17837, 17839, 17851, 17863, 17881, 17891, 17903, 
+17909, 17911, 17921, 17923, 17929, 17939, 17957, 17959, 17971, 17977, 
+17981, 17987, 17989, 18013, 18041, 18043, 18047, 18049, 18059, 18061, 
+18077, 18089, 18097, 18119, 18121, 18127, 18131, 18133, 18143, 18149, 
+18169, 18181, 18191, 18199, 18211, 18217, 18223, 18229, 18233, 18251, 
+18253, 18257, 18269, 18287, 18289, 18301, 18307, 18311, 18313, 18329, 
+18341, 18353, 18367, 18371, 18379, 18397, 18401, 18413, 18427, 18433, 
+18439, 18443, 18451, 18457, 18461, 18481, 18493, 18503, 18517, 18521, 
+18523, 18539, 18541, 18553, 18583, 18587, 18593, 18617, 18637, 18661, 
+18671, 18679, 18691, 18701, 18713, 18719, 18731, 18743, 18749, 18757, 
+18773, 18787, 18793, 18797, 18803, 18839, 18859, 18869, 18899, 18911, 
+18913, 18917, 18919, 18947, 18959, 18973, 18979, 19001, 19009, 19013, 
+19031, 19037, 19051, 19069, 19073, 19079, 19081, 19087, 19121, 19139, 
+19141, 19157, 19163, 19181, 19183, 19207, 19211, 19213, 19219, 19231, 
+19237, 19249, 19259, 19267, 19273, 19289, 19301, 19309, 19319, 19333, 
+19373, 19379, 19381, 19387, 19391, 19403, 19417, 19421, 19423, 19427, 
+19429, 19433, 19441, 19447, 19457, 19463, 19469, 19471, 19477, 19483, 
+19489, 19501, 19507, 19531, 19541, 19543, 19553, 19559, 19571, 19577, 
+19583, 19597, 19603, 19609, 19661, 19681, 19687, 19697, 19699, 19709, 
+19717, 19727, 19739, 19751, 19753, 19759, 19763, 19777, 19793, 19801, 
+19813, 19819, 19841, 19843, 19853, 19861, 19867, 19889, 19891, 19913, 
+19919, 19927, 19937, 19949, 19961, 19963, 19973, 19979, 19991, 19993, 
+19997, 20011, 20021, 20023, 20029, 20047, 20051, 20063, 20071, 20089, 
+20101, 20107, 20113, 20117, 20123, 20129, 20143, 20147, 20149, 20161, 
+20173, 20177, 20183, 20201, 20219, 20231, 20233, 20249, 20261, 20269, 
+20287, 20297, 20323, 20327, 20333, 20341, 20347, 20353, 20357, 20359, 
+20369, 20389, 20393, 20399, 20407, 20411, 20431, 20441, 20443, 20477, 
+20479, 20483, 20507, 20509, 20521, 20533, 20543, 20549, 20551, 20563, 
+20593, 20599, 20611, 20627, 20639, 20641, 20663, 20681, 20693, 20707, 
+20717, 20719, 20731, 20743, 20747, 20749, 20753, 20759, 20771, 20773, 
+20789, 20807, 20809, 20849, 20857, 20873, 20879, 20887, 20897, 20899, 
+20903, 20921, 20929, 20939, 20947, 20959, 20963, 20981, 20983, 21001, 
+21011, 21013, 21017, 21019, 21023, 21031, 21059, 21061, 21067, 21089, 
+21101, 21107, 21121, 21139, 21143, 21149, 21157, 21163, 21169, 21179, 
+21187, 21191, 21193, 21211, 21221, 21227, 21247, 21269, 21277, 21283, 
+21313, 21317, 21319, 21323, 21341, 21347, 21377, 21379, 21383, 21391, 
+21397, 21401, 21407, 21419, 21433, 21467, 21481, 21487, 21491, 21493, 
+21499, 21503, 21517, 21521, 21523, 21529, 21557, 21559, 21563, 21569, 
+21577, 21587, 21589, 21599, 21601, 21611, 21613, 21617, 21647, 21649, 
+21661, 21673, 21683, 21701, 21713, 21727, 21737, 21739, 21751, 21757, 
+21767, 21773, 21787, 21799, 21803, 21817, 21821, 21839, 21841, 21851, 
+21859, 21863, 21871, 21881, 21893, 21911, 21929, 21937, 21943, 21961, 
+21977, 21991, 21997, 22003, 22013, 22027, 22031, 22037, 22039, 22051, 
+22063, 22067, 22073, 22079, 22091, 22093, 22109, 22111, 22123, 22129, 
+22133, 22147, 22153, 22157, 22159, 22171, 22189, 22193, 22229, 22247, 
+22259, 22271, 22273, 22277, 22279, 22283, 22291, 22303, 22307, 22343, 
+22349, 22367, 22369, 22381, 22391, 22397, 22409, 22433, 22441, 22447, 
+22453, 22469, 22481, 22483, 22501, 22511, 22531, 22541, 22543, 22549, 
+22567, 22571, 22573, 22613, 22619, 22621, 22637, 22639, 22643, 22651, 
+22669, 22679, 22691, 22697, 22699, 22709, 22717, 22721, 22727, 22739, 
+22741, 22751, 22769, 22777, 22783, 22787, 22807, 22811, 22817, 22853, 
+22859, 22861, 22871, 22877, 22901, 22907, 22921, 22937, 22943, 22961, 
+22963, 22973, 22993, 23003, 23011, 23017, 23021, 23027, 23029, 23039, 
+23041, 23053, 23057, 23059, 23063, 23071, 23081, 23087, 23099, 23117, 
+23131, 23143, 23159, 23167, 23173, 23189, 23197, 23201, 23203, 23209, 
+23227, 23251, 23269, 23279, 23291, 23293, 23297, 23311, 23321, 23327, 
+23333, 23339, 23357, 23369, 23371, 23399, 23417, 23431, 23447, 23459, 
+23473, 23497, 23509, 23531, 23537, 23539, 23549, 23557, 23561, 23563, 
+23567, 23581, 23593, 23599, 23603, 23609, 23623, 23627, 23629, 23633, 
+23663, 23669, 23671, 23677, 23687, 23689, 23719, 23741, 23743, 23747, 
+23753, 23761, 23767, 23773, 23789, 23801, 23813, 23819, 23827, 23831, 
+23833, 23857, 23869, 23873, 23879, 23887, 23893, 23899, 23909, 23911, 
+23917, 23929, 23957, 23971, 23977, 23981, 23993, 24001, 24007, 24019, 
+24023, 24029, 24043, 24049, 24061, 24071, 24077, 24083, 24091, 24097, 
+24103, 24107, 24109, 24113, 24121, 24133, 24137, 24151, 24169, 24179, 
+24181, 24197, 24203, 24223, 24229, 24239, 24247, 24251, 24281, 24317, 
+24329, 24337, 24359, 24371, 24373, 24379, 24391, 24407, 24413, 24419, 
+24421, 24439, 24443, 24469, 24473, 24481, 24499, 24509, 24517, 24527, 
+24533, 24547, 24551, 24571, 24593, 24611, 24623, 24631, 24659, 24671, 
+24677, 24683, 24691, 24697, 24709, 24733, 24749, 24763, 24767, 24781, 
+24793, 24799, 24809, 24821, 24841, 24847, 24851, 24859, 24877, 24889, 
+24907, 24917, 24919, 24923, 24943, 24953, 24967, 24971, 24977, 24979, 
+24989, 25013, 25031, 25033, 25037, 25057, 25073, 25087, 25097, 25111, 
+25117, 25121, 25127, 25147, 25153, 25163, 25169, 25171, 25183, 25189, 
+25219, 25229, 25237, 25243, 25247, 25253, 25261, 25301, 25303, 25307, 
+25309, 25321, 25339, 25343, 25349, 25357, 25367, 25373, 25391, 25409, 
+25411, 25423, 25439, 25447, 25453, 25457, 25463, 25469, 25471, 25523, 
+25537, 25541, 25561, 25577, 25579, 25583, 25589, 25601, 25603, 25609, 
+25621, 25633, 25639, 25643, 25657, 25667, 25673, 25679, 25693, 25703, 
+25717, 25733, 25741, 25747, 25759, 25763, 25771, 25793, 25799, 25801, 
+25819, 25841, 25847, 25849, 25867, 25873, 25889, 25903, 25913, 25919, 
+25931, 25933, 25939, 25943, 25951, 25969, 25981, 25997, 25999, 26003, 
+26017, 26021, 26029, 26041, 26053, 26083, 26099, 26107, 26111, 26113, 
+26119, 26141, 26153, 26161, 26171, 26177, 26183, 26189, 26203, 26209, 
+26227, 26237, 26249, 26251, 26261, 26263, 26267, 26293, 26297, 26309, 
+26317, 26321, 26339, 26347, 26357, 26371, 26387, 26393, 26399, 26407, 
+26417, 26423, 26431, 26437, 26449, 26459, 26479, 26489, 26497, 26501, 
+26513, 26539, 26557, 26561, 26573, 26591, 26597, 26627, 26633, 26641, 
+26647, 26669, 26681, 26683, 26687, 26693, 26699, 26701, 26711, 26713, 
+26717, 26723, 26729, 26731, 26737, 26759, 26777, 26783, 26801, 26813, 
+26821, 26833, 26839, 26849, 26861, 26863, 26879, 26881, 26891, 26893, 
+26903, 26921, 26927, 26947, 26951, 26953, 26959, 26981, 26987, 26993, 
+27011, 27017, 27031, 27043, 27059, 27061, 27067, 27073, 27077, 27091, 
+27103, 27107, 27109, 27127, 27143, 27179, 27191, 27197, 27211, 27239, 
+27241, 27253, 27259, 27271, 27277, 27281, 27283, 27299, 27329, 27337, 
+27361, 27367, 27397, 27407, 27409, 27427, 27431, 27437, 27449, 27457, 
+27479, 27481, 27487, 27509, 27527, 27529, 27539, 27541, 27551, 27581, 
+27583, 27611, 27617, 27631, 27647, 27653, 27673, 27689, 27691, 27697, 
+27701, 27733, 27737, 27739, 27743, 27749, 27751, 27763, 27767, 27773, 
+27779, 27791, 27793, 27799, 27803, 27809, 27817, 27823, 27827, 27847, 
+27851, 27883, 27893, 27901, 27917, 27919, 27941, 27943, 27947, 27953, 
+27961, 27967, 27983, 27997, 28001, 28019, 28027, 28031, 28051, 28057, 
+28069, 28081, 28087, 28097, 28099, 28109, 28111, 28123, 28151, 28163, 
+28181, 28183, 28201, 28211, 28219, 28229, 28277, 28279, 28283, 28289, 
+28297, 28307, 28309, 28319, 28349, 28351, 28387, 28393, 28403, 28409, 
+28411, 28429, 28433, 28439, 28447, 28463, 28477, 28493, 28499, 28513, 
+28517, 28537, 28541, 28547, 28549, 28559, 28571, 28573, 28579, 28591, 
+28597, 28603, 28607, 28619, 28621, 28627, 28631, 28643, 28649, 28657, 
+28661, 28663, 28669, 28687, 28697, 28703, 28711, 28723, 28729, 28751, 
+28753, 28759, 28771, 28789, 28793, 28807, 28813, 28817, 28837, 28843, 
+28859, 28867, 28871, 28879, 28901, 28909, 28921, 28927, 28933, 28949, 
+28961, 28979, 29009, 29017, 29021, 29023, 29027, 29033, 29059, 29063, 
+29077, 29101, 29123, 29129, 29131, 29137, 29147, 29153, 29167, 29173, 
+29179, 29191, 29201, 29207, 29209, 29221, 29231, 29243, 29251, 29269, 
+29287, 29297, 29303, 29311, 29327, 29333, 29339, 29347, 29363, 29383, 
+29387, 29389, 29399, 29401, 29411, 29423, 29429, 29437, 29443, 29453, 
+29473, 29483, 29501, 29527, 29531, 29537, 29567, 29569, 29573, 29581, 
+29587, 29599, 29611, 29629, 29633, 29641, 29663, 29669, 29671, 29683, 
+29717, 29723, 29741, 29753, 29759, 29761, 29789, 29803, 29819, 29833, 
+29837, 29851, 29863, 29867, 29873, 29879, 29881, 29917, 29921, 29927, 
+29947, 29959, 29983, 29989, 30011, 30013, 30029, 30047, 30059, 30071, 
+30089, 30091, 30097, 30103, 30109, 30113, 30119, 30133, 30137, 30139, 
+30161, 30169, 30181, 30187, 30197, 30203, 30211, 30223, 30241, 30253, 
+30259, 30269, 30271, 30293, 30307, 30313, 30319, 30323, 30341, 30347, 
+30367, 30389, 30391, 30403, 30427, 30431, 30449, 30467, 30469, 30491, 
+30493, 30497, 30509, 30517, 30529, 30539, 30553, 30557, 30559, 30577, 
+30593, 30631, 30637, 30643, 30649, 30661, 30671, 30677, 30689, 30697, 
+30703, 30707, 30713, 30727, 30757, 30763, 30773, 30781, 30803, 30809, 
+30817, 30829, 30839, 30841, 30851, 30853, 30859, 30869, 30871, 30881, 
+30893, 30911, 30931, 30937, 30941, 30949, 30971, 30977, 30983, 31013, 
+31019, 31033, 31039, 31051, 31063, 31069, 31079, 31081, 31091, 31121, 
+31123, 31139, 31147, 31151, 31153, 31159, 31177, 31181, 31183, 31189, 
+31193, 31219, 31223, 31231, 31237, 31247, 31249, 31253, 31259, 31267, 
+31271, 31277, 31307, 31319, 31321, 31327, 31333, 31337, 31357, 31379, 
+31387, 31391, 31393, 31397, 31469, 31477, 31481, 31489, 31511, 31513, 
+31517, 31531, 31541, 31543, 31547, 31567, 31573, 31583, 31601, 31607, 
+31627, 31643, 31649, 31657, 31663, 31667, 31687, 31699, 31721, 31723, 
+31727, 31729, 31741, 31751, 31769, 31771, 31793, 31799, 31817, 31847, 
+31849, 31859, 31873, 31883, 31891, 31907, 31957, 31963, 31973, 31981, 
+31991, 32003, 32009, 32027, 32029, 32051, 32057, 32059, 32063, 32069, 
+32077, 32083, 32089, 32099, 32117, 32119, 32141, 32143, 32159, 32173, 
+32183, 32189, 32191, 32203, 32213, 32233, 32237, 32251, 32257, 32261, 
+32297, 32299, 32303, 32309, 32321, 32323, 32327, 32341, 32353, 32359, 
+32363, 32369, 32371, 32377, 32381, 32401, 32411, 32413, 32423, 32429, 
+32441, 32443, 32467, 32479, 32491, 32497, 32503, 32507, 32531, 32533, 
+32537, 32561, 32563, 32569, 32573, 32579, 32587, 32603, 32609, 32611, 
+32621, 32633, 32647, 32653, 32687, 32693, 32707, 32713, 32717, 32719, 
+32749, 32771, 32779, 32783, 32789, 32797, 32801, 32803, 32831, 32833, 
+32839, 32843, 32869, 32887, 32909, 32911, 32917, 32933, 32939, 32941, 
+32957, 32969, 32971, 32983, 32987, 32993, 32999, 33013, 33023, 33029, 
+33037, 33049, 33053, 33071, 33073, 33083, 33091, 33107, 33113, 33119, 
+33149, 33151, 33161, 33179, 33181, 33191, 33199, 33203, 33211, 33223, 
+33247, 33287, 33289, 33301, 33311, 33317, 33329, 33331, 33343, 33347, 
+33349, 33353, 33359, 33377, 33391, 33403, 33409, 33413, 33427, 33457, 
+33461, 33469, 33479, 33487, 33493, 33503, 33521, 33529, 33533, 33547, 
+33563, 33569, 33577, 33581, 33587, 33589, 33599, 33601, 33613, 33617, 
+33619, 33623, 33629, 33637, 33641, 33647, 33679, 33703, 33713, 33721, 
+33739, 33749, 33751, 33757, 33767, 33769, 33773, 33791, 33797, 33809, 
+33811, 33827, 33829, 33851, 33857, 33863, 33871, 33889, 33893, 33911, 
+33923, 33931, 33937, 33941, 33961, 33967, 33997, 34019, 34031, 34033, 
+34039, 34057, 34061, 34123, 34127, 34129, 34141, 34147, 34157, 34159, 
+34171, 34183, 34211, 34213, 34217, 34231, 34253, 34259, 34261, 34267, 
+34273, 34283, 34297, 34301, 34303, 34313, 34319, 34327, 34337, 34351, 
+34361, 34367, 34369, 34381, 34403, 34421, 34429, 34439, 34457, 34469, 
+34471, 34483, 34487, 34499, 34501, 34511, 34513, 34519, 34537, 34543, 
+34549, 34583, 34589, 34591, 34603, 34607, 34613, 34631, 34649, 34651, 
+34667, 34673, 34679, 34687, 34693, 34703, 34721, 34729, 34739, 34747, 
+34757, 34759, 34763, 34781, 34807, 34819, 34841, 34843, 34847, 34849, 
+34871, 34877, 34883, 34897, 34913, 34919, 34939, 34949, 34961, 34963, 
+34981, 35023, 35027, 35051, 35053, 35059, 35069, 35081, 35083, 35089, 
+35099, 35107, 35111, 35117, 35129, 35141, 35149, 35153, 35159, 35171, 
+35201, 35221, 35227, 35251, 35257, 35267, 35279, 35281, 35291, 35311, 
+35317, 35323, 35327, 35339, 35353, 35363, 35381, 35393, 35401, 35407, 
+35419, 35423, 35437, 35447, 35449, 35461, 35491, 35507, 35509, 35521, 
+35527, 35531, 35533, 35537, 35543, 35569, 35573, 35591, 35593, 35597, 
+35603, 35617, 35671, 35677, 35729, 35731, 35747, 35753, 35759, 35771, 
+35797, 35801, 35803, 35809, 35831, 35837, 35839, 35851, 35863, 35869, 
+35879, 35897, 35899, 35911, 35923, 35933, 35951, 35963, 35969, 35977, 
+35983, 35993, 35999, 36007, 36011, 36013, 36017, 36037, 36061, 36067, 
+36073, 36083, 36097, 36107, 36109, 36131, 36137, 36151, 36161, 36187, 
+36191, 36209, 36217, 36229, 36241, 36251, 36263, 36269, 36277, 36293, 
+36299, 36307, 36313, 36319, 36341, 36343, 36353, 36373, 36383, 36389, 
+36433, 36451, 36457, 36467, 36469, 36473, 36479, 36493, 36497, 36523, 
+36527, 36529, 36541, 36551, 36559, 36563, 36571, 36583, 36587, 36599, 
+36607, 36629, 36637, 36643, 36653, 36671, 36677, 36683, 36691, 36697, 
+36709, 36713, 36721, 36739, 36749, 36761, 36767, 36779, 36781, 36787, 
+36791, 36793, 36809, 36821, 36833, 36847, 36857, 36871, 36877, 36887, 
+36899, 36901, 36913, 36919, 36923, 36929, 36931, 36943, 36947, 36973, 
+36979, 36997, 37003, 37013, 37019, 37021, 37039, 37049, 37057, 37061, 
+37087, 37097, 37117, 37123, 37139, 37159, 37171, 37181, 37189, 37199, 
+37201, 37217, 37223, 37243, 37253, 37273, 37277, 37307, 37309, 37313, 
+37321, 37337, 37339, 37357, 37361, 37363, 37369, 37379, 37397, 37409, 
+37423, 37441, 37447, 37463, 37483, 37489, 37493, 37501, 37507, 37511, 
+37517, 37529, 37537, 37547, 37549, 37561, 37567, 37571, 37573, 37579, 
+37589, 37591, 37607, 37619, 37633, 37643, 37649, 37657, 37663, 37691, 
+37693, 37699, 37717, 37747, 37781, 37783, 37799, 37811, 37813, 37831, 
+37847, 37853, 37861, 37871, 37879, 37889, 37897, 37907, 37951, 37957, 
+37963, 37967, 37987, 37991, 37993, 37997, 38011, 38039, 38047, 38053, 
+38069, 38083, 38113, 38119, 38149, 38153, 38167, 38177, 38183, 38189, 
+38197, 38201, 38219, 38231, 38237, 38239, 38261, 38273, 38281, 38287, 
+38299, 38303, 38317, 38321, 38327, 38329, 38333, 38351, 38371, 38377, 
+38393, 38431, 38447, 38449, 38453, 38459, 38461, 38501, 38543, 38557, 
+38561, 38567, 38569, 38593, 38603, 38609, 38611, 38629, 38639, 38651, 
+38653, 38669, 38671, 38677, 38693, 38699, 38707, 38711, 38713, 38723, 
+38729, 38737, 38747, 38749, 38767, 38783, 38791, 38803, 38821, 38833, 
+38839, 38851, 38861, 38867, 38873, 38891, 38903, 38917, 38921, 38923, 
+38933, 38953, 38959, 38971, 38977, 38993, 39019, 39023, 39041, 39043, 
+39047, 39079, 39089, 39097, 39103, 39107, 39113, 39119, 39133, 39139, 
+39157, 39161, 39163, 39181, 39191, 39199, 39209, 39217, 39227, 39229, 
+39233, 39239, 39241, 39251, 39293, 39301, 39313, 39317, 39323, 39341, 
+39343, 39359, 39367, 39371, 39373, 39383, 39397, 39409, 39419, 39439, 
+39443, 39451, 39461, 39499, 39503, 39509, 39511, 39521, 39541, 39551, 
+39563, 39569, 39581, 39607, 39619, 39623, 39631, 39659, 39667, 39671, 
+39679, 39703, 39709, 39719, 39727, 39733, 39749, 39761, 39769, 39779, 
+39791, 39799, 39821, 39827, 39829, 39839, 39841, 39847, 39857, 39863, 
+39869, 39877, 39883, 39887, 39901, 39929, 39937, 39953, 39971, 39979, 
+39983, 39989, 40009, 40013, 40031, 40037, 40039, 40063, 40087, 40093, 
+40099, 40111, 40123, 40127, 40129, 40151, 40153, 40163, 40169, 40177, 
+40189, 40193, 40213, 40231, 40237, 40241, 40253, 40277, 40283, 40289, 
+40343, 40351, 40357, 40361, 40387, 40423, 40427, 40429, 40433, 40459, 
+40471, 40483, 40487, 40493, 40499, 40507, 40519, 40529, 40531, 40543, 
+40559, 40577, 40583, 40591, 40597, 40609, 40627, 40637, 40639, 40693, 
+40697, 40699, 40709, 40739, 40751, 40759, 40763, 40771, 40787, 40801, 
+40813, 40819, 40823, 40829, 40841, 40847, 40849, 40853, 40867, 40879, 
+40883, 40897, 40903, 40927, 40933, 40939, 40949, 40961, 40973, 40993, 
+41011, 41017, 41023, 41039, 41047, 41051, 41057, 41077, 41081, 41113, 
+41117, 41131, 41141, 41143, 41149, 41161, 41177, 41179, 41183, 41189, 
+41201, 41203, 41213, 41221, 41227, 41231, 41233, 41243, 41257, 41263, 
+41269, 41281, 41299, 41333, 41341, 41351, 41357, 41381, 41387, 41389, 
+41399, 41411, 41413, 41443, 41453, 41467, 41479, 41491, 41507, 41513, 
+41519, 41521, 41539, 41543, 41549, 41579, 41593, 41597, 41603, 41609, 
+41611, 41617, 41621, 41627, 41641, 41647, 41651, 41659, 41669, 41681, 
+41687, 41719, 41729, 41737, 41759, 41761, 41771, 41777, 41801, 41809, 
+41813, 41843, 41849, 41851, 41863, 41879, 41887, 41893, 41897, 41903, 
+41911, 41927, 41941, 41947, 41953, 41957, 41959, 41969, 41981, 41983, 
+41999, 42013, 42017, 42019, 42023, 42043, 42061, 42071, 42073, 42083, 
+42089, 42101, 42131, 42139, 42157, 42169, 42179, 42181, 42187, 42193, 
+42197, 42209, 42221, 42223, 42227, 42239, 42257, 42281, 42283, 42293, 
+42299, 42307, 42323, 42331, 42337, 42349, 42359, 42373, 42379, 42391, 
+42397, 42403, 42407, 42409, 42433, 42437, 42443, 42451, 42457, 42461, 
+42463, 42467, 42473, 42487, 42491, 42499, 42509, 42533, 42557, 42569, 
+42571, 42577, 42589, 42611, 42641, 42643, 42649, 42667, 42677, 42683, 
+42689, 42697, 42701, 42703, 42709, 42719, 42727, 42737, 42743, 42751, 
+42767, 42773, 42787, 42793, 42797, 42821, 42829, 42839, 42841, 42853, 
+42859, 42863, 42899, 42901, 42923, 42929, 42937, 42943, 42953, 42961, 
+42967, 42979, 42989, 43003, 43013, 43019, 43037, 43049, 43051, 43063, 
+43067, 43093, 43103, 43117, 43133, 43151, 43159, 43177, 43189, 43201, 
+43207, 43223, 43237, 43261, 43271, 43283, 43291, 43313, 43319, 43321, 
+43331, 43391, 43397, 43399, 43403, 43411, 43427, 43441, 43451, 43457, 
+43481, 43487, 43499, 43517, 43541, 43543, 43573, 43577, 43579, 43591, 
+43597, 43607, 43609, 43613, 43627, 43633, 43649, 43651, 43661, 43669, 
+43691, 43711, 43717, 43721, 43753, 43759, 43777, 43781, 43783, 43787, 
+43789, 43793, 43801, 43853, 43867, 43889, 43891, 43913, 43933, 43943, 
+43951, 43961, 43963, 43969, 43973, 43987, 43991, 43997, 44017, 44021, 
+44027, 44029, 44041, 44053, 44059, 44071, 44087, 44089, 44101, 44111, 
+44119, 44123, 44129, 44131, 44159, 44171, 44179, 44189, 44201, 44203, 
+44207, 44221, 44249, 44257, 44263, 44267, 44269, 44273, 44279, 44281, 
+44293, 44351, 44357, 44371, 44381, 44383, 44389, 44417, 44449, 44453, 
+44483, 44491, 44497, 44501, 44507, 44519, 44531, 44533, 44537, 44543, 
+44549, 44563, 44579, 44587, 44617, 44621, 44623, 44633, 44641, 44647, 
+44651, 44657, 44683, 44687, 44699, 44701, 44711, 44729, 44741, 44753, 
+44771, 44773, 44777, 44789, 44797, 44809, 44819, 44839, 44843, 44851, 
+44867, 44879, 44887, 44893, 44909, 44917, 44927, 44939, 44953, 44959, 
+44963, 44971, 44983, 44987, 45007, 45013, 45053, 45061, 45077, 45083, 
+45119, 45121, 45127, 45131, 45137, 45139, 45161, 45179, 45181, 45191, 
+45197, 45233, 45247, 45259, 45263, 45281, 45289, 45293, 45307, 45317, 
+45319, 45329, 45337, 45341, 45343, 45361, 45377, 45389, 45403, 45413, 
+45427, 45433, 45439, 45481, 45491, 45497, 45503, 45523, 45533, 45541, 
+45553, 45557, 45569, 45587, 45589, 45599, 45613, 45631, 45641, 45659, 
+45667, 45673, 45677, 45691, 45697, 45707, 45737, 45751, 45757, 45763, 
+45767, 45779, 45817, 45821, 45823, 45827, 45833, 45841, 45853, 45863, 
+45869, 45887, 45893, 45943, 45949, 45953, 45959, 45971, 45979, 45989, 
+46021, 46027, 46049, 46051, 46061, 46073, 46091, 46093, 46099, 46103, 
+46133, 46141, 46147, 46153, 46171, 46181, 46183, 46187, 46199, 46219, 
+46229, 46237, 46261, 46271, 46273, 46279, 46301, 46307, 46309, 46327, 
+46337, 46349, 46351, 46381, 46399, 46411, 46439, 46441, 46447, 46451, 
+46457, 46471, 46477, 46489, 46499, 46507, 46511, 46523, 46549, 46559, 
+46567, 46573, 46589, 46591, 46601, 46619, 46633, 46639, 46643, 46649, 
+46663, 46679, 46681, 46687, 46691, 46703, 46723, 46727, 46747, 46751, 
+46757, 46769, 46771, 46807, 46811, 46817, 46819, 46829, 46831, 46853, 
+46861, 46867, 46877, 46889, 46901, 46919, 46933, 46957, 46993, 46997, 
+47017, 47041, 47051, 47057, 47059, 47087, 47093, 47111, 47119, 47123, 
+47129, 47137, 47143, 47147, 47149, 47161, 47189, 47207, 47221, 47237, 
+47251, 47269, 47279, 47287, 47293, 47297, 47303, 47309, 47317, 47339, 
+47351, 47353, 47363, 47381, 47387, 47389, 47407, 47417, 47419, 47431, 
+47441, 47459, 47491, 47497, 47501, 47507, 47513, 47521, 47527, 47533, 
+47543, 47563, 47569, 47581, 47591, 47599, 47609, 47623, 47629, 47639, 
+47653, 47657, 47659, 47681, 47699, 47701, 47711, 47713, 47717, 47737, 
+47741, 47743, 47777, 47779, 47791, 47797, 47807, 47809, 47819, 47837, 
+47843, 47857, 47869, 47881, 47903, 47911, 47917, 47933, 47939, 47947, 
+47951, 47963, 47969, 47977, 47981, 48017, 48023, 48029, 48049, 48073, 
+48079, 48091, 48109, 48119, 48121, 48131, 48157, 48163, 48179, 48187, 
+48193, 48197, 48221, 48239, 48247, 48259, 48271, 48281, 48299, 48311, 
+48313, 48337, 48341, 48353, 48371, 48383, 48397, 48407, 48409, 48413, 
+48437, 48449, 48463, 48473, 48479, 48481, 48487, 48491, 48497, 48523, 
+48527, 48533, 48539, 48541, 48563, 48571, 48589, 48593, 48611, 48619, 
+48623, 48647, 48649, 48661, 48673, 48677, 48679, 48731, 48733, 48751, 
+48757, 48761, 48767, 48779, 48781, 48787, 48799, 48809, 48817, 48821, 
+48823, 48847, 48857, 48859, 48869, 48871, 48883, 48889, 48907, 48947, 
+48953, 48973, 48989, 48991, 49003, 49009, 49019, 49031, 49033, 49037, 
+49043, 49057, 49069, 49081, 49103, 49109, 49117, 49121, 49123, 49139, 
+49157, 49169, 49171, 49177, 49193, 49199, 49201, 49207, 49211, 49223, 
+49253, 49261, 49277, 49279, 49297, 49307, 49331, 49333, 49339, 49363, 
+49367, 49369, 49391, 49393, 49409, 49411, 49417, 49429, 49433, 49451, 
+49459, 49463, 49477, 49481, 49499, 49523, 49529, 49531, 49537, 49547, 
+49549, 49559, 49597, 49603, 49613, 49627, 49633, 49639, 49663, 49667, 
+49669, 49681, 49697, 49711, 49727, 49739, 49741, 49747, 49757, 49783, 
+49787, 49789, 49801, 49807, 49811, 49823, 49831, 49843, 49853, 49871, 
+49877, 49891, 49919, 49921, 49927, 49937, 49939, 49943, 49957, 49991, 
+49993, 49999, 50021, 50023, 50033, 50047, 50051, 50053, 50069, 50077, 
+50087, 50093, 50101, 50111, 50119, 50123, 50129, 50131, 50147, 50153, 
+50159, 50177, 50207, 50221, 50227, 50231, 50261, 50263, 50273, 50287, 
+50291, 50311, 50321, 50329, 50333, 50341, 50359, 50363, 50377, 50383, 
+50387, 50411, 50417, 50423, 50441, 50459, 50461, 50497, 50503, 50513, 
+50527, 50539, 50543, 50549, 50551, 50581, 50587, 50591, 50593, 50599, 
+50627, 50647, 50651, 50671, 50683, 50707, 50723, 50741, 50753, 50767, 
+50773, 50777, 50789, 50821, 50833, 50839, 50849, 50857, 50867, 50873, 
+50891, 50893, 50909, 50923, 50929, 50951, 50957, 50969, 50971, 50989, 
+50993, 51001, 51031, 51043, 51047, 51059, 51061, 51071, 51109, 51131, 
+51133, 51137, 51151, 51157, 51169, 51193, 51197, 51199, 51203, 51217, 
+51229, 51239, 51241, 51257, 51263, 51283, 51287, 51307, 51329, 51341, 
+51343, 51347, 51349, 51361, 51383, 51407, 51413, 51419, 51421, 51427, 
+51431, 51437, 51439, 51449, 51461, 51473, 51479, 51481, 51487, 51503, 
+51511, 51517, 51521, 51539, 51551, 51563, 51577, 51581, 51593, 51599, 
+51607, 51613, 51631, 51637, 51647, 51659, 51673, 51679, 51683, 51691, 
+51713, 51719, 51721, 51749, 51767, 51769, 51787, 51797, 51803, 51817, 
+51827, 51829, 51839, 51853, 51859, 51869, 51871, 51893, 51899, 51907, 
+51913, 51929, 51941, 51949, 51971, 51973, 51977, 51991, 52009, 52021, 
+52027, 52051, 52057, 52067, 52069, 52081, 52103, 52121, 52127, 52147, 
+52153, 52163, 52177, 52181, 52183, 52189, 52201, 52223, 52237, 52249, 
+52253, 52259, 52267, 52289, 52291, 52301, 52313, 52321, 52361, 52363, 
+52369, 52379, 52387, 52391, 52433, 52453, 52457, 52489, 52501, 52511, 
+52517, 52529, 52541, 52543, 52553, 52561, 52567, 52571, 52579, 52583, 
+52609, 52627, 52631, 52639, 52667, 52673, 52691, 52697, 52709, 52711, 
+52721, 52727, 52733, 52747, 52757, 52769, 52783, 52807, 52813, 52817, 
+52837, 52859, 52861, 52879, 52883, 52889, 52901, 52903, 52919, 52937, 
+52951, 52957, 52963, 52967, 52973, 52981, 52999, 53003, 53017, 53047, 
+53051, 53069, 53077, 53087, 53089, 53093, 53101, 53113, 53117, 53129, 
+53147, 53149, 53161, 53171, 53173, 53189, 53197, 53201, 53231, 53233, 
+53239, 53267, 53269, 53279, 53281, 53299, 53309, 53323, 53327, 53353, 
+53359, 53377, 53381, 53401, 53407, 53411, 53419, 53437, 53441, 53453, 
+53479, 53503, 53507, 53527, 53549, 53551, 53569, 53591, 53593, 53597, 
+53609, 53611, 53617, 53623, 53629, 53633, 53639, 53653, 53657, 53681, 
+53693, 53699, 53717, 53719, 53731, 53759, 53773, 53777, 53783, 53791, 
+53813, 53819, 53831, 53849, 53857, 53861, 53881, 53887, 53891, 53897, 
+53899, 53917, 53923, 53927, 53939, 53951, 53959, 53987, 53993, 54001, 
+54011, 54013, 54037, 54049, 54059, 54083, 54091, 54101, 54121, 54133, 
+54139, 54151, 54163, 54167, 54181, 54193, 54217, 54251, 54269, 54277, 
+54287, 54293, 54311, 54319, 54323, 54331, 54347, 54361, 54367, 54371, 
+54377, 54401, 54403, 54409, 54413, 54419, 54421, 54437, 54443, 54449, 
+54469, 54493, 54497, 54499, 54503, 54517, 54521, 54539, 54541, 54547, 
+54559, 54563, 54577, 54581, 54583, 54601, 54617, 54623, 54629, 54631, 
+54647, 54667, 54673, 54679, 54709, 54713, 54721, 54727, 54751, 54767, 
+54773, 54779, 54787, 54799, 54829, 54833, 54851, 54869, 54877, 54881, 
+54907, 54917, 54919, 54941, 54949, 54959, 54973, 54979, 54983, 55001, 
+55009, 55021, 55049, 55051, 55057, 55061, 55073, 55079, 55103, 55109, 
+55117, 55127, 55147, 55163, 55171, 55201, 55207, 55213, 55217, 55219, 
+55229, 55243, 55249, 55259, 55291, 55313, 55331, 55333, 55337, 55339, 
+55343, 55351, 55373, 55381, 55399, 55411, 55439, 55441, 55457, 55469, 
+55487, 55501, 55511, 55529, 55541, 55547, 55579, 55589, 55603, 55609, 
+55619, 55621, 55631, 55633, 55639, 55661, 55663, 55667, 55673, 55681, 
+55691, 55697, 55711, 55717, 55721, 55733, 55763, 55787, 55793, 55799, 
+55807, 55813, 55817, 55819, 55823, 55829, 55837, 55843, 55849, 55871, 
+55889, 55897, 55901, 55903, 55921, 55927, 55931, 55933, 55949, 55967, 
+55987, 55997, 56003, 56009, 56039, 56041, 56053, 56081, 56087, 56093, 
+56099, 56101, 56113, 56123, 56131, 56149, 56167, 56171, 56179, 56197, 
+56207, 56209, 56237, 56239, 56249, 56263, 56267, 56269, 56299, 56311, 
+56333, 56359, 56369, 56377, 56383, 56393, 56401, 56417, 56431, 56437, 
+56443, 56453, 56467, 56473, 56477, 56479, 56489, 56501, 56503, 56509, 
+56519, 56527, 56531, 56533, 56543, 56569, 56591, 56597, 56599, 56611, 
+56629, 56633, 56659, 56663, 56671, 56681, 56687, 56701, 56711, 56713, 
+56731, 56737, 56747, 56767, 56773, 56779, 56783, 56807, 56809, 56813, 
+56821, 56827, 56843, 56857, 56873, 56891, 56893, 56897, 56909, 56911, 
+56921, 56923, 56929, 56941, 56951, 56957, 56963, 56983, 56989, 56993, 
+56999, 57037, 57041, 57047, 57059, 57073, 57077, 57089, 57097, 57107, 
+57119, 57131, 57139, 57143, 57149, 57163, 57173, 57179, 57191, 57193, 
+57203, 57221, 57223, 57241, 57251, 57259, 57269, 57271, 57283, 57287, 
+57301, 57329, 57331, 57347, 57349, 57367, 57373, 57383, 57389, 57397, 
+57413, 57427, 57457, 57467, 57487, 57493, 57503, 57527, 57529, 57557, 
+57559, 57571, 57587, 57593, 57601, 57637, 57641, 57649, 57653, 57667, 
+57679, 57689, 57697, 57709, 57713, 57719, 57727, 57731, 57737, 57751, 
+57773, 57781, 57787, 57791, 57793, 57803, 57809, 57829, 57839, 57847, 
+57853, 57859, 57881, 57899, 57901, 57917, 57923, 57943, 57947, 57973, 
+57977, 57991, 58013, 58027, 58031, 58043, 58049, 58057, 58061, 58067, 
+58073, 58099, 58109, 58111, 58129, 58147, 58151, 58153, 58169, 58171, 
+58189, 58193, 58199, 58207, 58211, 58217, 58229, 58231, 58237, 58243, 
+58271, 58309, 58313, 58321, 58337, 58363, 58367, 58369, 58379, 58391, 
+58393, 58403, 58411, 58417, 58427, 58439, 58441, 58451, 58453, 58477, 
+58481, 58511, 58537, 58543, 58549, 58567, 58573, 58579, 58601, 58603, 
+58613, 58631, 58657, 58661, 58679, 58687, 58693, 58699, 58711, 58727, 
+58733, 58741, 58757, 58763, 58771, 58787, 58789, 58831, 58889, 58897, 
+58901, 58907, 58909, 58913, 58921, 58937, 58943, 58963, 58967, 58979, 
+58991, 58997, 59009, 59011, 59021, 59023, 59029, 59051, 59053, 59063, 
+59069, 59077, 59083, 59093, 59107, 59113, 59119, 59123, 59141, 59149, 
+59159, 59167, 59183, 59197, 59207, 59209, 59219, 59221, 59233, 59239, 
+59243, 59263, 59273, 59281, 59333, 59341, 59351, 59357, 59359, 59369, 
+59377, 59387, 59393, 59399, 59407, 59417, 59419, 59441, 59443, 59447, 
+59453, 59467, 59471, 59473, 59497, 59509, 59513, 59539, 59557, 59561, 
+59567, 59581, 59611, 59617, 59621, 59627, 59629, 59651, 59659, 59663, 
+59669, 59671, 59693, 59699, 59707, 59723, 59729, 59743, 59747, 59753, 
+59771, 59779, 59791, 59797, 59809, 59833, 59863, 59879, 59887, 59921, 
+59929, 59951, 59957, 59971, 59981, 59999, 60013, 60017, 60029, 60037, 
+60041, 60077, 60083, 60089, 60091, 60101, 60103, 60107, 60127, 60133, 
+60139, 60149, 60161, 60167, 60169, 60209, 60217, 60223, 60251, 60257, 
+60259, 60271, 60289, 60293, 60317, 60331, 60337, 60343, 60353, 60373, 
+60383, 60397, 60413, 60427, 60443, 60449, 60457, 60493, 60497, 60509, 
+60521, 60527, 60539, 60589, 60601, 60607, 60611, 60617, 60623, 60631, 
+60637, 60647, 60649, 60659, 60661, 60679, 60689, 60703, 60719, 60727, 
+60733, 60737, 60757, 60761, 60763, 60773, 60779, 60793, 60811, 60821, 
+60859, 60869, 60887, 60889, 60899, 60901, 60913, 60917, 60919, 60923, 
+60937, 60943, 60953, 60961, 61001, 61007, 61027, 61031, 61043, 61051, 
+61057, 61091, 61099, 61121, 61129, 61141, 61151, 61153, 61169, 61211, 
+61223, 61231, 61253, 61261, 61283, 61291, 61297, 61331, 61333, 61339, 
+61343, 61357, 61363, 61379, 61381, 61403, 61409, 61417, 61441, 61463, 
+61469, 61471, 61483, 61487, 61493, 61507, 61511, 61519, 61543, 61547, 
+61553, 61559, 61561, 61583, 61603, 61609, 61613, 61627, 61631, 61637, 
+61643, 61651, 61657, 61667, 61673, 61681, 61687, 61703, 61717, 61723, 
+61729, 61751, 61757, 61781, 61813, 61819, 61837, 61843, 61861, 61871, 
+61879, 61909, 61927, 61933, 61949, 61961, 61967, 61979, 61981, 61987, 
+61991, 62003, 62011, 62017, 62039, 62047, 62053, 62057, 62071, 62081, 
+62099, 62119, 62129, 62131, 62137, 62141, 62143, 62171, 62189, 62191, 
+62201, 62207, 62213, 62219, 62233, 62273, 62297, 62299, 62303, 62311, 
+62323, 62327, 62347, 62351, 62383, 62401, 62417, 62423, 62459, 62467, 
+62473, 62477, 62483, 62497, 62501, 62507, 62533, 62539, 62549, 62563, 
+62581, 62591, 62597, 62603, 62617, 62627, 62633, 62639, 62653, 62659, 
+62683, 62687, 62701, 62723, 62731, 62743, 62753, 62761, 62773, 62791, 
+62801, 62819, 62827, 62851, 62861, 62869, 62873, 62897, 62903, 62921, 
+62927, 62929, 62939, 62969, 62971, 62981, 62983, 62987, 62989, 63029, 
+63031, 63059, 63067, 63073, 63079, 63097, 63103, 63113, 63127, 63131, 
+63149, 63179, 63197, 63199, 63211, 63241, 63247, 63277, 63281, 63299, 
+63311, 63313, 63317, 63331, 63337, 63347, 63353, 63361, 63367, 63377, 
+63389, 63391, 63397, 63409, 63419, 63421, 63439, 63443, 63463, 63467, 
+63473, 63487, 63493, 63499, 63521, 63527, 63533, 63541, 63559, 63577, 
+63587, 63589, 63599, 63601, 63607, 63611, 63617, 63629, 63647, 63649, 
+63659, 63667, 63671, 63689, 63691, 63697, 63703, 63709, 63719, 63727, 
+63737, 63743, 63761, 63773, 63781, 63793, 63799, 63803, 63809, 63823, 
+63839, 63841, 63853, 63857, 63863, 63901, 63907, 63913, 63929, 63949, 
+63977, 63997, 64007, 64013, 64019, 64033, 64037, 64063, 64067, 64081, 
+64091, 64109, 64123, 64151, 64153, 64157, 64171, 64187, 64189, 64217, 
+64223, 64231, 64237, 64271, 64279, 64283, 64301, 64303, 64319, 64327, 
+64333, 64373, 64381, 64399, 64403, 64433, 64439, 64451, 64453, 64483, 
+64489, 64499, 64513, 64553, 64567, 64577, 64579, 64591, 64601, 64609, 
+64613, 64621, 64627, 64633, 64661, 64663, 64667, 64679, 64693, 64709, 
+64717, 64747, 64763, 64781, 64783, 64793, 64811, 64817, 64849, 64853, 
+64871, 64877, 64879, 64891, 64901, 64919, 64921, 64927, 64937, 64951, 
+64969, 64997, 65003, 65011, 65027, 65029, 65033, 65053, 65063, 65071, 
+65089, 65099, 65101, 65111, 65119, 65123, 65129, 65141, 65147, 65167, 
+65171, 65173, 65179, 65183, 65203, 65213, 65239, 65257, 65267, 65269, 
+65287, 65293, 65309, 65323, 65327, 65353, 65357, 65371, 65381, 65393, 
+65407, 65413, 65419, 65423, 65437, 65447, 65449, 65479, 65497, 65519, 
+65521, 
diff --git a/realloc.c b/realloc.c
new file mode 100644 (file)
index 0000000..57e6d42
--- /dev/null
+++ b/realloc.c
@@ -0,0 +1,50 @@
+/* realloc.c
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "realloc.h"
+
+void *
+nettle_realloc(void *ctx UNUSED, void *p, unsigned length)
+{
+  return realloc(p, length);
+}
+
+void *
+nettle_xrealloc(void *ctx UNUSED, void *p, unsigned length)
+{
+  void *n = realloc(p, length);
+  if (length && !n)
+    {
+      fprintf(stderr, "Virtual memory exhausted.\n");
+      abort();
+    }
+  return n;
+}
diff --git a/realloc.h b/realloc.h
new file mode 100644 (file)
index 0000000..5406ec8
--- /dev/null
+++ b/realloc.h
@@ -0,0 +1,41 @@
+/* realloc.h
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_REALLOC_H_INCLUDED
+#define NETTLE_REALLOC_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+nettle_realloc_func nettle_realloc;
+nettle_realloc_func nettle_xrealloc;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_REALLOC_H_INCLUDED */
diff --git a/ripemd160-compress.c b/ripemd160-compress.c
new file mode 100644 (file)
index 0000000..66b25b2
--- /dev/null
@@ -0,0 +1,266 @@
+/* ripemd160-compress.c  -  RIPE-MD160 (Transform function) */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+
+#include "ripemd160.h"
+
+#include "macros.h"
+
+/****************
+ * Rotate the 32 bit unsigned integer X by N bits left
+ */
+
+#define ROL32(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
+
+
+/****************
+ * Transform the message X which consists of 16 32-bit-words
+ */
+void
+_nettle_ripemd160_compress(uint32_t *state, const uint8_t *data)
+{
+  register uint32_t a,b,c,d,e;
+  uint32_t aa,bb,cc,dd,ee,t;
+  uint32_t x[16];
+
+#ifdef WORDS_BIGENDIAN
+  {
+    int i;
+    for (i=0; i < 16; i++, data += 4 )
+      x[i] = LE_READ_UINT32(data);
+  }
+#else
+  /* memcpy seems a bit faster. Benchmarked on Intel SU4100, it makes
+     the entire update function roughly 6% faster. */
+  memcpy(x, data, sizeof(x));
+#endif
+
+
+#define K0  0x00000000
+#define K1  0x5A827999
+#define K2  0x6ED9EBA1
+#define K3  0x8F1BBCDC
+#define K4  0xA953FD4E
+#define KK0 0x50A28BE6
+#define KK1 0x5C4DD124
+#define KK2 0x6D703EF3
+#define KK3 0x7A6D76E9
+#define KK4 0x00000000
+#define F0(x,y,z)   ( (x) ^ (y) ^ (z) )
+#define F1(x,y,z)   ( ((x) & (y)) | (~(x) & (z)) )
+#define F2(x,y,z)   ( ((x) | ~(y)) ^ (z) )
+#define F3(x,y,z)   ( ((x) & (z)) | ((y) & ~(z)) )
+#define F4(x,y,z)   ( (x) ^ ((y) | ~(z)) )
+#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \
+          a = ROL32(t,s) + e;        \
+          c = ROL32(c,10);         \
+        } while(0)
+
+  /* left lane */
+  a = state[0];
+  b = state[1];
+  c = state[2];
+  d = state[3];
+  e = state[4];
+  R( a, b, c, d, e, F0, K0,  0, 11 );
+  R( e, a, b, c, d, F0, K0,  1, 14 );
+  R( d, e, a, b, c, F0, K0,  2, 15 );
+  R( c, d, e, a, b, F0, K0,  3, 12 );
+  R( b, c, d, e, a, F0, K0,  4,  5 );
+  R( a, b, c, d, e, F0, K0,  5,  8 );
+  R( e, a, b, c, d, F0, K0,  6,  7 );
+  R( d, e, a, b, c, F0, K0,  7,  9 );
+  R( c, d, e, a, b, F0, K0,  8, 11 );
+  R( b, c, d, e, a, F0, K0,  9, 13 );
+  R( a, b, c, d, e, F0, K0, 10, 14 );
+  R( e, a, b, c, d, F0, K0, 11, 15 );
+  R( d, e, a, b, c, F0, K0, 12,  6 );
+  R( c, d, e, a, b, F0, K0, 13,  7 );
+  R( b, c, d, e, a, F0, K0, 14,  9 );
+  R( a, b, c, d, e, F0, K0, 15,  8 );
+  R( e, a, b, c, d, F1, K1,  7,  7 );
+  R( d, e, a, b, c, F1, K1,  4,  6 );
+  R( c, d, e, a, b, F1, K1, 13,  8 );
+  R( b, c, d, e, a, F1, K1,  1, 13 );
+  R( a, b, c, d, e, F1, K1, 10, 11 );
+  R( e, a, b, c, d, F1, K1,  6,  9 );
+  R( d, e, a, b, c, F1, K1, 15,  7 );
+  R( c, d, e, a, b, F1, K1,  3, 15 );
+  R( b, c, d, e, a, F1, K1, 12,  7 );
+  R( a, b, c, d, e, F1, K1,  0, 12 );
+  R( e, a, b, c, d, F1, K1,  9, 15 );
+  R( d, e, a, b, c, F1, K1,  5,  9 );
+  R( c, d, e, a, b, F1, K1,  2, 11 );
+  R( b, c, d, e, a, F1, K1, 14,  7 );
+  R( a, b, c, d, e, F1, K1, 11, 13 );
+  R( e, a, b, c, d, F1, K1,  8, 12 );
+  R( d, e, a, b, c, F2, K2,  3, 11 );
+  R( c, d, e, a, b, F2, K2, 10, 13 );
+  R( b, c, d, e, a, F2, K2, 14,  6 );
+  R( a, b, c, d, e, F2, K2,  4,  7 );
+  R( e, a, b, c, d, F2, K2,  9, 14 );
+  R( d, e, a, b, c, F2, K2, 15,  9 );
+  R( c, d, e, a, b, F2, K2,  8, 13 );
+  R( b, c, d, e, a, F2, K2,  1, 15 );
+  R( a, b, c, d, e, F2, K2,  2, 14 );
+  R( e, a, b, c, d, F2, K2,  7,  8 );
+  R( d, e, a, b, c, F2, K2,  0, 13 );
+  R( c, d, e, a, b, F2, K2,  6,  6 );
+  R( b, c, d, e, a, F2, K2, 13,  5 );
+  R( a, b, c, d, e, F2, K2, 11, 12 );
+  R( e, a, b, c, d, F2, K2,  5,  7 );
+  R( d, e, a, b, c, F2, K2, 12,  5 );
+  R( c, d, e, a, b, F3, K3,  1, 11 );
+  R( b, c, d, e, a, F3, K3,  9, 12 );
+  R( a, b, c, d, e, F3, K3, 11, 14 );
+  R( e, a, b, c, d, F3, K3, 10, 15 );
+  R( d, e, a, b, c, F3, K3,  0, 14 );
+  R( c, d, e, a, b, F3, K3,  8, 15 );
+  R( b, c, d, e, a, F3, K3, 12,  9 );
+  R( a, b, c, d, e, F3, K3,  4,  8 );
+  R( e, a, b, c, d, F3, K3, 13,  9 );
+  R( d, e, a, b, c, F3, K3,  3, 14 );
+  R( c, d, e, a, b, F3, K3,  7,  5 );
+  R( b, c, d, e, a, F3, K3, 15,  6 );
+  R( a, b, c, d, e, F3, K3, 14,  8 );
+  R( e, a, b, c, d, F3, K3,  5,  6 );
+  R( d, e, a, b, c, F3, K3,  6,  5 );
+  R( c, d, e, a, b, F3, K3,  2, 12 );
+  R( b, c, d, e, a, F4, K4,  4,  9 );
+  R( a, b, c, d, e, F4, K4,  0, 15 );
+  R( e, a, b, c, d, F4, K4,  5,  5 );
+  R( d, e, a, b, c, F4, K4,  9, 11 );
+  R( c, d, e, a, b, F4, K4,  7,  6 );
+  R( b, c, d, e, a, F4, K4, 12,  8 );
+  R( a, b, c, d, e, F4, K4,  2, 13 );
+  R( e, a, b, c, d, F4, K4, 10, 12 );
+  R( d, e, a, b, c, F4, K4, 14,  5 );
+  R( c, d, e, a, b, F4, K4,  1, 12 );
+  R( b, c, d, e, a, F4, K4,  3, 13 );
+  R( a, b, c, d, e, F4, K4,  8, 14 );
+  R( e, a, b, c, d, F4, K4, 11, 11 );
+  R( d, e, a, b, c, F4, K4,  6,  8 );
+  R( c, d, e, a, b, F4, K4, 15,  5 );
+  R( b, c, d, e, a, F4, K4, 13,  6 );
+
+  aa = a; bb = b; cc = c; dd = d; ee = e;
+
+  /* right lane */
+  a = state[0];
+  b = state[1];
+  c = state[2];
+  d = state[3];
+  e = state[4];
+  R( a, b, c, d, e, F4, KK0,  5,  8);
+  R( e, a, b, c, d, F4, KK0, 14,  9);
+  R( d, e, a, b, c, F4, KK0,  7,  9);
+  R( c, d, e, a, b, F4, KK0,  0, 11);
+  R( b, c, d, e, a, F4, KK0,  9, 13);
+  R( a, b, c, d, e, F4, KK0,  2, 15);
+  R( e, a, b, c, d, F4, KK0, 11, 15);
+  R( d, e, a, b, c, F4, KK0,  4,  5);
+  R( c, d, e, a, b, F4, KK0, 13,  7);
+  R( b, c, d, e, a, F4, KK0,  6,  7);
+  R( a, b, c, d, e, F4, KK0, 15,  8);
+  R( e, a, b, c, d, F4, KK0,  8, 11);
+  R( d, e, a, b, c, F4, KK0,  1, 14);
+  R( c, d, e, a, b, F4, KK0, 10, 14);
+  R( b, c, d, e, a, F4, KK0,  3, 12);
+  R( a, b, c, d, e, F4, KK0, 12,  6);
+  R( e, a, b, c, d, F3, KK1,  6,  9);
+  R( d, e, a, b, c, F3, KK1, 11, 13);
+  R( c, d, e, a, b, F3, KK1,  3, 15);
+  R( b, c, d, e, a, F3, KK1,  7,  7);
+  R( a, b, c, d, e, F3, KK1,  0, 12);
+  R( e, a, b, c, d, F3, KK1, 13,  8);
+  R( d, e, a, b, c, F3, KK1,  5,  9);
+  R( c, d, e, a, b, F3, KK1, 10, 11);
+  R( b, c, d, e, a, F3, KK1, 14,  7);
+  R( a, b, c, d, e, F3, KK1, 15,  7);
+  R( e, a, b, c, d, F3, KK1,  8, 12);
+  R( d, e, a, b, c, F3, KK1, 12,  7);
+  R( c, d, e, a, b, F3, KK1,  4,  6);
+  R( b, c, d, e, a, F3, KK1,  9, 15);
+  R( a, b, c, d, e, F3, KK1,  1, 13);
+  R( e, a, b, c, d, F3, KK1,  2, 11);
+  R( d, e, a, b, c, F2, KK2, 15,  9);
+  R( c, d, e, a, b, F2, KK2,  5,  7);
+  R( b, c, d, e, a, F2, KK2,  1, 15);
+  R( a, b, c, d, e, F2, KK2,  3, 11);
+  R( e, a, b, c, d, F2, KK2,  7,  8);
+  R( d, e, a, b, c, F2, KK2, 14,  6);
+  R( c, d, e, a, b, F2, KK2,  6,  6);
+  R( b, c, d, e, a, F2, KK2,  9, 14);
+  R( a, b, c, d, e, F2, KK2, 11, 12);
+  R( e, a, b, c, d, F2, KK2,  8, 13);
+  R( d, e, a, b, c, F2, KK2, 12,  5);
+  R( c, d, e, a, b, F2, KK2,  2, 14);
+  R( b, c, d, e, a, F2, KK2, 10, 13);
+  R( a, b, c, d, e, F2, KK2,  0, 13);
+  R( e, a, b, c, d, F2, KK2,  4,  7);
+  R( d, e, a, b, c, F2, KK2, 13,  5);
+  R( c, d, e, a, b, F1, KK3,  8, 15);
+  R( b, c, d, e, a, F1, KK3,  6,  5);
+  R( a, b, c, d, e, F1, KK3,  4,  8);
+  R( e, a, b, c, d, F1, KK3,  1, 11);
+  R( d, e, a, b, c, F1, KK3,  3, 14);
+  R( c, d, e, a, b, F1, KK3, 11, 14);
+  R( b, c, d, e, a, F1, KK3, 15,  6);
+  R( a, b, c, d, e, F1, KK3,  0, 14);
+  R( e, a, b, c, d, F1, KK3,  5,  6);
+  R( d, e, a, b, c, F1, KK3, 12,  9);
+  R( c, d, e, a, b, F1, KK3,  2, 12);
+  R( b, c, d, e, a, F1, KK3, 13,  9);
+  R( a, b, c, d, e, F1, KK3,  9, 12);
+  R( e, a, b, c, d, F1, KK3,  7,  5);
+  R( d, e, a, b, c, F1, KK3, 10, 15);
+  R( c, d, e, a, b, F1, KK3, 14,  8);
+  R( b, c, d, e, a, F0, KK4, 12,  8);
+  R( a, b, c, d, e, F0, KK4, 15,  5);
+  R( e, a, b, c, d, F0, KK4, 10, 12);
+  R( d, e, a, b, c, F0, KK4,  4,  9);
+  R( c, d, e, a, b, F0, KK4,  1, 12);
+  R( b, c, d, e, a, F0, KK4,  5,  5);
+  R( a, b, c, d, e, F0, KK4,  8, 14);
+  R( e, a, b, c, d, F0, KK4,  7,  6);
+  R( d, e, a, b, c, F0, KK4,  6,  8);
+  R( c, d, e, a, b, F0, KK4,  2, 13);
+  R( b, c, d, e, a, F0, KK4, 13,  6);
+  R( a, b, c, d, e, F0, KK4, 14,  5);
+  R( e, a, b, c, d, F0, KK4,  0, 15);
+  R( d, e, a, b, c, F0, KK4,  3, 13);
+  R( c, d, e, a, b, F0, KK4,  9, 11);
+  R( b, c, d, e, a, F0, KK4, 11, 11);
+
+
+  t    = state[1] + d + cc;
+  state[1] = state[2] + e + dd;
+  state[2] = state[3] + a + ee;
+  state[3] = state[4] + b + aa;
+  state[4] = state[0] + c + bb;
+  state[0] = t;
+}
diff --git a/ripemd160-meta.c b/ripemd160-meta.c
new file mode 100644 (file)
index 0000000..80f6985
--- /dev/null
@@ -0,0 +1,32 @@
+/* ripemd160-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2011 Andres Mejia
+ *
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "ripemd160.h"
+
+const struct nettle_hash nettle_ripemd160
+= _NETTLE_HASH(ripemd160, RIPEMD160);
diff --git a/ripemd160.c b/ripemd160.c
new file mode 100644 (file)
index 0000000..ffcecc3
--- /dev/null
@@ -0,0 +1,193 @@
+/* ripemd160.c  -  RIPE-MD160 */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ * Copyright (C) 2011 Niels Möller
+ *
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+#include <assert.h>
+
+#include "ripemd160.h"
+
+#include "macros.h"
+#include "nettle-write.h"
+
+/*********************************
+ * RIPEMD-160 is not patented, see (as of 2011-08-28)
+ *   http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
+ * Note that the code uses Little Endian byteorder, which is good for
+ * 386 etc, but we must add some conversion when used on a big endian box.
+ *
+ *
+ * Pseudo-code for RIPEMD-160
+ *
+ * RIPEMD-160 is an iterative hash function that operates on 32-bit words.
+ * The round function takes as input a 5-word chaining variable and a 16-word
+ * message block and maps this to a new chaining variable. All operations are
+ * defined on 32-bit words. Padding is identical to that of MD4.
+ *
+ *
+ * RIPEMD-160: definitions
+ *
+ *
+ *   nonlinear functions at bit level: exor, mux, -, mux, -
+ *
+ *   f(j, x, y, z) = x XOR y XOR z      (0 <= j <= 15)
+ *   f(j, x, y, z) = (x AND y) OR (NOT(x) AND z)  (16 <= j <= 31)
+ *   f(j, x, y, z) = (x OR NOT(y)) XOR z    (32 <= j <= 47)
+ *   f(j, x, y, z) = (x AND z) OR (y AND NOT(z))  (48 <= j <= 63)
+ *   f(j, x, y, z) = x XOR (y OR NOT(z))    (64 <= j <= 79)
+ *
+ *
+ *   added constants (hexadecimal)
+ *
+ *   K(j) = 0x00000000      (0 <= j <= 15)
+ *   K(j) = 0x5A827999     (16 <= j <= 31)  int(2**30 x sqrt(2))
+ *   K(j) = 0x6ED9EBA1     (32 <= j <= 47)  int(2**30 x sqrt(3))
+ *   K(j) = 0x8F1BBCDC     (48 <= j <= 63)  int(2**30 x sqrt(5))
+ *   K(j) = 0xA953FD4E     (64 <= j <= 79)  int(2**30 x sqrt(7))
+ *   K'(j) = 0x50A28BE6     (0 <= j <= 15)      int(2**30 x cbrt(2))
+ *   K'(j) = 0x5C4DD124    (16 <= j <= 31)      int(2**30 x cbrt(3))
+ *   K'(j) = 0x6D703EF3    (32 <= j <= 47)      int(2**30 x cbrt(5))
+ *   K'(j) = 0x7A6D76E9    (48 <= j <= 63)      int(2**30 x cbrt(7))
+ *   K'(j) = 0x00000000    (64 <= j <= 79)
+ *
+ *
+ *   selection of message word
+ *
+ *   r(j)      = j          (0 <= j <= 15)
+ *   r(16..31) = 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8
+ *   r(32..47) = 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12
+ *   r(48..63) = 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2
+ *   r(64..79) = 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
+ *   r0(0..15) = 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12
+ *   r0(16..31)= 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2
+ *   r0(32..47)= 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13
+ *   r0(48..63)= 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14
+ *   r0(64..79)= 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
+ *
+ *
+ *   amount for rotate left (rol)
+ *
+ *   s(0..15)  = 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8
+ *   s(16..31) = 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12
+ *   s(32..47) = 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5
+ *   s(48..63) = 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12
+ *   s(64..79) = 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
+ *   s'(0..15) = 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6
+ *   s'(16..31)= 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11
+ *   s'(32..47)= 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5
+ *   s'(48..63)= 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8
+ *   s'(64..79)= 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
+ *
+ *
+ *   initial value (hexadecimal)
+ *
+ *   h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476;
+ *              h4 = 0xC3D2E1F0;
+ *
+ *
+ * RIPEMD-160: pseudo-code
+ *
+ *   It is assumed that the message after padding consists of t 16-word blocks
+ *   that will be denoted with X[i][j], with 0 <= i <= t-1 and 0 <= j <= 15.
+ *   The symbol [+] denotes addition modulo 2**32 and rol_s denotes cyclic left
+ *   shift (rotate) over s positions.
+ *
+ *
+ *   for i := 0 to t-1 {
+ *   A := h0; B := h1; C := h2; D = h3; E = h4;
+ *   A' := h0; B' := h1; C' := h2; D' = h3; E' = h4;
+ *   for j := 0 to 79 {
+ *       T := rol_s(j)(A [+] f(j, B, C, D) [+] X[i][r(j)] [+] K(j)) [+] E;
+ *       A := E; E := D; D := rol_10(C); C := B; B := T;
+ *       T := rol_s'(j)(A' [+] f(79-j, B', C', D') [+] X[i][r'(j)]
+                   [+] K'(j)) [+] E';
+ *       A' := E'; E' := D'; D' := rol_10(C'); C' := B'; B' := T;
+ *   }
+ *   T := h1 [+] C [+] D'; h1 := h2 [+] D [+] E'; h2 := h3 [+] E [+] A';
+ *   h3 := h4 [+] A [+] B'; h4 := h0 [+] B [+] C'; h0 := T;
+ *   }
+ */
+
+/* Some examples:
+ * ""                    9c1185a5c5e9fc54612808977ee8f548b2258d31
+ * "a"                   0bdc9d2d256b3ee9daae347be6f4dc835a467ffe
+ * "abc"                 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc
+ * "message digest"      5d0689ef49d2fae572b881b123a85ffa21595f36
+ * "a...z"               f71c27109c692c1b56bbdceb5b9d2865b3708dbc
+ * "abcdbcde...nopq"     12a053384a9c0c88e405a06c27dcf49ada62eb2b
+ * "A...Za...z0...9"     b0e20b6e3116640286ed3a87a5713079b21f5189
+ * 8 times "1234567890"  9b752e45573d4b39f4dbd3323cab82bf63326bfb
+ * 1 million times "a"   52783243c1697bdbe16d37f97f68f08325dc1528
+ */
+
+void
+ripemd160_init(struct ripemd160_ctx *ctx)
+{
+  static const uint32_t iv[_RIPEMD160_DIGEST_LENGTH] =
+    {
+      0x67452301,
+      0xEFCDAB89,
+      0x98BADCFE,
+      0x10325476,
+      0xC3D2E1F0,
+    };
+  memcpy(ctx->state, iv, sizeof(ctx->state));
+  ctx->count_low = ctx->count_high = 0;
+  ctx->index = 0;
+}
+
+#define COMPRESS(ctx, data) (_nettle_ripemd160_compress((ctx)->state, (data)))
+
+/* Update the message digest with the contents
+ * of DATA with length LENGTH.
+ */
+void
+ripemd160_update(struct ripemd160_ctx *ctx, unsigned length, const uint8_t *data)
+{
+  MD_UPDATE(ctx, length, data, COMPRESS, MD_INCR(ctx));
+}
+
+void
+ripemd160_digest(struct ripemd160_ctx *ctx, unsigned length, uint8_t *digest)
+{
+  uint32_t high, low;
+
+  assert(length <= RIPEMD160_DIGEST_SIZE);
+
+  MD_PAD(ctx, 8, COMPRESS);
+
+  /* There are 2^9 bits in one block */
+  high = (ctx->count_high << 9) | (ctx->count_low >> 23);
+  low = (ctx->count_low << 9) | (ctx->index << 3);
+                                                                       \
+  /* append the 64 bit count */
+  LE_WRITE_UINT32(ctx->block + 56, low);
+  LE_WRITE_UINT32(ctx->block + 60, high);
+  _nettle_ripemd160_compress(ctx->state, ctx->block);
+
+  _nettle_write_le32(length, digest, ctx->state);
+  ripemd160_init(ctx);
+}
diff --git a/ripemd160.h b/ripemd160.h
new file mode 100644 (file)
index 0000000..83ed6e5
--- /dev/null
@@ -0,0 +1,78 @@
+/* ripemd160.h
+ *
+ * RIPEMD-160 hash function.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2011 Andres Mejia
+ *
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_RIPEMD160_H_INCLUDED
+#define NETTLE_RIPEMD160_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nettle-types.h"
+
+/* Name mangling */
+#define ripemd160_init nettle_ripemd160_init
+#define ripemd160_update nettle_ripemd160_update
+#define ripemd160_digest nettle_ripemd160_digest
+
+/* RIPEMD160 */
+
+#define RIPEMD160_DIGEST_SIZE 20
+#define RIPEMD160_DATA_SIZE 64
+
+/* Digest is kept internally as 5 32-bit words. */
+#define _RIPEMD160_DIGEST_LENGTH 5
+
+struct ripemd160_ctx
+{
+  uint32_t state[_RIPEMD160_DIGEST_LENGTH];
+  uint32_t count_low, count_high;         /* 64-bit block count */
+  uint8_t block[RIPEMD160_DATA_SIZE];
+  unsigned int index;
+};
+
+void
+ripemd160_init(struct ripemd160_ctx *ctx);
+
+void
+ripemd160_update(struct ripemd160_ctx *ctx,
+                unsigned length,
+                const uint8_t *data);
+
+void
+ripemd160_digest(struct ripemd160_ctx *ctx,
+                unsigned length,
+                uint8_t *digest);
+
+/* Internal compression function. STATE points to 5 uint32_t words,
+   and DATA points to 64 bytes of input data, possibly unaligned. */
+void
+_nettle_ripemd160_compress(uint32_t *state, const uint8_t *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_RIPEMD160_H_INCLUDED */
diff --git a/rotors.h b/rotors.h
new file mode 100644 (file)
index 0000000..290f5d9
--- /dev/null
+++ b/rotors.h
@@ -0,0 +1,82 @@
+/* automagically made - do not fuss with this */
+
+ 34, 13,  5, 46, 47, 18, 32, 41, 11, 53, 33, 20,
+ 14, 36, 30, 24, 49,  2, 15, 37, 42, 50,  0, 21,
+ 38, 48,  6, 26, 39,  4, 52, 25, 12, 27, 31, 40,
+  1, 17, 28, 29, 23, 51, 35,  7,  3, 22,  9, 43,
+
+ 41, 20, 12, 53, 54, 25, 39, 48, 18, 31, 40, 27,
+ 21, 43, 37,  0,  1,  9, 22, 44, 49,  2,  7, 28,
+ 45, 55, 13, 33, 46, 11,  6, 32, 19, 34, 38, 47,
+  8, 24, 35, 36, 30,  3, 42, 14, 10, 29, 16, 50,
+
+ 55, 34, 26, 38, 11, 39, 53,  5, 32, 45, 54, 41,
+ 35,  2, 51, 14, 15, 23, 36,  3,  8, 16, 21, 42,
+  6, 12, 27, 47, 31, 25, 20, 46, 33, 48, 52,  4,
+ 22,  7, 49, 50, 44, 17,  1, 28, 24, 43, 30,  9,
+
+ 12, 48, 40, 52, 25, 53, 38, 19, 46,  6, 11, 55,
+ 49, 16, 10, 28, 29, 37, 50, 17, 22, 30, 35,  1,
+ 20, 26, 41,  4, 45, 39, 34, 31, 47,  5, 13, 18,
+ 36, 21,  8,  9,  3,  0, 15, 42,  7,  2, 44, 23,
+
+ 26,  5, 54, 13, 39, 38, 52, 33, 31, 20, 25, 12,
+  8, 30, 24, 42, 43, 51,  9,  0, 36, 44, 49, 15,
+ 34, 40, 55, 18,  6, 53, 48, 45,  4, 19, 27, 32,
+ 50, 35, 22, 23, 17, 14, 29,  1, 21, 16,  3, 37,
+
+ 40, 19, 11, 27, 53, 52, 13, 47, 45, 34, 39, 26,
+ 22, 44,  7,  1,  2, 10, 23, 14, 50,  3,  8, 29,
+ 48, 54, 12, 32, 20, 38,  5,  6, 18, 33, 41, 46,
+  9, 49, 36, 37,  0, 28, 43, 15, 35, 30, 17, 51,
+
+ 54, 33, 25, 41, 38, 13, 27,  4,  6, 48, 53, 40,
+ 36,  3, 21, 15, 16, 24, 37, 28,  9, 17, 22, 43,
+  5, 11, 26, 46, 34, 52, 19, 20, 32, 47, 55, 31,
+ 23,  8, 50, 51, 14, 42,  2, 29, 49, 44,  0, 10,
+
+ 11, 47, 39, 55, 52, 27, 41, 18, 20,  5, 38, 54,
+ 50, 17, 35, 29, 30,  7, 51, 42, 23,  0, 36,  2,
+ 19, 25, 40, 31, 48, 13, 33, 34, 46,  4, 12, 45,
+ 37, 22,  9, 10, 28,  1, 16, 43,  8,  3, 14, 24,
+
+ 18, 54, 46,  5,  6, 34, 48, 25, 27, 12, 45,  4,
+  2, 24, 42, 36, 37, 14,  3, 49, 30,  7, 43,  9,
+ 26, 32, 47, 38, 55, 20, 40, 41, 53, 11, 19, 52,
+ 44, 29, 16, 17, 35,  8, 23, 50, 15, 10, 21,  0,
+
+ 32, 11, 31, 19, 20, 48,  5, 39, 41, 26,  6, 18,
+ 16,  7,  1, 50, 51, 28, 17,  8, 44, 21,  2, 23,
+ 40, 46,  4, 52, 12, 34, 54, 55, 38, 25, 33, 13,
+  3, 43, 30,  0, 49, 22, 37,  9, 29, 24, 35, 14,
+
+ 46, 25, 45, 33, 34,  5, 19, 53, 55, 40, 20, 32,
+ 30, 21, 15,  9, 10, 42,  0, 22,  3, 35, 16, 37,
+ 54, 31, 18, 13, 26, 48, 11, 12, 52, 39, 47, 27,
+ 17,  2, 44, 14,  8, 36, 51, 23, 43,  7, 49, 28,
+
+ 31, 39,  6, 47, 48, 19, 33, 38, 12, 54, 34, 46,
+ 44, 35, 29, 23, 24,  1, 14, 36, 17, 49, 30, 51,
+ 11, 45, 32, 27, 40,  5, 25, 26, 13, 53,  4, 41,
+  0, 16,  3, 28, 22, 50, 10, 37,  2, 21,  8, 42,
+
+ 45, 53, 20,  4,  5, 33, 47, 52, 26, 11, 48, 31,
+  3, 49, 43, 37,  7, 15, 28, 50,  0,  8, 44, 10,
+ 25,  6, 46, 41, 54, 19, 39, 40, 27, 38, 18, 55,
+ 14, 30, 17, 42, 36,  9, 24, 51, 16, 35, 22,  1,
+
+  6, 38, 34, 18, 19, 47,  4, 13, 40, 25,  5, 45,
+ 17,  8,  2, 51, 21, 29, 42,  9, 14, 22,  3, 24,
+ 39, 20, 31, 55, 11, 33, 53, 54, 41, 52, 32, 12,
+ 28, 44,  0,  1, 50, 23,  7, 10, 30, 49, 36, 15,
+
+ 20, 52, 48, 32, 33,  4, 18, 27, 54, 39, 19,  6,
+  0, 22, 16, 10, 35, 43,  1, 23, 28, 36, 17,  7,
+ 53, 34, 45, 12, 25, 47, 38, 11, 55, 13, 46, 26,
+ 42,  3, 14, 15,  9, 37, 21, 24, 44,  8, 50, 29,
+
+ 27,  6, 55, 39, 40, 11, 25, 34,  4, 46, 26, 13,
+  7, 29, 23, 17, 42, 50,  8, 30, 35, 43, 24, 14,
+ 31, 41, 52, 19, 32, 54, 45, 18,  5, 20, 53, 33,
+ 49, 10, 21, 22, 16, 44, 28,  0, 51, 15,  2, 36,
+
diff --git a/rsa-compat.c b/rsa-compat.c
new file mode 100644 (file)
index 0000000..8eef185
--- /dev/null
@@ -0,0 +1,157 @@
+/* rsa-compat.c
+ *
+ * The RSA publickey algorithm, RSAREF compatible interface.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "rsa-compat.h"
+
+#include "bignum.h"
+#include "md5.h"
+
+int
+R_SignInit(R_SIGNATURE_CTX *ctx,
+           int digestAlgorithm)
+{
+  if (digestAlgorithm != DA_MD5)
+    return RE_DIGEST_ALGORITHM;
+
+  md5_init(&ctx->hash);
+
+  return 0;
+}
+
+int
+R_SignUpdate(R_SIGNATURE_CTX *ctx,
+             const uint8_t *data,
+             /* Length is an unsigned char according to rsaref.txt,
+              * but that must be a typo. */
+             unsigned length)
+{
+  md5_update(&ctx->hash, length, data);
+
+  return RE_SUCCESS;
+}
+
+int
+R_SignFinal(R_SIGNATURE_CTX *ctx,
+            uint8_t *signature,
+            unsigned *length,
+            R_RSA_PRIVATE_KEY *key)
+{
+  struct rsa_private_key k;
+  int res;
+  
+  nettle_mpz_init_set_str_256_u(k.p,
+                               MAX_RSA_MODULUS_LEN, key->prime[0]);
+  nettle_mpz_init_set_str_256_u(k.q,
+                               MAX_RSA_MODULUS_LEN, key->prime[1]);
+  nettle_mpz_init_set_str_256_u(k.a,
+                               MAX_RSA_MODULUS_LEN, key->primeExponent[0]);
+  nettle_mpz_init_set_str_256_u(k.b,
+                               MAX_RSA_MODULUS_LEN, key->primeExponent[1]);
+  nettle_mpz_init_set_str_256_u(k.c,
+                               MAX_RSA_MODULUS_LEN, key->coefficient);
+
+  if (rsa_private_key_prepare(&k) && (k.size <= MAX_RSA_MODULUS_LEN))
+    {
+      mpz_t s;
+      mpz_init(s);
+
+      if (rsa_md5_sign(&k, &ctx->hash, s))
+       {
+         nettle_mpz_get_str_256(k.size, signature, s);
+         *length = k.size;
+
+         res = RE_SUCCESS;
+       }
+      else
+       res = RE_PRIVATE_KEY;
+
+      mpz_clear(s);
+    }
+  else
+    res = RE_PRIVATE_KEY;
+  
+  mpz_clear(k.p);
+  mpz_clear(k.q);
+  mpz_clear(k.a);
+  mpz_clear(k.b);
+  mpz_clear(k.c);
+
+  return res;
+}
+
+int
+R_VerifyInit(R_SIGNATURE_CTX *ctx,
+             int digestAlgorithm)
+{
+  return R_SignInit(ctx, digestAlgorithm);
+}
+
+int
+R_VerifyUpdate(R_SIGNATURE_CTX *ctx,
+               const uint8_t *data,
+               /* Length is an unsigned char according to rsaref.txt,
+                * but that must be a typo. */
+               unsigned length)
+{
+  return R_SignUpdate(ctx, data, length);
+}
+
+int
+R_VerifyFinal(R_SIGNATURE_CTX *ctx,
+              uint8_t *signature,
+              unsigned length,
+              R_RSA_PUBLIC_KEY *key)
+{
+  struct rsa_public_key k;
+  int res;
+
+  nettle_mpz_init_set_str_256_u(k.n,
+                               MAX_RSA_MODULUS_LEN, key->modulus);
+  nettle_mpz_init_set_str_256_u(k.e,
+                               MAX_RSA_MODULUS_LEN, key->exponent);
+  
+  if (rsa_public_key_prepare(&k) && (k.size == length))
+    {
+      mpz_t s;
+  
+      nettle_mpz_init_set_str_256_u(s,
+                                   k.size, signature);
+      res = rsa_md5_verify(&k, &ctx->hash, s)
+       ? RE_SUCCESS : RE_SIGNATURE;
+
+      mpz_clear(s);
+    }
+  else
+    res = RE_PUBLIC_KEY;
+
+  mpz_clear(k.n);
+  mpz_clear(k.e);
+
+  return res;
+}
diff --git a/rsa-compat.h b/rsa-compat.h
new file mode 100644 (file)
index 0000000..9622503
--- /dev/null
@@ -0,0 +1,131 @@
+/* rsa-compat.h
+ *
+ * The RSA publickey algorithm, RSAREF compatible interface.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_RSA_COMPAT_H_INCLUDED
+#define NETTLE_RSA_COMPAT_H_INCLUDED
+
+#include "rsa.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define R_SignInit nettle_R_SignInit
+#define R_SignUpdate nettle_R_SignUpdate
+#define R_SignFinal nettle_R_SignFinal
+#define R_VerifyInit nettle_R_VerifyInit
+#define R_VerifyUpdate nettle_R_VerifyUpdate
+#define R_VerifyFinal nettle_R_VerifyFinal
+
+/* 256 octets or 2048 bits */
+#define MAX_RSA_MODULUS_LEN 256
+
+typedef struct
+{
+  unsigned bits;
+  uint8_t modulus[MAX_RSA_MODULUS_LEN];
+  uint8_t exponent[MAX_RSA_MODULUS_LEN];
+} R_RSA_PUBLIC_KEY;
+
+typedef struct
+{
+  unsigned bits;
+  uint8_t modulus[MAX_RSA_MODULUS_LEN];
+  uint8_t publicExponent[MAX_RSA_MODULUS_LEN];
+  uint8_t exponent[MAX_RSA_MODULUS_LEN];
+  uint8_t prime[2][MAX_RSA_MODULUS_LEN];
+  uint8_t primeExponent[2][MAX_RSA_MODULUS_LEN];
+  uint8_t coefficient[MAX_RSA_MODULUS_LEN];
+} R_RSA_PRIVATE_KEY;
+
+/* Only MD5 is supported for now */
+typedef struct
+{
+  struct md5_ctx hash;
+} R_SIGNATURE_CTX;
+
+/* Digest algorithms */
+/* DA_MD2 not implemented */
+enum { DA_MD5 = 1 };
+
+/* Return values */
+enum {
+  RE_SUCCESS = 0,
+  RE_CONTENT_ENCODING,     /* encryptedContent has RFC 1421 encoding error */
+  RE_DATA,                 /* other party's private value out of range */
+  RE_DIGEST_ALGORITHM,     /* message-digest algorithm is invalid */
+  RE_ENCODING,             /* encoded block has RFC 1421 encoding error */
+  RE_ENCRYPTION_ALGORITHM, /* encryption algorithm is invalid */
+  RE_KEY,                  /* recovered data encryption key cannot decrypt */
+  RE_KEY_ENCODING,         /* encrypted key has RFC 1421 encoding error */
+  RE_LEN,                  /* signatureLen out of range */
+  RE_MODULUS_LEN,          /* modulus length invalid */
+  RE_NEED_RANDOM,          /* random structure is not seeded */
+  RE_PRIVATE_KEY,          /* private key cannot encrypt message digest, */
+  RE_PUBLIC_KEY,           /* publicKey cannot decrypt signature */
+  RE_SIGNATURE,            /* signature is incorrect */
+  RE_SIGNATURE_ENCODING,   /* encodedSignature has RFC 1421 encoding error */
+};
+
+int
+R_SignInit(R_SIGNATURE_CTX *ctx,
+           int digestAlgorithm);
+
+int
+R_SignUpdate(R_SIGNATURE_CTX *ctx,
+             const uint8_t *data,
+             /* Length is an unsigned char according to rsaref.txt,
+              * but that must be a typo. */
+             unsigned length);
+
+int
+R_SignFinal(R_SIGNATURE_CTX *ctx,
+            uint8_t *signature,
+            unsigned *length,
+            R_RSA_PRIVATE_KEY *key);
+
+int
+R_VerifyInit(R_SIGNATURE_CTX *ctx,
+             int digestAlgorithm);
+
+int
+R_VerifyUpdate(R_SIGNATURE_CTX *ctx,
+               const uint8_t *data,
+               /* Length is an unsigned char according to rsaref.txt,
+                * but that must be a typo. */
+               unsigned length);
+
+int
+R_VerifyFinal(R_SIGNATURE_CTX *ctx,
+              uint8_t *signature,
+              unsigned length,
+              R_RSA_PUBLIC_KEY *key);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_RSA_COMPAT_H_INCLUDED */
diff --git a/rsa-decrypt.c b/rsa-decrypt.c
new file mode 100644 (file)
index 0000000..973fa65
--- /dev/null
@@ -0,0 +1,80 @@
+/* rsa_decrypt.c
+ *
+ * The RSA publickey algorithm. PKCS#1 encryption.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "rsa.h"
+
+#include "bignum.h"
+#include "nettle-internal.h"
+
+int
+rsa_decrypt(const struct rsa_private_key *key,
+           unsigned *length, uint8_t *message,
+           const mpz_t gibberish)
+{
+  TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8);
+  uint8_t *terminator;
+  unsigned padding;
+  unsigned message_length;
+  
+  mpz_t m;
+
+  mpz_init(m);
+  rsa_compute_root(key, m, gibberish);
+
+  TMP_ALLOC(em, key->size);
+  nettle_mpz_get_str_256(key->size, em, m);
+  mpz_clear(m);
+
+  /* Check format */
+  if (em[0] || em[1] != 2)
+    return 0;
+
+  terminator = memchr(em + 2, 0, key->size - 2);
+
+  if (!terminator)
+    return 0;
+  
+  padding = terminator - (em + 2);
+  if (padding < 8)
+    return 0;
+
+  message_length = key->size - 3 - padding;
+
+  if (*length < message_length)
+    return 0;
+  
+  memcpy(message, terminator + 1, message_length);
+  *length = message_length;
+
+  return 1;
+}
diff --git a/rsa-encrypt.c b/rsa-encrypt.c
new file mode 100644 (file)
index 0000000..a901e71
--- /dev/null
@@ -0,0 +1,83 @@
+/* rsa_encrypt.c
+ *
+ * The RSA publickey algorithm. PKCS#1 encryption.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "rsa.h"
+
+#include "bignum.h"
+#include "nettle-internal.h"
+
+int
+rsa_encrypt(const struct rsa_public_key *key,
+           /* For padding */
+           void *random_ctx, nettle_random_func random,
+           unsigned length, const uint8_t *message,
+           mpz_t gibbberish)
+{
+  TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8);
+  unsigned padding;
+  unsigned i;
+  
+  /* The message is encoded as a string of the same length as the
+   * modulo n, of the form
+   *
+   *   00 02 pad 00 message
+   *
+   * where padding should be at least 8 pseudorandomly generated
+   * *non-zero* octets. */
+     
+  if (length + 11 > key->size)
+    /* Message too long for this key. */
+    return 0;
+
+  /* At least 8 octets of random padding */
+  padding = key->size - length - 3;
+  assert(padding >= 8);
+  
+  TMP_ALLOC(em, key->size - 1);
+  em[0] = 2;
+
+  random(random_ctx, padding, em + 1);
+
+  /* Replace 0-octets with 1 */
+  for (i = 0; i<padding; i++)
+    if (!em[i+1])
+      em[i+1] = 1;
+
+  em[padding+1] = 0;
+  memcpy(em + padding + 2, message, length);
+
+  nettle_mpz_set_str_256_u(gibbberish, key->size - 1, em);
+  mpz_powm(gibbberish, gibbberish, key->e, key->n);
+
+  return 1;  
+}
diff --git a/rsa-keygen.c b/rsa-keygen.c
new file mode 100644 (file)
index 0000000..8c56bb4
--- /dev/null
@@ -0,0 +1,204 @@
+/* rsa-keygen.c
+ *
+ * Generation of RSA keypairs
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "rsa.h"
+#include "bignum.h"
+
+#ifndef DEBUG
+# define DEBUG 0
+#endif
+
+#if DEBUG
+# include <stdio.h>
+#endif
+
+
+int
+rsa_generate_keypair(struct rsa_public_key *pub,
+                    struct rsa_private_key *key,
+                    void *random_ctx, nettle_random_func random,
+                    void *progress_ctx, nettle_progress_func progress,
+                    unsigned n_size,
+                    unsigned e_size)
+{
+  mpz_t p1;
+  mpz_t q1;
+  mpz_t phi;
+  mpz_t tmp;
+
+  if (e_size)
+    {
+      /* We should choose e randomly. Is the size reasonable? */
+      if ((e_size < 16) || (e_size >= n_size) )
+       return 0;
+    }
+  else
+    {
+      /* We have a fixed e. Check that it makes sense */
+
+      /* It must be odd */
+      if (!mpz_tstbit(pub->e, 0))
+       return 0;
+
+      /* And 3 or larger */
+      if (mpz_cmp_ui(pub->e, 3) < 0)
+       return 0;
+
+      /* And size less than n */
+      if (mpz_sizeinbase(pub->e, 2) >= n_size)
+       return 0;
+    }
+
+  if (n_size < RSA_MINIMUM_N_BITS)
+    return 0;
+  
+  mpz_init(p1); mpz_init(q1); mpz_init(phi); mpz_init(tmp);
+
+  /* Generate primes */
+  for (;;)
+    {
+      /* Generate p, such that gcd(p-1, e) = 1 */
+      for (;;)
+       {
+         nettle_random_prime(key->p, (n_size+1)/2, 1,
+                             random_ctx, random,
+                             progress_ctx, progress);
+
+         mpz_sub_ui(p1, key->p, 1);
+      
+         /* If e was given, we must chose p such that p-1 has no factors in
+          * common with e. */
+         if (e_size)
+           break;
+         
+         mpz_gcd(tmp, pub->e, p1);
+
+         if (mpz_cmp_ui(tmp, 1) == 0)
+           break;
+         else if (progress) progress(progress_ctx, 'c');
+       } 
+
+      if (progress)
+       progress(progress_ctx, '\n');
+      
+      /* Generate q, such that gcd(q-1, e) = 1 */
+      for (;;)
+       {
+         nettle_random_prime(key->q, n_size/2, 1,
+                             random_ctx, random,
+                             progress_ctx, progress);
+
+         /* Very unlikely. */
+         if (mpz_cmp (key->q, key->p) == 0)
+           continue;
+
+         mpz_sub_ui(q1, key->q, 1);
+      
+         /* If e was given, we must chose q such that q-1 has no factors in
+          * common with e. */
+         if (e_size)
+           break;
+         
+         mpz_gcd(tmp, pub->e, q1);
+
+         if (mpz_cmp_ui(tmp, 1) == 0)
+           break;
+         else if (progress) progress(progress_ctx, 'c');
+       }
+
+      /* Now we have the primes. Is the product of the right size? */
+      mpz_mul(pub->n, key->p, key->q);
+
+      assert (mpz_sizeinbase(pub->n, 2) == n_size);
+
+      if (progress)
+       progress(progress_ctx, '\n');
+
+      /* c = q^{-1} (mod p) */
+      if (mpz_invert(key->c, key->q, key->p))
+       /* This should succeed everytime. But if it doesn't,
+        * we try again. */
+       break;
+      else if (progress) progress(progress_ctx, '?');
+    }
+
+  mpz_mul(phi, p1, q1);
+  
+  /* If we didn't have a given e, generate one now. */
+  if (e_size)
+    {
+      int retried = 0;
+      for (;;)
+       {
+         nettle_mpz_random_size(pub->e,
+                                random_ctx, random,
+                                e_size);
+       
+         /* Make sure it's odd and that the most significant bit is
+          * set */
+         mpz_setbit(pub->e, 0);
+         mpz_setbit(pub->e, e_size - 1);
+
+         /* Needs gmp-3, or inverse might be negative. */
+         if (mpz_invert(key->d, pub->e, phi))
+           break;
+
+         if (progress) progress(progress_ctx, 'e');
+         retried = 1;
+       }
+      if (retried && progress)
+       progress(progress_ctx, '\n');   
+    }
+  else
+    {
+      /* Must always succeed, as we already that e
+       * doesn't have any common factor with p-1 or q-1. */
+      int res = mpz_invert(key->d, pub->e, phi);
+      assert(res);
+    }
+
+  /* Done! Almost, we must compute the auxillary private values. */
+  /* a = d % (p-1) */
+  mpz_fdiv_r(key->a, key->d, p1);
+
+  /* b = d % (q-1) */
+  mpz_fdiv_r(key->b, key->d, q1);
+
+  /* c was computed earlier */
+
+  pub->size = key->size = (n_size + 7) / 8;
+  assert(pub->size >= RSA_MINIMUM_N_OCTETS);
+  
+  mpz_clear(p1); mpz_clear(q1); mpz_clear(phi); mpz_clear(tmp);
+
+  return 1;
+}
diff --git a/rsa-md5-sign.c b/rsa-md5-sign.c
new file mode 100644 (file)
index 0000000..166cba7
--- /dev/null
@@ -0,0 +1,73 @@
+/* rsa-md5-sign.c
+ *
+ * Signatures using RSA and MD5.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "rsa.h"
+
+#include "bignum.h"
+#include "pkcs1.h"
+
+int
+rsa_md5_sign(const struct rsa_private_key *key,
+             struct md5_ctx *hash,
+             mpz_t s)
+{
+  assert(key->size > 0);
+
+  if (pkcs1_rsa_md5_encode(s, key->size - 1, hash))
+    {
+      rsa_compute_root(key, s, s);
+      return 1;
+    }
+  else
+    {
+      mpz_set_ui(s, 0);
+      return 0;
+    }
+}
+
+int
+rsa_md5_sign_digest(const struct rsa_private_key *key,
+                   const uint8_t *digest,
+                   mpz_t s)
+{
+  assert(key->size > 0);
+
+  if (pkcs1_rsa_md5_encode_digest(s, key->size - 1, digest))
+    {
+      rsa_compute_root(key, s, s);
+      return 1;
+    }
+  else
+    {
+      mpz_set_ui(s, 0);
+      return 0;
+    }  
+}
diff --git a/rsa-md5-verify.c b/rsa-md5-verify.c
new file mode 100644 (file)
index 0000000..f8931c7
--- /dev/null
@@ -0,0 +1,73 @@
+/* rsa-md5-verify.c
+ *
+ * Verifying signatures created with RSA and MD5.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "rsa.h"
+
+#include "bignum.h"
+#include "pkcs1.h"
+
+int
+rsa_md5_verify(const struct rsa_public_key *key,
+               struct md5_ctx *hash,
+               const mpz_t s)
+{
+  int res;
+  mpz_t m;
+
+  assert(key->size > 0);
+  mpz_init(m);
+
+  res = (pkcs1_rsa_md5_encode(m, key->size - 1, hash)
+        && _rsa_verify(key, m, s));
+
+  mpz_clear(m);
+
+  return res;
+}
+
+int
+rsa_md5_verify_digest(const struct rsa_public_key *key,
+                     const uint8_t *digest,
+                     const mpz_t s)
+{
+  int res;
+  mpz_t m;
+
+  assert(key->size > 0);
+  mpz_init(m);
+  
+  res = (pkcs1_rsa_md5_encode_digest(m, key->size - 1, digest)
+        && _rsa_verify(key, m, s));
+
+  mpz_clear(m);
+
+  return res;
+}
diff --git a/rsa-sha1-sign.c b/rsa-sha1-sign.c
new file mode 100644 (file)
index 0000000..f120c7b
--- /dev/null
@@ -0,0 +1,73 @@
+/* rsa-sha1-sign.c
+ *
+ * Signatures using RSA and SHA1.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "rsa.h"
+
+#include "bignum.h"
+#include "pkcs1.h"
+
+int
+rsa_sha1_sign(const struct rsa_private_key *key,
+              struct sha1_ctx *hash,
+              mpz_t s)
+{
+  assert(key->size > 0);
+
+  if (pkcs1_rsa_sha1_encode(s, key->size - 1, hash))
+    {
+      rsa_compute_root(key, s, s);
+      return 1;
+    }
+  else
+    {
+      mpz_set_ui(s, 0);
+      return 0;
+    }
+}
+
+int
+rsa_sha1_sign_digest(const struct rsa_private_key *key,
+                    const uint8_t *digest,
+                    mpz_t s)
+{
+  assert(key->size > 0);
+
+  if (pkcs1_rsa_sha1_encode_digest(s, key->size - 1, digest))
+    {
+      rsa_compute_root(key, s, s);
+      return 1;
+    }
+  else
+    {
+      mpz_set_ui(s, 0);
+      return 0;
+    }
+}
diff --git a/rsa-sha1-verify.c b/rsa-sha1-verify.c
new file mode 100644 (file)
index 0000000..71ed848
--- /dev/null
@@ -0,0 +1,73 @@
+/* rsa-sha1-verify.c
+ *
+ * Verifying signatures created with RSA and SHA1.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "rsa.h"
+
+#include "bignum.h"
+#include "pkcs1.h"
+
+int
+rsa_sha1_verify(const struct rsa_public_key *key,
+                struct sha1_ctx *hash,
+                const mpz_t s)
+{
+  int res;
+  mpz_t m;
+
+  assert(key->size > 0);
+  mpz_init(m);
+  
+  res = (pkcs1_rsa_sha1_encode(m, key->size - 1, hash)
+        && _rsa_verify(key, m, s));
+  
+  mpz_clear(m);
+
+  return res;
+}
+
+int
+rsa_sha1_verify_digest(const struct rsa_public_key *key,
+                      const uint8_t *digest,
+                      const mpz_t s)
+{
+  int res;
+  mpz_t m;
+
+  assert(key->size > 0);
+  mpz_init(m);
+  
+  res = (pkcs1_rsa_sha1_encode_digest(m, key->size - 1, digest)
+        && _rsa_verify(key, m, s));
+  
+  mpz_clear(m);
+
+  return res;
+}
diff --git a/rsa-sha256-sign.c b/rsa-sha256-sign.c
new file mode 100644 (file)
index 0000000..5f3cf7c
--- /dev/null
@@ -0,0 +1,73 @@
+/* rsa-sha256-sign.c
+ *
+ * Signatures using RSA and SHA256.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2003, 2006 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "rsa.h"
+
+#include "bignum.h"
+#include "pkcs1.h"
+
+int
+rsa_sha256_sign(const struct rsa_private_key *key,
+               struct sha256_ctx *hash,
+               mpz_t s)
+{
+  assert(key->size > 0);
+
+  if (pkcs1_rsa_sha256_encode(s, key->size - 1, hash))
+    {
+      rsa_compute_root(key, s, s);
+      return 1;
+    }
+  else
+    {
+      mpz_set_ui(s, 0);
+      return 0;
+    }  
+}
+
+int
+rsa_sha256_sign_digest(const struct rsa_private_key *key,
+                      const uint8_t *digest,
+                      mpz_t s)
+{
+  assert(key->size > 0);
+
+  if (pkcs1_rsa_sha256_encode_digest(s, key->size - 1, digest))
+    {
+      rsa_compute_root(key, s, s);
+      return 1;
+    }
+  else
+    {
+      mpz_set_ui(s, 0);
+      return 0;
+    }  
+}
diff --git a/rsa-sha256-verify.c b/rsa-sha256-verify.c
new file mode 100644 (file)
index 0000000..ef3f1e3
--- /dev/null
@@ -0,0 +1,73 @@
+/* rsa-sha256-verify.c
+ *
+ * Verifying signatures created with RSA and SHA256.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2003, 2006 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "rsa.h"
+
+#include "bignum.h"
+#include "pkcs1.h"
+
+int
+rsa_sha256_verify(const struct rsa_public_key *key,
+                 struct sha256_ctx *hash,
+                 const mpz_t s)
+{
+  int res;
+  mpz_t m;
+
+  assert(key->size > 0);
+  mpz_init(m);
+
+  res = (pkcs1_rsa_sha256_encode(m, key->size - 1, hash)
+        &&_rsa_verify(key, m, s));
+  
+  mpz_clear(m);
+
+  return res;
+}
+
+int
+rsa_sha256_verify_digest(const struct rsa_public_key *key,
+                        const uint8_t *digest,
+                        const mpz_t s)
+{
+  int res;
+  mpz_t m;
+
+  assert(key->size > 0);
+  mpz_init(m);
+  
+  res = (pkcs1_rsa_sha256_encode_digest(m, key->size - 1, digest)
+        && _rsa_verify(key, m, s));
+  
+  mpz_clear(m);
+
+  return res;
+}
diff --git a/rsa-sha512-sign.c b/rsa-sha512-sign.c
new file mode 100644 (file)
index 0000000..fa14487
--- /dev/null
@@ -0,0 +1,73 @@
+/* rsa-sha512-sign.c
+ *
+ * Signatures using RSA and SHA512.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2003, 2006, 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "rsa.h"
+
+#include "bignum.h"
+#include "pkcs1.h"
+
+int
+rsa_sha512_sign(const struct rsa_private_key *key,
+               struct sha512_ctx *hash,
+               mpz_t s)
+{
+  assert(key->size > 0);
+
+  if (pkcs1_rsa_sha512_encode(s, key->size - 1, hash))
+    {
+      rsa_compute_root(key, s, s);
+      return 1;
+    }
+  else
+    {
+      mpz_set_ui(s, 0);
+      return 0;
+    }  
+}
+
+int
+rsa_sha512_sign_digest(const struct rsa_private_key *key,
+                      const uint8_t *digest,
+                      mpz_t s)
+{
+  assert(key->size > 0);
+
+  if (pkcs1_rsa_sha512_encode_digest(s, key->size - 1, digest))
+    {
+      rsa_compute_root(key, s, s);
+      return 1;
+    }
+  else
+    {
+      mpz_set_ui(s, 0);
+      return 0;
+    }  
+}
diff --git a/rsa-sha512-verify.c b/rsa-sha512-verify.c
new file mode 100644 (file)
index 0000000..869a8f5
--- /dev/null
@@ -0,0 +1,73 @@
+/* rsa-sha512-verify.c
+ *
+ * Verifying signatures created with RSA and SHA512.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2003, 2006, 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "rsa.h"
+
+#include "bignum.h"
+#include "pkcs1.h"
+
+int
+rsa_sha512_verify(const struct rsa_public_key *key,
+                 struct sha512_ctx *hash,
+                 const mpz_t s)
+{
+  int res;
+  mpz_t m;
+
+  assert(key->size > 0);
+  mpz_init(m);
+  
+  res = (pkcs1_rsa_sha512_encode(m, key->size - 1, hash) 
+        && _rsa_verify(key, m, s));
+  
+  mpz_clear(m);
+
+  return res;
+}
+
+int
+rsa_sha512_verify_digest(const struct rsa_public_key *key,
+                        const uint8_t *digest,
+                        const mpz_t s)
+{
+  int res;
+  mpz_t m;
+
+  assert(key->size > 0);
+  mpz_init(m);
+  
+  res = (pkcs1_rsa_sha512_encode_digest(m, key->size - 1, digest)
+        && _rsa_verify(key, m, s));
+  
+  mpz_clear(m);
+
+  return res;
+}
diff --git a/rsa-sign.c b/rsa-sign.c
new file mode 100644 (file)
index 0000000..aa407ca
--- /dev/null
@@ -0,0 +1,136 @@
+/* rsa-sign.c
+ *
+ * Creating RSA signatures.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "rsa.h"
+
+#include "bignum.h"
+
+void
+rsa_private_key_init(struct rsa_private_key *key)
+{
+  mpz_init(key->d);
+  mpz_init(key->p);
+  mpz_init(key->q);
+  mpz_init(key->a);
+  mpz_init(key->b);
+  mpz_init(key->c);
+
+  /* Not really necessary, but it seems cleaner to initialize all the
+   * storage. */
+  key->size = 0;
+}
+
+void
+rsa_private_key_clear(struct rsa_private_key *key)
+{
+  mpz_clear(key->d);
+  mpz_clear(key->p);
+  mpz_clear(key->q);
+  mpz_clear(key->a);
+  mpz_clear(key->b);
+  mpz_clear(key->c);
+}
+
+int
+rsa_private_key_prepare(struct rsa_private_key *key)
+{
+  mpz_t n;
+  
+  /* The size of the product is the sum of the sizes of the factors,
+   * or sometimes one less. It's possible but tricky to compute the
+   * size without computing the full product. */
+
+  mpz_init(n);
+  mpz_mul(n, key->p, key->q);
+
+  key->size = _rsa_check_size(n);
+
+  mpz_clear(n);
+  
+  return (key->size > 0);
+}
+
+/* Computing an rsa root. */
+void
+rsa_compute_root(const struct rsa_private_key *key,
+                mpz_t x, const mpz_t m)
+{
+  mpz_t xp; /* modulo p */
+  mpz_t xq; /* modulo q */
+
+  mpz_init(xp); mpz_init(xq);    
+
+  /* Compute xq = m^d % q = (m%q)^b % q */
+  mpz_fdiv_r(xq, m, key->q);
+  mpz_powm(xq, xq, key->b, key->q);
+
+  /* Compute xp = m^d % p = (m%p)^a % p */
+  mpz_fdiv_r(xp, m, key->p);
+  mpz_powm(xp, xp, key->a, key->p);
+
+  /* Set xp' = (xp - xq) c % p. */
+  mpz_sub(xp, xp, xq);
+  mpz_mul(xp, xp, key->c);
+  mpz_fdiv_r(xp, xp, key->p);
+
+  /* Finally, compute x = xq + q xp'
+   *
+   * To prove that this works, note that
+   *
+   *   xp  = x + i p,
+   *   xq  = x + j q,
+   *   c q = 1 + k p
+   *
+   * for some integers i, j and k. Now, for some integer l,
+   *
+   *   xp' = (xp - xq) c + l p
+   *       = (x + i p - (x + j q)) c + l p
+   *       = (i p - j q) c + l p
+   *       = (i c + l) p - j (c q)
+   *       = (i c + l) p - j (1 + kp)
+   *       = (i c + l - j k) p - j
+   *
+   * which shows that xp' = -j (mod p). We get
+   *
+   *   xq + q xp' = x + j q + (i c + l - j k) p q - j q
+   *              = x + (i c + l - j k) p q
+   *
+   * so that
+   *
+   *   xq + q xp' = x (mod pq)
+   *
+   * We also get 0 <= xq + q xp' < p q, because
+   *
+   *   0 <= xq < q and 0 <= xp' < p.
+   */
+  mpz_mul(x, key->q, xp);
+  mpz_add(x, x, xq);
+
+  mpz_clear(xp); mpz_clear(xq);
+}
diff --git a/rsa-verify.c b/rsa-verify.c
new file mode 100644 (file)
index 0000000..2e3b52f
--- /dev/null
@@ -0,0 +1,56 @@
+/* rsa-verify.c
+ *
+ * Verifying RSA signatures.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "rsa.h"
+
+#include "bignum.h"
+
+int
+_rsa_verify(const struct rsa_public_key *key,
+           const mpz_t m,
+           const mpz_t s)
+{
+  int res;
+  
+  mpz_t m1;
+  
+  if ( (mpz_sgn(s) <= 0)
+       || (mpz_cmp(s, key->n) >= 0) )
+    return 0;
+       
+  mpz_init(m1);
+  
+  mpz_powm(m1, s, key->e, key->n);
+
+  res = !mpz_cmp(m, m1);
+
+  mpz_clear(m1);
+
+  return res;
+}
diff --git a/rsa.c b/rsa.c
new file mode 100644 (file)
index 0000000..ae20421
--- /dev/null
+++ b/rsa.c
@@ -0,0 +1,73 @@
+/* rsa.c
+ *
+ * The RSA publickey algorithm.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "rsa.h"
+
+#include "bignum.h"
+
+void
+rsa_public_key_init(struct rsa_public_key *key)
+{
+  mpz_init(key->n);
+  mpz_init(key->e);
+
+  /* Not really necessary, but it seems cleaner to initialize all the
+   * storage. */
+  key->size = 0;
+}
+
+void
+rsa_public_key_clear(struct rsa_public_key *key)
+{
+  mpz_clear(key->n);
+  mpz_clear(key->e);
+}
+
+/* Computes the size, in octets, of a the modulo. Returns 0 if the
+ * modulo is too small to be useful. */
+
+unsigned
+_rsa_check_size(mpz_t n)
+{
+  /* Round upwards */
+  unsigned size = (mpz_sizeinbase(n, 2) + 7) / 8;
+
+  if (size < RSA_MINIMUM_N_OCTETS)
+    return 0;
+
+  return size;
+}
+
+int
+rsa_public_key_prepare(struct rsa_public_key *key)
+{
+  key->size = _rsa_check_size(key->n);
+  
+  return (key->size > 0);
+}
diff --git a/rsa.h b/rsa.h
new file mode 100644 (file)
index 0000000..9631e50
--- /dev/null
+++ b/rsa.h
@@ -0,0 +1,384 @@
+/* rsa.h
+ *
+ * The RSA publickey algorithm.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_RSA_H_INCLUDED
+#define NETTLE_RSA_H_INCLUDED
+
+#include <gmp.h>
+#include "nettle-types.h"
+
+#include "md5.h"
+#include "sha.h"
+
+/* For nettle_random_func */
+#include "nettle-meta.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define rsa_public_key_init nettle_rsa_public_key_init
+#define rsa_public_key_clear nettle_rsa_public_key_clear
+#define rsa_public_key_prepare nettle_rsa_public_key_prepare
+#define rsa_private_key_init nettle_rsa_private_key_init
+#define rsa_private_key_clear nettle_rsa_private_key_clear
+#define rsa_private_key_prepare nettle_rsa_private_key_prepare
+#define rsa_md5_sign nettle_rsa_md5_sign
+#define rsa_md5_verify nettle_rsa_md5_verify
+#define rsa_sha1_sign nettle_rsa_sha1_sign
+#define rsa_sha1_verify nettle_rsa_sha1_verify
+#define rsa_sha256_sign nettle_rsa_sha256_sign
+#define rsa_sha256_verify nettle_rsa_sha256_verify
+#define rsa_sha512_sign nettle_rsa_sha512_sign
+#define rsa_sha512_verify nettle_rsa_sha512_verify
+#define rsa_md5_sign_digest nettle_rsa_md5_sign_digest
+#define rsa_md5_verify_digest nettle_rsa_md5_verify_digest
+#define rsa_sha1_sign_digest nettle_rsa_sha1_sign_digest
+#define rsa_sha1_verify_digest nettle_rsa_sha1_verify_digest
+#define rsa_sha256_sign_digest nettle_rsa_sha256_sign_digest
+#define rsa_sha256_verify_digest nettle_rsa_sha256_verify_digest
+#define rsa_sha512_sign_digest nettle_rsa_sha512_sign_digest
+#define rsa_sha512_verify_digest nettle_rsa_sha512_verify_digest
+#define rsa_encrypt nettle_rsa_encrypt
+#define rsa_decrypt nettle_rsa_decrypt
+#define rsa_compute_root nettle_rsa_compute_root
+#define rsa_generate_keypair nettle_rsa_generate_keypair
+#define rsa_keypair_to_sexp nettle_rsa_keypair_to_sexp
+#define rsa_keypair_from_sexp_alist nettle_rsa_keypair_from_sexp_alist
+#define rsa_keypair_from_sexp nettle_rsa_keypair_from_sexp
+#define rsa_public_key_from_der_iterator nettle_rsa_public_key_from_der_iterator
+#define rsa_private_key_from_der_iterator nettle_rsa_private_key_from_der_iterator
+#define rsa_keypair_from_der nettle_rsa_keypair_from_der
+#define rsa_keypair_to_openpgp nettle_rsa_keypair_to_openpgp
+#define _rsa_verify _nettle_rsa_verify
+#define _rsa_check_size _nettle_rsa_check_size
+
+/* This limit is somewhat arbitrary. Technically, the smallest modulo
+   which makes sense at all is 15 = 3*5, phi(15) = 8, size 4 bits. But
+   for ridiculously small keys, not all odd e are possible (e.g., for
+   5 bits, the only possible modulo is 3*7 = 21, phi(21) = 12, and e =
+   3 don't work). The smallest size that makes sense with pkcs#1, and
+   which allows RSA encryption of one byte messages, is 12 octets, 89
+   bits. */
+
+#define RSA_MINIMUM_N_OCTETS 12
+#define RSA_MINIMUM_N_BITS (8*RSA_MINIMUM_N_OCTETS - 7)
+
+struct rsa_public_key
+{
+  /* Size of the modulo, in octets. This is also the size of all
+   * signatures that are created or verified with this key. */
+  unsigned size;
+  
+  /* Modulo */
+  mpz_t n;
+
+  /* Public exponent */
+  mpz_t e;
+};
+
+struct rsa_private_key
+{
+  unsigned size;
+
+  /* d is filled in by the key generation function; otherwise it's
+   * completely unused. */
+  mpz_t d;
+  
+  /* The two factors */
+  mpz_t p; mpz_t q;
+
+  /* d % (p-1), i.e. a e = 1 (mod (p-1)) */
+  mpz_t a;
+
+  /* d % (q-1), i.e. b e = 1 (mod (q-1)) */
+  mpz_t b;
+
+  /* modular inverse of q , i.e. c q = 1 (mod p) */
+  mpz_t c;
+};
+
+/* Signing a message works as follows:
+ *
+ * Store the private key in a rsa_private_key struct.
+ *
+ * Call rsa_private_key_prepare. This initializes the size attribute
+ * to the length of a signature.
+ *
+ * Initialize a hashing context, by callling
+ *   md5_init
+ *
+ * Hash the message by calling
+ *   md5_update
+ *
+ * Create the signature by calling
+ *   rsa_md5_sign
+ *
+ * The signature is represented as a mpz_t bignum. This call also
+ * resets the hashing context.
+ *
+ * When done with the key and signature, don't forget to call
+ * mpz_clear.
+ */
+/* Calls mpz_init to initialize bignum storage. */
+void
+rsa_public_key_init(struct rsa_public_key *key);
+
+/* Calls mpz_clear to deallocate bignum storage. */
+void
+rsa_public_key_clear(struct rsa_public_key *key);
+
+int
+rsa_public_key_prepare(struct rsa_public_key *key);
+
+/* Calls mpz_init to initialize bignum storage. */
+void
+rsa_private_key_init(struct rsa_private_key *key);
+
+/* Calls mpz_clear to deallocate bignum storage. */
+void
+rsa_private_key_clear(struct rsa_private_key *key);
+
+int
+rsa_private_key_prepare(struct rsa_private_key *key);
+
+
+/* PKCS#1 style signatures */
+int
+rsa_md5_sign(const struct rsa_private_key *key,
+             struct md5_ctx *hash,
+             mpz_t signature);
+
+
+int
+rsa_md5_verify(const struct rsa_public_key *key,
+               struct md5_ctx *hash,
+              const mpz_t signature);
+
+int
+rsa_sha1_sign(const struct rsa_private_key *key,
+              struct sha1_ctx *hash,
+              mpz_t signature);
+
+int
+rsa_sha1_verify(const struct rsa_public_key *key,
+                struct sha1_ctx *hash,
+               const mpz_t signature);
+
+int
+rsa_sha256_sign(const struct rsa_private_key *key,
+               struct sha256_ctx *hash,
+               mpz_t signature);
+
+int
+rsa_sha256_verify(const struct rsa_public_key *key,
+                 struct sha256_ctx *hash,
+                 const mpz_t signature);
+
+int
+rsa_sha512_sign(const struct rsa_private_key *key,
+               struct sha512_ctx *hash,
+               mpz_t signature);
+
+int
+rsa_sha512_verify(const struct rsa_public_key *key,
+                 struct sha512_ctx *hash,
+                 const mpz_t signature);
+
+/* Variants taking the digest as argument. */
+int
+rsa_md5_sign_digest(const struct rsa_private_key *key,
+                   const uint8_t *digest,
+                   mpz_t s);
+
+int
+rsa_md5_verify_digest(const struct rsa_public_key *key,
+                     const uint8_t *digest,
+                     const mpz_t signature);
+
+int
+rsa_sha1_sign_digest(const struct rsa_private_key *key,
+                    const uint8_t *digest,
+                    mpz_t s);
+
+int
+rsa_sha1_verify_digest(const struct rsa_public_key *key,
+                      const uint8_t *digest,
+                      const mpz_t signature);
+
+int
+rsa_sha256_sign_digest(const struct rsa_private_key *key,
+                      const uint8_t *digest,
+                      mpz_t s);
+
+int
+rsa_sha256_verify_digest(const struct rsa_public_key *key,
+                        const uint8_t *digest,
+                        const mpz_t signature);
+
+int
+rsa_sha512_sign_digest(const struct rsa_private_key *key,
+                      const uint8_t *digest,
+                      mpz_t s);
+
+int
+rsa_sha512_verify_digest(const struct rsa_public_key *key,
+                        const uint8_t *digest,
+                        const mpz_t signature);
+
+
+/* RSA encryption, using PKCS#1 */
+/* These functions uses the v1.5 padding. What should the v2 (OAEP)
+ * functions be called? */
+
+/* Returns 1 on success, 0 on failure, which happens if the
+ * message is too long for the key. */
+int
+rsa_encrypt(const struct rsa_public_key *key,
+           /* For padding */
+           void *random_ctx, nettle_random_func random,
+           unsigned length, const uint8_t *cleartext,
+           mpz_t cipher);
+
+/* Message must point to a buffer of size *LENGTH. KEY->size is enough
+ * for all valid messages. On success, *LENGTH is updated to reflect
+ * the actual length of the message. Returns 1 on success, 0 on
+ * failure, which happens if decryption failed or if the message
+ * didn't fit. */
+int
+rsa_decrypt(const struct rsa_private_key *key,
+           unsigned *length, uint8_t *cleartext,
+           const mpz_t ciphertext);
+
+/* Compute x, the e:th root of m. Calling it with x == m is allowed. */
+void
+rsa_compute_root(const struct rsa_private_key *key,
+                mpz_t x, const mpz_t m);
+
+
+/* Key generation */
+
+/* Note that the key structs must be initialized first. */
+int
+rsa_generate_keypair(struct rsa_public_key *pub,
+                    struct rsa_private_key *key,
+
+                    void *random_ctx, nettle_random_func random,
+                    void *progress_ctx, nettle_progress_func progress,
+
+                    /* Desired size of modulo, in bits */
+                    unsigned n_size,
+                    
+                    /* Desired size of public exponent, in bits. If
+                     * zero, the passed in value pub->e is used. */
+                    unsigned e_size);
+
+
+#define RSA_SIGN(key, algorithm, ctx, length, data, signature) ( \
+  algorithm##_update(ctx, length, data), \
+  rsa_##algorithm##_sign(key, ctx, signature) \
+)
+
+#define RSA_VERIFY(key, algorithm, ctx, length, data, signature) ( \
+  algorithm##_update(ctx, length, data), \
+  rsa_##algorithm##_verify(key, ctx, signature) \
+)
+
+\f
+/* Keys in sexp form. */
+
+struct nettle_buffer;
+
+/* Generates a public-key expression if PRIV is NULL .*/
+int
+rsa_keypair_to_sexp(struct nettle_buffer *buffer,
+                   const char *algorithm_name, /* NULL means "rsa" */
+                   const struct rsa_public_key *pub,
+                   const struct rsa_private_key *priv);
+
+struct sexp_iterator;
+
+int
+rsa_keypair_from_sexp_alist(struct rsa_public_key *pub,
+                           struct rsa_private_key *priv,
+                           unsigned limit,
+                           struct sexp_iterator *i);
+
+/* If PRIV is NULL, expect a public-key expression. If PUB is NULL,
+ * expect a private key expression and ignore the parts not needed for
+ * the public key. */
+/* Keys must be initialized before calling this function, as usual. */
+int
+rsa_keypair_from_sexp(struct rsa_public_key *pub,
+                     struct rsa_private_key *priv,
+                     unsigned limit,
+                     unsigned length, const uint8_t *expr);
+
+
+/* Keys in PKCS#1 format. */
+struct asn1_der_iterator;
+
+int
+rsa_public_key_from_der_iterator(struct rsa_public_key *pub,
+                                unsigned limit,
+                                struct asn1_der_iterator *i);
+
+int
+rsa_private_key_from_der_iterator(struct rsa_public_key *pub,
+                                 struct rsa_private_key *priv,
+                                 unsigned limit,
+                                 struct asn1_der_iterator *i);
+
+/* For public keys, use PRIV == NULL */ 
+int
+rsa_keypair_from_der(struct rsa_public_key *pub,
+                    struct rsa_private_key *priv,
+                    unsigned limit, 
+                    unsigned length, const uint8_t *data);
+
+/* OpenPGP format. Experimental interface, subject to change. */
+int
+rsa_keypair_to_openpgp(struct nettle_buffer *buffer,
+                      const struct rsa_public_key *pub,
+                      const struct rsa_private_key *priv,
+                      /* A single user id. NUL-terminated utf8. */
+                      const char *userid);
+
+/* Internal functions. */
+int
+_rsa_verify(const struct rsa_public_key *key,
+           const mpz_t m,
+           const mpz_t s);
+
+unsigned
+_rsa_check_size(mpz_t n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_RSA_H_INCLUDED */
diff --git a/rsa2openpgp.c b/rsa2openpgp.c
new file mode 100644 (file)
index 0000000..f129ff7
--- /dev/null
@@ -0,0 +1,102 @@
+/* rsa2openpgp.c
+ *
+ * Converting rsa keys to OpenPGP format.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+#include <time.h>
+
+#include "rsa.h"
+
+#include "buffer.h"
+#include "pgp.h"
+
+
+/* According to RFC 2440, a public key consists of the following packets:
+ *
+ * Public key packet
+ *
+ * Zero or more revocation signatures
+ *
+ * One or more User ID packets
+ *
+ * After each User ID packet, zero or more signature packets
+ *
+ * Zero or more Subkey packets
+ *
+ * After each Subkey packet, one signature packet, optionally a
+ * revocation.
+ *
+ * Currently, we generate a public key packet, a single user id, and a
+ * signature. */
+
+int
+rsa_keypair_to_openpgp(struct nettle_buffer *buffer,
+                      const struct rsa_public_key *pub,
+                      const struct rsa_private_key *priv,
+                      /* A single user id. NUL-terminated utf8. */
+                      const char *userid)
+{
+  time_t now = time(NULL);
+
+  unsigned key_start;
+  unsigned key_length;
+  unsigned userid_start;
+  
+  struct sha1_ctx key_hash;
+  struct sha1_ctx signature_hash;
+  uint8_t fingerprint[SHA1_DIGEST_SIZE];
+  
+  key_start = buffer->size;
+  
+  if (!pgp_put_public_rsa_key(buffer, pub, now))
+    return 0;
+
+  /* userid packet */
+  userid_start = buffer->size;
+  if (!pgp_put_userid(buffer, strlen(userid), userid))
+    return 0;
+
+  /* FIXME: We hash the key first, and then the user id. Is this right? */
+  sha1_init(&key_hash);
+  sha1_update(&key_hash,
+             userid_start - key_start,
+             buffer->contents + key_start);
+
+  signature_hash = key_hash;
+  sha1_digest(&key_hash, sizeof(fingerprint), fingerprint);
+
+  sha1_update(&signature_hash,
+             buffer->size - userid_start,
+             buffer->contents + userid_start);
+  
+  return pgp_put_rsa_sha1_signature(buffer,
+                                   priv,
+                                   fingerprint + SHA1_DIGEST_SIZE - 8,
+                                   PGP_SIGN_CERTIFICATION,
+                                   &signature_hash);
+}
diff --git a/rsa2sexp.c b/rsa2sexp.c
new file mode 100644 (file)
index 0000000..8578ec3
--- /dev/null
@@ -0,0 +1,52 @@
+/* rsa2sexp.c
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "rsa.h"
+
+#include "sexp.h"
+
+int
+rsa_keypair_to_sexp(struct nettle_buffer *buffer,
+                   const char *algorithm_name,
+                   const struct rsa_public_key *pub,
+                   const struct rsa_private_key *priv)
+{
+  if (!algorithm_name)
+    algorithm_name = "rsa-pkcs1";
+  
+  if (priv)
+    return sexp_format(buffer,
+                      "(private-key(%0s(n%b)(e%b)"
+                      "(d%b)(p%b)(q%b)(a%b)(b%b)(c%b)))",
+                      algorithm_name, pub->n, pub->e,
+                      priv->d, priv->p, priv->q,
+                      priv->a, priv->b, priv->c);
+  else
+    return sexp_format(buffer, "(public-key(%0s(n%b)(e%b)))",
+                      algorithm_name, pub->n, pub->e);
+}
diff --git a/serpent-decrypt.c b/serpent-decrypt.c
new file mode 100644 (file)
index 0000000..c2847af
--- /dev/null
@@ -0,0 +1,559 @@
+/* serpent-decrypt.c
+ *
+ * The serpent block cipher.
+ *
+ * For more details on this algorithm, see the Serpent website at
+ * http://www.cl.cam.ac.uk/~rja14/serpent.html
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2011  Niels Möller
+ * Copyright (C) 2010, 2011  Simon Josefsson
+ * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* This file is derived from cipher/serpent.c in Libgcrypt v1.4.6.
+   The adaption to Nettle was made by Simon Josefsson on 2010-12-07
+   with final touches on 2011-05-30.  Changes include replacing
+   libgcrypt with nettle in the license template, renaming
+   serpent_context to serpent_ctx, renaming u32 to uint32_t, removing
+   libgcrypt stubs and selftests, modifying entry function prototypes,
+   using FOR_BLOCKS to iterate through data in encrypt/decrypt, using
+   LE_READ_UINT32 and LE_WRITE_UINT32 to access data in
+   encrypt/decrypt, and running indent on the code. */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <limits.h>
+
+#include "serpent.h"
+
+#include "macros.h"
+#include "serpent-internal.h"
+
+/* 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.
+
+  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."  */
+
+/* S0 inverse:  13  3 11  0 10  6  5 12  1 14  4  7 15  9  8  2 */
+/* Original single-assignment form:
+
+     t01 = x2  ^ x3;
+     t02 = x0  | x1;
+     t03 = x1  | x2;
+     t04 = x2  & t01;
+     t05 = t02 ^ t01;
+     t06 = x0  | t04;
+     y2  =     ~ t05;
+     t08 = x1  ^ x3;
+     t09 = t03 & t08;
+     t10 = x3  | y2;
+     y1  = t09 ^ t06;
+     t12 = x0  | t05;
+     t13 = y1  ^ t12;
+     t14 = t03 ^ t10;
+     t15 = x0  ^ x2;
+     y3  = t14 ^ t13;
+     t17 = t05 & t13;
+     t18 = t14 | t17;
+     y0  = t15 ^ t18;
+*/
+#define SBOX0_INVERSE(x0, x1, x2, x3, y0, y1, y2, y3)          \
+  do {                                                         \
+    y0  = x0 ^ x2;                                             \
+    y2  = x0 | x1;                                             \
+    y1  = x2 ^ x3;                                             \
+    y2 ^= y1;                                                  \
+    y1 &= x2;                                                  \
+    x2 |= x1;                                                  \
+    x1 ^= x3;                                                  \
+    y1 |= x0;                                                  \
+    x1 &= x2;                                                  \
+    y1 ^= x1;                                                  \
+    x0 |= y2;                                                  \
+    x0 ^= y1;                                                  \
+    x1  = y2 & x0;                                             \
+    y2  = ~ y2;                                                        \
+    x3 |= y2;                                                  \
+    x3 ^= x2;                                                  \
+    y3  = x3 ^ x0;                                             \
+    x1 |= x3;                                                  \
+    y0 ^= x1;                                                  \
+  } while (0)
+
+/* S1 inverse:   5  8  2 14 15  6 12  3 11  4  7  9  1 13 10  0 */
+/* Original single-assignment form:
+     t01 = x0  ^ x1;
+     t02 = x1  | x3;
+     t03 = x0  & x2;
+     t04 = x2  ^ t02;
+     t05 = x0  | t04;
+     t06 = t01 & t05;
+     t07 = x3  | t03;
+     t08 = x1  ^ t06;
+     t09 = t07 ^ t06;
+     t10 = t04 | t03;
+     t11 = x3  & t08;
+     y2  =     ~ t09;
+     y1  = t10 ^ t11;
+     t14 = x0  | y2;
+     t15 = t06 ^ y1;
+     y3  = t01 ^ t04;
+     t17 = x2  ^ t15;
+     y0  = t14 ^ t17;
+*/
+#define SBOX1_INVERSE(x0, x1, x2, x3, y0, y1, y2, y3)      \
+  do {                                                     \
+    y1  = x1 | x3;                                         \
+    y1 ^= x2;                                              \
+    y3  = x0 ^ x1;                                         \
+    y0  = x0 | y1;                                         \
+    y0 &= y3;                                              \
+    x1 ^= y0;                                              \
+    y3 ^= y1;                                              \
+    x1 &= x3;                                              \
+    y2  = x0 & x2;                                         \
+    y1 |= y2;                                              \
+    y2 |= x3;                                              \
+    y2 ^= y0;                                              \
+    y2  = ~ y2;                                                    \
+    y1 ^= x1;                                              \
+    y0 ^= y1;                                              \
+    y0 ^= x2;                                              \
+    x0 |= y2;                                              \
+    y0 ^= x0;                                              \
+  } while (0)
+
+/* S2 inverse:  12  9 15  4 11 14  1  2  0  3  6 13  5  8 10  7 */
+/* Original single-assignment form:
+     t01 = x0  ^ x3;
+     t02 = x2  ^ x3;
+     t03 = x0  & x2;
+     t04 = x1  | t02;
+     y0  = t01 ^ t04;
+     t06 = x0  | x2;
+     t07 = x3  | y0;
+     t08 =     ~ x3;
+     t09 = x1  & t06;
+     t10 = t08 | t03;
+     t11 = x1  & t07;
+     t12 = t06 & t02;
+     y3  = t09 ^ t10;
+     y1  = t12 ^ t11;
+     t15 = x2  & y3;
+     t16 = y0  ^ y1;
+     t17 = t10 ^ t15;
+     y2  = t16 ^ t17;
+*/
+#define SBOX2_INVERSE(x0, x1, x2, x3, y0, y1, y2, y3)          \
+  do {                                                         \
+    y0  = x0 ^ x3;                                             \
+    y2  = x2 ^ x3;                                             \
+    y1  = x1 | y2;                                             \
+    y0 ^= y1;                                                  \
+    y1  = x3 | y0;                                             \
+    y1 &= x1;                                                  \
+    x3  = ~ x3;                                                        \
+    y3  = x0 | x2;                                             \
+    y2 &= y3;                                                  \
+    y1 ^= y2;                                                  \
+    y3 &= x1;                                                  \
+    x0 &= x2;                                                  \
+    x0 |= x3;                                                  \
+    y3 ^= x0;                                                  \
+    x2 &= y3;                                                  \
+    x2 ^= x0;                                                  \
+    y2  = y0 ^ y1;                                             \
+    y2 ^= x2;                                                  \
+  } while (0)
+
+/* S3 inverse:   0  9 10  7 11 14  6 13  3  5 12  2  4  8 15  1 */
+/* Original single-assignment form:
+     t01 = x2  | x3;
+     t02 = x0  | x3;
+     t03 = x2  ^ t02;
+     t04 = x1  ^ t02;
+     t05 = x0  ^ x3;
+     t06 = t04 & t03;
+     t07 = x1  & t01;
+     y2  = t05 ^ t06;
+     t09 = x0  ^ t03;
+     y0  = t07 ^ t03;
+     t11 = y0  | t05;
+     t12 = t09 & t11;
+     t13 = x0  & y2;
+     t14 = t01 ^ t05;
+     y1  = x1  ^ t12;
+     t16 = x1  | t13;
+     y3  = t14 ^ t16;
+*/
+#define SBOX3_INVERSE(x0, x1, x2, x3, y0, y1, y2, y3)      \
+  do {                                                     \
+    y3  = x2 | x3;                                         \
+    y0  = x1 & y3;                                         \
+    y2  = x0 | x3;                                         \
+    y1  = x2 ^ y2;                                         \
+    y0 ^= y1;                                              \
+    x3 ^= x0;                                              \
+    y3 ^= x3;                                              \
+    y2 ^= x1;                                              \
+    y2 &= y1;                                              \
+    y2 ^= x3;                                              \
+    y1 ^= x0;                                              \
+    x3 |= y0;                                              \
+    y1 &= x3;                                              \
+    y1 ^= x1;                                              \
+    x0 &= y2;                                              \
+    x0 |= x1;                                              \
+    y3 ^= x0;                                              \
+  } while (0)
+
+/* S4 inverse:   5  0  8  3 10  9  7 14  2 12 11  6  4 15 13  1 */
+/* Original single-assignment form:
+     t01 = x1  | x3;
+     t02 = x2  | x3;
+     t03 = x0  & t01;
+     t04 = x1  ^ t02;
+     t05 = x2  ^ x3;
+     t06 =     ~ t03;
+     t07 = x0  & t04;
+     y1  = t05 ^ t07;
+     t09 = y1  | t06;
+     t10 = x0  ^ t07;
+     t11 = t01 ^ t09;
+     t12 = x3  ^ t04;
+     t13 = x2  | t10;
+     y3  = t03 ^ t12;
+     t15 = x0  ^ t04;
+     y2  = t11 ^ t13;
+     y0  = t15 ^ t09;
+*/
+#define SBOX4_INVERSE(x0, x1, x2, x3, y0, y1, y2, y3)      \
+  do {                                                     \
+    y1  = x2 ^ x3;                                         \
+    y2  = x2 | x3;                                         \
+    y2 ^= x1;                                              \
+    x1 |= x3;                                              \
+    y0  = x0 ^ y2;                                         \
+    x3 ^= y2;                                              \
+    y2 &= x0;                                              \
+    y1 ^= y2;                                              \
+    y2 ^= x0;                                              \
+    y2 |= x2;                                              \
+    x0 &=  x1;                                             \
+    y3  = x0 ^ x3;                                         \
+    x0  = ~ x0;                                                    \
+    x0 |= y1;                                              \
+    y0 ^= x0;                                              \
+    x0 ^= x1;                                              \
+    y2 ^= x0;                                              \
+  } while (0)
+
+/* S5 inverse:   8 15  2  9  4  1 13 14 11  6  5  3  7 12 10  0 */
+/* Original single-assignment form:
+     t01 = x0  & x3;
+     t02 = x2  ^ t01;
+     t03 = x0  ^ x3;
+     t04 = x1  & t02;
+     t05 = x0  & x2;
+     y0  = t03 ^ t04;
+     t07 = x0  & y0;
+     t08 = t01 ^ y0;
+     t09 = x1  | t05;
+     t10 =     ~ x1;
+     y1  = t08 ^ t09;
+     t12 = t10 | t07;
+     t13 = y0  | y1;
+     y3  = t02 ^ t12;
+     t15 = t02 ^ t13;
+     t16 = x1  ^ x3;
+     y2  = t16 ^ t15;
+*/
+#define SBOX5_INVERSE(x0, x1, x2, x3, y0, y1, y2, y3)      \
+  do {                                                     \
+    y1  = x0 & x3;                                         \
+    y3  = x2 ^ y1;                                         \
+    y0  = x1 & y3;                                         \
+    y2  = x0 ^ x3;                                         \
+    x3 ^= x1;                                              \
+    y0 ^= y2;                                              \
+    x2 &= x0;                                              \
+    x0 &= y0;                                              \
+    x2 |= x1;                                              \
+    y1 ^= y0;                                              \
+    y1 ^= x2;                                              \
+    y2  = y0 | y1;                                         \
+    y2 ^= y3;                                              \
+    y2 ^= x3;                                              \
+    x1  = ~ x1;                                                    \
+    x1 |= x0;                                              \
+    y3 ^= x1;                                              \
+  } while (0)
+
+/* S6 inverse:  15 10  1 13  5  3  6  0  4  9 14  7  2 12  8 11 */
+/* Original single-assignment form:
+     t01 = x0  ^ x2;
+     t02 =     ~ x2;
+     t03 = x1  & t01;
+     t04 = x1  | t02;
+     t05 = x3  | t03;
+     t06 = x1  ^ x3;
+     t07 = x0  & t04;
+     t08 = x0  | t02;
+     t09 = t07 ^ t05;
+     y1  = t06 ^ t08;
+     y0  =     ~ t09;
+     t12 = x1  & y0;
+     t13 = t01 & t05;
+     t14 = t01 ^ t12;
+     t15 = t07 ^ t13;
+     t16 = x3  | t02;
+     t17 = x0  ^ y1;
+     y3  = t17 ^ t15;
+     y2  = t16 ^ t14;
+ */
+#define SBOX6_INVERSE(x0, x1, x2, x3, y0, y1, y2, y3)      \
+  do {                                                     \
+    y2  = x0 ^ x2;                                         \
+    x2  = ~ x2;                                                    \
+    y0  = x1 ^ x3;                                         \
+    y1  = x0 | x2;                                         \
+    y1 ^= y0;                                              \
+    y3  = x1 & y2;                                         \
+    y3 |= x3;                                              \
+    x3 |= x2;                                              \
+    x2 |= x1;                                              \
+    x2 &= x0;                                              \
+    y0  = x2 ^ y3;                                         \
+    y0  = ~ y0;                                                    \
+    y3 &= y2;                                              \
+    y3 ^= x2;                                              \
+    x0 ^= y1;                                              \
+    y3 ^= x0;                                              \
+    x1 &= y0;                                              \
+    y2 ^= x1;                                              \
+    y2 ^= x3;                                              \
+  } while (0)
+
+/* S7 inverse:   3  0  6 13  9 14 15  8  5 12 11  7 10  1  4  2 */
+/* Original single-assignment form:
+     t01 = x0  & x1;
+     t02 = x0  | x1;
+     t03 = x2  | t01;
+     t04 = x3  & t02;
+     y3  = t03 ^ t04;
+     t06 = x1  ^ t04;
+     t07 = x3  ^ y3;
+     t08 =     ~ t07;
+     t09 = t06 | t08;
+     t10 = x1  ^ x3;
+     t11 = x0  | x3;
+     y1  = x0  ^ t09;
+     t13 = x2  ^ t06;
+     t14 = x2  & t11;
+     t15 = x3  | y1;
+     t16 = t01 | t10;
+     y0  = t13 ^ t15;
+     y2  = t14 ^ t16;
+*/
+#define SBOX7_INVERSE(x0, x1, x2, x3, y0, y1, y2, y3)      \
+  do {                                                     \
+    y3  = x0 & x1;                                         \
+    y2  = x1 ^ x3;                                         \
+    y2 |= y3;                                              \
+    y1  = x0 | x3;                                         \
+    y1 &= x2;                                              \
+    y2 ^= y1;                                              \
+    y3 |= x2;                                              \
+    y0  = x0 | x1;                                         \
+    y0 &= x3;                                              \
+    y3 ^= y0;                                              \
+    y0 ^= x1;                                              \
+    y1  = x3 ^ y3;                                         \
+    y1  = ~ y1;                                                    \
+    y1 |= y0;                                              \
+    y0 ^= x2;                                              \
+    y1 ^= x0;                                              \
+    x3 |= y1;                                              \
+    y0 ^= x3;                                              \
+  } while (0)
+
+/* In-place inverse linear transformation.  */
+#define LINEAR_TRANSFORMATION_INVERSE(x0,x1,x2,x3)      \
+  do {                                                   \
+    x2 = ROL32 (x2, 10);                    \
+    x0 = ROL32 (x0, 27);                    \
+    x2 = x2 ^ x3 ^ (x1 << 7); \
+    x0 = x0 ^ x1 ^ x3;        \
+    x3 = ROL32 (x3, 25);                     \
+    x1 = ROL32 (x1, 31);                     \
+    x3 = x3 ^ x2 ^ (x0 << 3); \
+    x1 = x1 ^ x0 ^ x2;        \
+    x2 = ROL32 (x2, 29);                     \
+    x0 = ROL32 (x0, 19);                    \
+  } while (0)
+
+/* Round inputs are x0,x1,x2,x3 (destroyed), and round outputs are
+   y0,y1,y2,y3. */
+#define ROUND_INVERSE(which, subkey, x0,x1,x2,x3, y0,y1,y2,y3) \
+  do {                                                        \
+    LINEAR_TRANSFORMATION_INVERSE (x0,x1,x2,x3);              \
+    SBOX##which##_INVERSE(x0,x1,x2,x3, y0,y1,y2,y3);          \
+    KEYXOR(y0,y1,y2,y3, subkey);                              \
+  } while (0)
+
+#if HAVE_NATIVE_64_BIT
+
+/* In-place inverse linear transformation.  */
+#define LINEAR_TRANSFORMATION64_INVERSE(x0,x1,x2,x3)    \
+  do {                                                   \
+    x2 = ROL64 (x2, 10);                    \
+    x0 = ROL64 (x0, 27);                    \
+    x2 = x2 ^ x3 ^ RSHIFT64(x1, 7); \
+    x0 = x0 ^ x1 ^ x3;        \
+    x3 = ROL64 (x3, 25);                     \
+    x1 = ROL64 (x1, 31);                     \
+    x3 = x3 ^ x2 ^ RSHIFT64(x0, 3); \
+    x1 = x1 ^ x0 ^ x2;        \
+    x2 = ROL64 (x2, 29);                     \
+    x0 = ROL64 (x0, 19);                    \
+  } while (0)
+
+#define ROUND64_INVERSE(which, subkey, x0,x1,x2,x3, y0,y1,y2,y3) \
+  do {                                                        \
+    LINEAR_TRANSFORMATION64_INVERSE (x0,x1,x2,x3);            \
+    SBOX##which##_INVERSE(x0,x1,x2,x3, y0,y1,y2,y3);          \
+    KEYXOR64(y0,y1,y2,y3, subkey);                            \
+  } while (0)
+
+#endif /* HAVE_NATIVE_64_BIT */
+
+void
+serpent_decrypt (const struct serpent_ctx *ctx,
+                unsigned length, uint8_t * dst, const uint8_t * src)
+{
+  assert( !(length % SERPENT_BLOCK_SIZE));
+
+#if HAVE_NATIVE_64_BIT
+  if (length & SERPENT_BLOCK_SIZE)
+#else
+  while (length >= SERPENT_BLOCK_SIZE)
+#endif
+    {
+      uint32_t x0,x1,x2,x3, y0,y1,y2,y3;
+      unsigned k;
+
+      x0 = LE_READ_UINT32 (src);
+      x1 = LE_READ_UINT32 (src + 4);
+      x2 = LE_READ_UINT32 (src + 8);
+      x3 = LE_READ_UINT32 (src + 12);
+
+      /* Inverse of special round */
+      KEYXOR (x0,x1,x2,x3, ctx->keys[32]);
+      SBOX7_INVERSE (x0,x1,x2,x3, y0,y1,y2,y3);
+      KEYXOR (y0,y1,y2,y3, ctx->keys[31]);
+
+      k = 24;
+      goto start32;
+      while (k > 0)
+       {
+         k -= 8;
+         ROUND_INVERSE (7, ctx->keys[k+7], x0,x1,x2,x3, y0,y1,y2,y3);
+       start32:
+         ROUND_INVERSE (6, ctx->keys[k+6], y0,y1,y2,y3, x0,x1,x2,x3);
+         ROUND_INVERSE (5, ctx->keys[k+5], x0,x1,x2,x3, y0,y1,y2,y3);
+         ROUND_INVERSE (4, ctx->keys[k+4], y0,y1,y2,y3, x0,x1,x2,x3);
+         ROUND_INVERSE (3, ctx->keys[k+3], x0,x1,x2,x3, y0,y1,y2,y3);
+         ROUND_INVERSE (2, ctx->keys[k+2], y0,y1,y2,y3, x0,x1,x2,x3);
+         ROUND_INVERSE (1, ctx->keys[k+1], x0,x1,x2,x3, y0,y1,y2,y3);
+         ROUND_INVERSE (0, ctx->keys[k], y0,y1,y2,y3, x0,x1,x2,x3);
+       }
+      
+      LE_WRITE_UINT32 (dst, x0);
+      LE_WRITE_UINT32 (dst + 4, x1);
+      LE_WRITE_UINT32 (dst + 8, x2);
+      LE_WRITE_UINT32 (dst + 12, x3);
+
+      src += SERPENT_BLOCK_SIZE;
+      dst += SERPENT_BLOCK_SIZE;
+      length -= SERPENT_BLOCK_SIZE;
+    }
+#if HAVE_NATIVE_64_BIT
+  FOR_BLOCKS(length, dst, src, 2*SERPENT_BLOCK_SIZE)
+    {
+      uint64_t x0,x1,x2,x3, y0,y1,y2,y3;
+      unsigned k;
+
+      x0 = LE_READ_UINT32 (src);
+      x1 = LE_READ_UINT32 (src + 4);
+      x2 = LE_READ_UINT32 (src + 8);
+      x3 = LE_READ_UINT32 (src + 12);
+
+      x0 <<= 32; x0 |= LE_READ_UINT32 (src + 16);
+      x1 <<= 32; x1 |= LE_READ_UINT32 (src + 20);
+      x2 <<= 32; x2 |= LE_READ_UINT32 (src + 24);
+      x3 <<= 32; x3 |= LE_READ_UINT32 (src + 28);
+
+      /* Inverse of special round */
+      KEYXOR64 (x0,x1,x2,x3, ctx->keys[32]);
+      SBOX7_INVERSE (x0,x1,x2,x3, y0,y1,y2,y3);
+      KEYXOR64 (y0,y1,y2,y3, ctx->keys[31]);
+
+      k = 24;
+      goto start64;
+      while (k > 0)
+       {
+         k -= 8;
+         ROUND64_INVERSE (7, ctx->keys[k+7], x0,x1,x2,x3, y0,y1,y2,y3);
+       start64:
+         ROUND64_INVERSE (6, ctx->keys[k+6], y0,y1,y2,y3, x0,x1,x2,x3);
+         ROUND64_INVERSE (5, ctx->keys[k+5], x0,x1,x2,x3, y0,y1,y2,y3);
+         ROUND64_INVERSE (4, ctx->keys[k+4], y0,y1,y2,y3, x0,x1,x2,x3);
+         ROUND64_INVERSE (3, ctx->keys[k+3], x0,x1,x2,x3, y0,y1,y2,y3);
+         ROUND64_INVERSE (2, ctx->keys[k+2], y0,y1,y2,y3, x0,x1,x2,x3);
+         ROUND64_INVERSE (1, ctx->keys[k+1], x0,x1,x2,x3, y0,y1,y2,y3);
+         ROUND64_INVERSE (0, ctx->keys[k], y0,y1,y2,y3, x0,x1,x2,x3);
+       }
+    
+      LE_WRITE_UINT32 (dst + 16, x0);
+      LE_WRITE_UINT32 (dst + 20, x1);
+      LE_WRITE_UINT32 (dst + 24, x2);
+      LE_WRITE_UINT32 (dst + 28, x3);
+      x0 >>= 32; LE_WRITE_UINT32 (dst, x0);
+      x1 >>= 32; LE_WRITE_UINT32 (dst + 4, x1);
+      x2 >>= 32; LE_WRITE_UINT32 (dst + 8, x2);
+      x3 >>= 32; LE_WRITE_UINT32 (dst + 12, x3);
+    }
+#endif /* HAVE_NATIVE_64_BIT */  
+}
diff --git a/serpent-encrypt.c b/serpent-encrypt.c
new file mode 100644 (file)
index 0000000..21651e8
--- /dev/null
@@ -0,0 +1,528 @@
+/* serpent-encrypt.c
+ *
+ * The serpent block cipher.
+ *
+ * For more details on this algorithm, see the Serpent website at
+ * http://www.cl.cam.ac.uk/~rja14/serpent.html
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2011  Niels Möller
+ * Copyright (C) 2010, 2011  Simon Josefsson
+ * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* This file is derived from cipher/serpent.c in Libgcrypt v1.4.6.
+   The adaption to Nettle was made by Simon Josefsson on 2010-12-07
+   with final touches on 2011-05-30.  Changes include replacing
+   libgcrypt with nettle in the license template, renaming
+   serpent_context to serpent_ctx, renaming u32 to uint32_t, removing
+   libgcrypt stubs and selftests, modifying entry function prototypes,
+   using FOR_BLOCKS to iterate through data in encrypt/decrypt, using
+   LE_READ_UINT32 and LE_WRITE_UINT32 to access data in
+   encrypt/decrypt, and running indent on the code. */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <limits.h>
+
+#include "serpent.h"
+
+#include "macros.h"
+#include "serpent-internal.h"
+
+/* 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.
+
+  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."  */
+
+/* S0:  3  8 15  1 10  6  5 11 14 13  4  2  7  0  9 12 */
+/* Could easily let y0, y1 overlap with x0, x1, and possibly also x2 and y2 */
+#define SBOX0(x0, x1, x2, x3, y0, y1, y2, y3)  \
+  do {                                                 \
+    y3  = x1 ^ x2;                                     \
+    y0  = x0 | x3;                                     \
+    y1  = x0 ^ x1;                                     \
+    y3 ^= y0;                                          \
+    y2  = x2 | y3;                                     \
+    x0 ^= x3;                                          \
+    y2 &= x3;                                          \
+    x3 ^= x2;                                          \
+    x2 |= x1;                                          \
+    y0  = y1 & x2;                                     \
+    y2 ^= y0;                                          \
+    y0 &= y2;                                          \
+    y0 ^= x2;                                          \
+    x1 &= x0;                                          \
+    y0 ^= x0;                                          \
+    y0  = ~ y0;                                                \
+    y1  = y0 ^ x1;                                     \
+    y1 ^= x3;                                          \
+  } while (0)
+
+/* FIXME: Arrange for some overlap between inputs and outputs? */
+/* S1: 15 12  2  7  9  0  5 10  1 11 14  8  6 13  3  4 */
+/* Original single-assignment form:
+   
+     t01 = x0  | x3;
+     t02 = x2  ^ x3;
+     t03 =     ~ x1;
+     t04 = x0  ^ x2;
+     t05 = x0  | t03;
+     t06 = x3  & t04;
+     t07 = t01 & t02;
+     t08 = x1  | t06;
+     y2  = t02 ^ t05;
+     t10 = t07 ^ t08;
+     t11 = t01 ^ t10;
+     t12 = y2  ^ t11;
+     t13 = x1  & x3;
+     y3  =     ~ t10;
+     y1  = t13 ^ t12;
+     t16 = t10 | y1;
+     t17 = t05 & t16;
+     y0  = x2  ^ t17;
+*/
+#define SBOX1(x0, x1, x2, x3, y0, y1, y2, y3)          \
+  do {                                                 \
+    y1  = x0 | x3;                                     \
+    y2  = x2 ^ x3;                                     \
+    y0  = ~ x1;                                                \
+    y3  = x0 ^ x2;                                     \
+    y0 |= x0;                                          \
+    y3 &= x3;                                          \
+    x0 = y1 & y2;                                      \
+    y3 |= x1;                                          \
+    y2 ^= y0;                                          \
+    y3 ^= x0;                                          \
+    x0  = y1 ^ y3;                                     \
+    x0 ^= y2;                                          \
+    y1  = x1 & x3;                                     \
+    y1 ^= x0;                                          \
+    x3  = y1 | y3;                                     \
+    y3  = ~ y3;                                                \
+    y0 &= x3;                                          \
+    y0 ^= x2;                                          \
+  } while (0)
+
+/* FIXME: Arrange for some overlap between inputs and outputs? */
+/* S2:  8  6  7  9  3 12 10 15 13  1 14  4  0 11  5  2 */
+#define SBOX2(x0, x1, x2, x3, y0, y1, y2, y3)  \
+  do {                                                 \
+    y2  = x0 | x2;                                     \
+    y1  = x0 ^ x1;                                     \
+    y3  = x3 ^ y2;                                     \
+    y0  = y1 ^ y3;                                     \
+    x3 |= x0;                                          \
+    x2 ^= y0;                                          \
+    x0  = x1 ^ x2;                                     \
+    x2 |= x1;                                          \
+    x0 &= y2;                                          \
+    y3 ^= x2;                                          \
+    y1 |= y3;                                          \
+    y1 ^= x0;                                          \
+    y2  = y3 ^ y1;                                     \
+    y2 ^= x1;                                          \
+    y3  = ~ y3;                                                \
+    y2 ^= x3;                                          \
+  } while (0)
+
+/* S3:  0 15 11  8 12  9  6  3 13  1  2  4 10  7  5 14 */
+/* Original single-assignment form:
+   
+     t01 = x0  ^ x2;
+     t02 = x0  | x3;
+     t03 = x0  & x3;
+     t04 = t01 & t02;
+     t05 = x1  | t03;
+     t06 = x0  & x1;
+     t07 = x3  ^ t04;
+     t08 = x2  | t06;
+     t09 = x1  ^ t07;
+     t10 = x3  & t05;
+     t11 = t02 ^ t10;
+     y3  = t08 ^ t09;
+     t13 = x3  | y3;
+     t14 = x0  | t07;
+     t15 = x1  & t13;
+     y2  = t08 ^ t11;
+     y0  = t14 ^ t15;
+     y1  = t05 ^ t04;
+*/
+#define SBOX3(x0, x1, x2, x3, y0, y1, y2, y3)  \
+  do {                                                 \
+    y1  = x0 ^ x2;                                     \
+    y0  = x0 | x3;                                     \
+    y3  = x0 & x3;                                     \
+    y1 &= y0;                                          \
+    y3 |= x1;                                          \
+    y2  = x0 & x1;                                     \
+    y2 |= x2;                                          \
+    x2  = x3 ^ y1;                                     \
+    y1 ^= y3;                                          \
+    x0 |= x2;                                          \
+    x2 ^= x1;                                          \
+    y3 &= x3;                                          \
+    y0 ^= y3;                                          \
+    y3  = y2 ^ x2;                                     \
+    y2 ^= y0;                                          \
+    x3 |= y3;                                          \
+    x1 &= x3;                                          \
+    y0  = x0 ^ x1;                                     \
+  } while (0)
+
+
+/* S4:  1 15  8  3 12  0 11  6  2  5  4 10  9 14  7 13 */
+/* Original single-assignment form:
+    t01 = x0  | x1;
+    t02 = x1  | x2;
+    t03 = x0  ^ t02;
+    t04 = x1  ^ x3;
+    t05 = x3  | t03;
+    t06 = x3  & t01;
+    y3  = t03 ^ t06;
+    t08 = y3  & t04;
+    t09 = t04 & t05;
+    t10 = x2  ^ t06;
+    t11 = x1  & x2;
+    t12 = t04 ^ t08;
+    t13 = t11 | t03;
+    t14 = t10 ^ t09;
+    t15 = x0  & t05;
+    t16 = t11 | t12;
+    y2  = t13 ^ t08;
+    y1  = t15 ^ t16;
+    y0  =     ~ t14;
+*/
+#define SBOX4(x0, x1, x2, x3, y0, y1, y2, y3)  \
+  do {                                                 \
+    y3  = x0 | x1;                                     \
+    y2  = x1 | x2;                                     \
+    y2 ^= x0;                                          \
+    y3 &= x3;                                          \
+    y0  = x1 ^ x3;                                     \
+    x3 |= y2;                                          \
+    x0 &= x3;                                          \
+    x1 &= x2;                                          \
+    x2 ^= y3;                                          \
+    y3 ^= y2;                                          \
+    y2 |= x1;                                          \
+    y1  = y3 & y0;                                     \
+    y2 ^= y1;                                          \
+    y1 ^= y0;                                          \
+    y1 |= x1;                                          \
+    y1 ^= x0;                                          \
+    y0 &= x3;                                          \
+    y0 ^= x2;                                          \
+    y0  = ~y0;                                         \
+  } while (0)
+
+/* S5: 15  5  2 11  4 10  9 12  0  3 14  8 13  6  7  1 */
+/* Original single-assignment form:
+    t01 = x1  ^ x3;
+    t02 = x1  | x3;
+    t03 = x0  & t01;
+    t04 = x2  ^ t02;
+    t05 = t03 ^ t04;
+    y0  =     ~ t05;
+    t07 = x0  ^ t01;
+    t08 = x3  | y0;
+    t09 = x1  | t05;
+    t10 = x3  ^ t08;
+    t11 = x1  | t07;
+    t12 = t03 | y0;
+    t13 = t07 | t10;
+    t14 = t01 ^ t11;
+    y2  = t09 ^ t13;
+    y1  = t07 ^ t08;
+    y3  = t12 ^ t14;
+*/
+#define SBOX5(x0, x1, x2, x3, y0, y1, y2, y3)  \
+  do {                                                 \
+    y0  = x1 | x3;                                     \
+    y0 ^= x2;                                          \
+    x2  = x1 ^ x3;                                     \
+    y2  = x0 ^ x2;                                     \
+    x0 &= x2;                                          \
+    y0 ^= x0;                                          \
+    y3  = x1 | y2;                                     \
+    x1 |= y0;                                          \
+    y0  = ~y0;                                         \
+    x0 |= y0;                                          \
+    y3 ^= x2;                                          \
+    y3 ^= x0;                                          \
+    y1  = x3 | y0;                                     \
+    x3 ^= y1;                                          \
+    y1 ^= y2;                                          \
+    y2 |= x3;                                          \
+    y2 ^= x1;                                          \
+  } while (0)
+
+/* S6:  7  2 12  5  8  4  6 11 14  9  1 15 13  3 10  0 */
+/* Original single-assignment form:
+    t01 = x0  & x3;
+    t02 = x1  ^ x2;
+    t03 = x0  ^ x3;
+    t04 = t01 ^ t02;
+    t05 = x1  | x2;
+    y1  =     ~ t04;
+    t07 = t03 & t05;
+    t08 = x1  & y1;
+    t09 = x0  | x2;
+    t10 = t07 ^ t08;
+    t11 = x1  | x3;
+    t12 = x2  ^ t11;
+    t13 = t09 ^ t10;
+    y2  =     ~ t13;
+    t15 = y1  & t03;
+    y3  = t12 ^ t07;
+    t17 = x0  ^ x1;
+    t18 = y2  ^ t15;
+    y0  = t17 ^ t18;
+*/
+#define SBOX6(x0, x1, x2, x3, y0, y1, y2, y3)  \
+  do {                                                 \
+    y0  = x0 ^ x3;                                     \
+    y1  = x0 & x3;                                     \
+    y2  = x0 | x2;                                     \
+    x3 |= x1;                                          \
+    x3 ^= x2;                                          \
+    x0 ^= x1;                                          \
+    y3  = x1 | x2;                                     \
+    x2 ^= x1;                                          \
+    y3 &= y0;                                          \
+    y1 ^= x2;                                          \
+    y1  = ~y1;                                         \
+    y0 &= y1;                                          \
+    x1 &= y1;                                          \
+    x1 ^= y3;                                          \
+    y3 ^= x3;                                          \
+    y2 ^= x1;                                          \
+    y2  = ~y2;                                         \
+    y0 ^= y2;                                          \
+    y0 ^= x0;                                          \
+  } while (0)
+
+/* S7:  1 13 15  0 14  8  2 11  7  4 12 10  9  3  5  6 */
+/* Original single-assignment form:
+    t01 = x0  & x2;
+    t02 =     ~ x3;
+    t03 = x0  & t02;
+    t04 = x1  | t01;
+    t05 = x0  & x1;
+    t06 = x2  ^ t04;
+    y3  = t03 ^ t06;
+    t08 = x2  | y3;
+    t09 = x3  | t05;
+    t10 = x0  ^ t08;
+    t11 = t04 & y3;
+    y1  = t09 ^ t10;
+    t13 = x1  ^ y1;
+    t14 = t01 ^ y1;
+    t15 = x2  ^ t05;
+    t16 = t11 | t13;
+    t17 = t02 | t14;
+    y0  = t15 ^ t17;
+    y2  = x0  ^ t16;
+*/
+/* It appears impossible to do this with only 8 registers. We
+   recompute t02, and t04 (if we have spare registers, hopefully the
+   compiler can recognize them as common subexpressions). */
+#define SBOX7(x0, x1, x2, x3, y0, y1, y2, y3)  \
+  do {                                                 \
+    y0  = x0 & x2;                                     \
+    y3  = x1 | y0; /* t04 */                           \
+    y3 ^= x2;                                          \
+    y1  = ~x3;     /* t02 */                           \
+    y1 &= x0;                                          \
+    y3 ^= y1;                                          \
+    y1  = x2 | y3;                                     \
+    y1 ^= x0;                                          \
+    y2  = x0 & x1;                                     \
+    x2 ^= y2;                                          \
+    y2 |= x3;                                          \
+    y1 ^= y2;                                          \
+    y2  = x1 | y0; /* t04 */                           \
+    y2 &= y3;                                          \
+    x1 ^= y1;                                          \
+    y2 |= x1;                                          \
+    y2 ^= x0;                                          \
+    y0 ^= y1;                                          \
+    x3  = ~x3;     /* t02 */                           \
+    y0 |= x3;                                          \
+    y0 ^= x2;                                          \
+  } while (0)
+
+/* In-place linear transformation.  */
+#define LINEAR_TRANSFORMATION(x0,x1,x2,x3)              \
+  do {                                                   \
+    x0 = ROL32 (x0, 13);                    \
+    x2 = ROL32 (x2, 3);                     \
+    x1 = x1 ^ x0 ^ x2;        \
+    x3 = x3 ^ x2 ^ (x0 << 3); \
+    x1 = ROL32 (x1, 1);                     \
+    x3 = ROL32 (x3, 7);                     \
+    x0 = x0 ^ x1 ^ x3;        \
+    x2 = x2 ^ x3 ^ (x1 << 7); \
+    x0 = ROL32 (x0, 5);                     \
+    x2 = ROL32 (x2, 22);                    \
+  } while (0)
+
+/* Round inputs are x0,x1,x2,x3 (destroyed), and round outputs are
+   y0,y1,y2,y3. */
+#define ROUND(which, subkey, x0,x1,x2,x3, y0,y1,y2,y3) \
+  do {                                                \
+    KEYXOR(x0,x1,x2,x3, subkey);                      \
+    SBOX##which(x0,x1,x2,x3, y0,y1,y2,y3);            \
+    LINEAR_TRANSFORMATION(y0,y1,y2,y3);                       \
+  } while (0)
+
+#if HAVE_NATIVE_64_BIT
+
+#define LINEAR_TRANSFORMATION64(x0,x1,x2,x3)            \
+  do {                                                   \
+    x0 = ROL64 (x0, 13);                    \
+    x2 = ROL64 (x2, 3);                     \
+    x1 = x1 ^ x0 ^ x2;        \
+    x3 = x3 ^ x2 ^ RSHIFT64(x0, 3);        \
+    x1 = ROL64 (x1, 1);                     \
+    x3 = ROL64 (x3, 7);                     \
+    x0 = x0 ^ x1 ^ x3;        \
+    x2 = x2 ^ x3 ^ RSHIFT64(x1, 7);        \
+    x0 = ROL64 (x0, 5);                     \
+    x2 = ROL64 (x2, 22);                    \
+  } while (0)
+
+#define ROUND64(which, subkey, x0,x1,x2,x3, y0,y1,y2,y3) \
+  do {                                                \
+    KEYXOR64(x0,x1,x2,x3, subkey);                    \
+    SBOX##which(x0,x1,x2,x3, y0,y1,y2,y3);            \
+    LINEAR_TRANSFORMATION64(y0,y1,y2,y3);                     \
+  } while (0)
+
+#endif /* HAVE_NATIVE_64_BIT */
+
+void
+serpent_encrypt (const struct serpent_ctx *ctx,
+                unsigned length, uint8_t * dst, const uint8_t * src)
+{
+  assert( !(length % SERPENT_BLOCK_SIZE));
+  
+#if HAVE_NATIVE_64_BIT
+  if (length & SERPENT_BLOCK_SIZE)
+#else
+  while (length >= SERPENT_BLOCK_SIZE)
+#endif
+    {
+      uint32_t x0,x1,x2,x3, y0,y1,y2,y3;
+      unsigned k;
+
+      x0 = LE_READ_UINT32 (src);
+      x1 = LE_READ_UINT32 (src + 4);
+      x2 = LE_READ_UINT32 (src + 8);
+      x3 = LE_READ_UINT32 (src + 12);
+
+      for (k = 0; ; k += 8)
+       {
+         ROUND (0, ctx->keys[k+0], x0,x1,x2,x3, y0,y1,y2,y3);
+         ROUND (1, ctx->keys[k+1], y0,y1,y2,y3, x0,x1,x2,x3);
+         ROUND (2, ctx->keys[k+2], x0,x1,x2,x3, y0,y1,y2,y3);
+         ROUND (3, ctx->keys[k+3], y0,y1,y2,y3, x0,x1,x2,x3);
+         ROUND (4, ctx->keys[k+4], x0,x1,x2,x3, y0,y1,y2,y3);
+         ROUND (5, ctx->keys[k+5], y0,y1,y2,y3, x0,x1,x2,x3);
+         ROUND (6, ctx->keys[k+6], x0,x1,x2,x3, y0,y1,y2,y3);
+         if (k == 24)
+           break;
+         ROUND (7, ctx->keys[k+7], y0,y1,y2,y3, x0,x1,x2,x3);
+       }
+
+      /* Special final round, using two subkeys. */
+      KEYXOR (y0,y1,y2,y3, ctx->keys[31]);
+      SBOX7 (y0,y1,y2,y3, x0,x1,x2,x3);
+      KEYXOR (x0,x1,x2,x3, ctx->keys[32]);
+    
+      LE_WRITE_UINT32 (dst, x0);
+      LE_WRITE_UINT32 (dst + 4, x1);
+      LE_WRITE_UINT32 (dst + 8, x2);
+      LE_WRITE_UINT32 (dst + 12, x3);
+
+      src += SERPENT_BLOCK_SIZE;
+      dst += SERPENT_BLOCK_SIZE;
+      length -= SERPENT_BLOCK_SIZE;
+    }
+#if HAVE_NATIVE_64_BIT
+  FOR_BLOCKS(length, dst, src, 2*SERPENT_BLOCK_SIZE)
+    {
+      uint64_t x0,x1,x2,x3, y0,y1,y2,y3;
+      unsigned k;
+
+      x0 = LE_READ_UINT32 (src);
+      x1 = LE_READ_UINT32 (src + 4);
+      x2 = LE_READ_UINT32 (src + 8);
+      x3 = LE_READ_UINT32 (src + 12);
+
+      x0 <<= 32; x0 |= LE_READ_UINT32 (src + 16);
+      x1 <<= 32; x1 |= LE_READ_UINT32 (src + 20);
+      x2 <<= 32; x2 |= LE_READ_UINT32 (src + 24);
+      x3 <<= 32; x3 |= LE_READ_UINT32 (src + 28);
+
+      for (k = 0; ; k += 8)
+       {
+         ROUND64 (0, ctx->keys[k+0], x0,x1,x2,x3, y0,y1,y2,y3);
+         ROUND64 (1, ctx->keys[k+1], y0,y1,y2,y3, x0,x1,x2,x3);
+         ROUND64 (2, ctx->keys[k+2], x0,x1,x2,x3, y0,y1,y2,y3);
+         ROUND64 (3, ctx->keys[k+3], y0,y1,y2,y3, x0,x1,x2,x3);
+         ROUND64 (4, ctx->keys[k+4], x0,x1,x2,x3, y0,y1,y2,y3);
+         ROUND64 (5, ctx->keys[k+5], y0,y1,y2,y3, x0,x1,x2,x3);
+         ROUND64 (6, ctx->keys[k+6], x0,x1,x2,x3, y0,y1,y2,y3);
+         if (k == 24)
+           break;
+         ROUND64 (7, ctx->keys[k+7], y0,y1,y2,y3, x0,x1,x2,x3);
+       }
+
+      /* Special final round, using two subkeys. */
+      KEYXOR64 (y0,y1,y2,y3, ctx->keys[31]);
+      SBOX7 (y0,y1,y2,y3, x0,x1,x2,x3);
+      KEYXOR64 (x0,x1,x2,x3, ctx->keys[32]);
+    
+      LE_WRITE_UINT32 (dst + 16, x0);
+      LE_WRITE_UINT32 (dst + 20, x1);
+      LE_WRITE_UINT32 (dst + 24, x2);
+      LE_WRITE_UINT32 (dst + 28, x3);
+      x0 >>= 32; LE_WRITE_UINT32 (dst, x0);
+      x1 >>= 32; LE_WRITE_UINT32 (dst + 4, x1);
+      x2 >>= 32; LE_WRITE_UINT32 (dst + 8, x2);
+      x3 >>= 32; LE_WRITE_UINT32 (dst + 12, x3);
+    }
+#endif /* HAVE_NATIVE_64_BIT */
+}
diff --git a/serpent-internal.h b/serpent-internal.h
new file mode 100644 (file)
index 0000000..66d5af4
--- /dev/null
@@ -0,0 +1,75 @@
+/* serpent-internal-h
+ *
+ * The serpent block cipher.
+ *
+ * For more details on this algorithm, see the Serpent website at
+ * http://www.cl.cam.ac.uk/~rja14/serpent.html
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2011  Niels Möller
+ * Copyright (C) 2010, 2011  Simon Josefsson
+ * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* This file is derived from cipher/serpent.c in Libgcrypt v1.4.6.
+   The adaption to Nettle was made by Simon Josefsson on 2010-12-07
+   with final touches on 2011-05-30.  Changes include replacing
+   libgcrypt with nettle in the license template, renaming
+   serpent_context to serpent_ctx, renaming u32 to uint32_t, removing
+   libgcrypt stubs and selftests, modifying entry function prototypes,
+   using FOR_BLOCKS to iterate through data in encrypt/decrypt, using
+   LE_READ_UINT32 and LE_WRITE_UINT32 to access data in
+   encrypt/decrypt, and running indent on the code. */
+
+#ifndef NETTLE_SERPENT_INTERNAL_H_INCLUDED
+#define NETTLE_SERPENT_INTERNAL_H_INCLUDED
+
+/* FIXME: Unify ROL macros used here, in camellia.c and cast128.c. */
+#define ROL32(x,n) ((((x))<<(n)) | (((x))>>(32-(n))))
+
+#define KEYXOR(x0,x1,x2,x3, subkey)                   \
+  do {                                                \
+    (x0) ^= (subkey)[0];                              \
+    (x1) ^= (subkey)[1];                              \
+    (x2) ^= (subkey)[2];                              \
+    (x3) ^= (subkey)[3];                              \
+  } while (0)
+
+#if HAVE_NATIVE_64_BIT
+/* Operate independently on both halves of a 64-bit word. */
+#define ROL64(x,n) \
+  (((x) << (n) & ~(((1L << (n))-1) << 32)) \
+   |(((x) >> (32-(n))) & ~(((1L << (32-(n)))-1) << (n))))
+
+#define KEYXOR64(x0,x1,x2,x3, subkey)                 \
+  do {                                                \
+    uint64_t _sk;                                     \
+    _sk = (subkey)[0]; _sk |= _sk << 32; (x0) ^= _sk;    \
+    _sk = (subkey)[1]; _sk |= _sk << 32; (x1) ^= _sk;    \
+    _sk = (subkey)[2]; _sk |= _sk << 32; (x2) ^= _sk;    \
+    _sk = (subkey)[3]; _sk |= _sk << 32; (x3) ^= _sk;    \
+  } while (0)
+
+#define RSHIFT64(x,n) \
+  ( ((x) << (n)) & ~(((1L << n) - 1) << 32))
+#endif /* HAVE_NATIVE_64_BIT */
+
+#endif /* NETTLE_SERPENT_INTERNAL_H_INCLUDED */
+
diff --git a/serpent-meta.c b/serpent-meta.c
new file mode 100644 (file)
index 0000000..204d2a1
--- /dev/null
@@ -0,0 +1,38 @@
+/* serpent-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "serpent.h"
+
+const struct nettle_cipher nettle_serpent128
+= _NETTLE_CIPHER(serpent, SERPENT, 128);
+
+const struct nettle_cipher nettle_serpent192
+= _NETTLE_CIPHER(serpent, SERPENT, 192);
+
+const struct nettle_cipher nettle_serpent256
+= _NETTLE_CIPHER(serpent, SERPENT, 256);
diff --git a/serpent-set-key.c b/serpent-set-key.c
new file mode 100644 (file)
index 0000000..d03f50e
--- /dev/null
@@ -0,0 +1,351 @@
+/* serpent-set-key.c
+ *
+ * The serpent block cipher.
+ *
+ * For more details on this algorithm, see the Serpent website at
+ * http://www.cl.cam.ac.uk/~rja14/serpent.html
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2011  Niels Möller
+ * Copyright (C) 2010, 2011  Simon Josefsson
+ * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* This file is derived from cipher/serpent.c in Libgcrypt v1.4.6.
+   The adaption to Nettle was made by Simon Josefsson on 2010-12-07
+   with final touches on 2011-05-30.  Changes include replacing
+   libgcrypt with nettle in the license template, renaming
+   serpent_context to serpent_ctx, renaming u32 to uint32_t, removing
+   libgcrypt stubs and selftests, modifying entry function prototypes,
+   using FOR_BLOCKS to iterate through data in encrypt/decrypt, using
+   LE_READ_UINT32 and LE_WRITE_UINT32 to access data in
+   encrypt/decrypt, and running indent on the code. */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <limits.h>
+
+#include "serpent.h"
+
+#include "macros.h"
+#include "serpent-internal.h"
+
+/* Magic number, used during generating of the subkeys.  */
+#define PHI 0x9E3779B9
+
+/* 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.
+
+  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."  */
+
+/* FIXME: Except when used within the key schedule, the inputs are not
+   used after the substitution, and hence we could allow them to be
+   destroyed. Can this freedom be used to optimize the sboxes? */
+#define SBOX0(type, a, b, c, d, w, x, y, z)    \
+  do { \
+    type t02, t03, t05, t06, t07, t08, t09; \
+    type 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; \
+  } while (0)
+
+#define SBOX1(type, a, b, c, d, w, x, y, z)    \
+  do { \
+    type t02, t03, t04, t05, t06, t07, t08; \
+    type 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; \
+  } while (0)
+
+#define SBOX2(type, a, b, c, d, w, x, y, z) \
+  do {                                    \
+    type t02, t03, t05, t06, t07, t08; \
+    type 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; \
+  } while (0)
+
+#define SBOX3(type, a, b, c, d, w, x, y, z) \
+  do {                                         \
+    type t02, t03, t04, t05, t06, t07, t08; \
+    type 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; \
+  } while (0)
+
+#define SBOX4(type, a, b, c, d, w, x, y, z) \
+  do { \
+    type t02, t03, t04, t05, t06, t08, t09; \
+    type 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; \
+  } while (0)
+
+#define SBOX5(type, a, b, c, d, w, x, y, z) \
+  do { \
+    type t02, t03, t04, t05, t07, t08, t09; \
+    type 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; \
+  } while (0)
+
+#define SBOX6(type, a, b, c, d, w, x, y, z) \
+  do { \
+    type t02, t03, t04, t05, t07, t08, t09, t10;       \
+    type 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; \
+  } while (0)
+
+#define SBOX7(type, a, b, c, d, w, x, y, z) \
+  do { \
+    type t02, t03, t04, t05, t06, t08, t09, t10;       \
+    type 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; \
+  } while (0)
+
+/* Key schedule */
+/* Note: Increments k */
+#define KS_RECURRENCE(w, i, k)                                         \
+  do {                                                                 \
+    uint32_t _wn = (w)[(i)] ^ (w)[((i)+3)&7] ^ w[((i)+5)&7]            \
+      ^ w[((i)+7)&7] ^ PHI ^ (k)++;                                    \
+    ((w)[(i)] = ROL32(_wn, 11));                                       \
+  } while (0)
+
+/* Note: Increments k four times and keys once */
+#define KS(keys, s, w, i, k)                                   \
+  do {                                                         \
+    KS_RECURRENCE(w, (i), (k));                                        \
+    KS_RECURRENCE(w, (i)+1, (k));                              \
+    KS_RECURRENCE(w, (i)+2, (k));                              \
+    KS_RECURRENCE(w, (i)+3, (k));                              \
+    SBOX##s(uint32_t, w[(i)],w[(i)+1],w[(i)+2],w[(i)+3],               \
+           (*keys)[0],(*keys)[1],(*keys)[2],(*keys)[3]);       \
+    (keys)++;                                                  \
+  } while (0)
+
+/* Pad user key and convert to an array of 8 uint32_t. */
+static void
+serpent_key_pad (const uint8_t *key, unsigned int key_length,
+                uint32_t *w)
+{
+  unsigned int i;
+
+  assert (key_length <= SERPENT_MAX_KEY_SIZE);
+  
+  for (i = 0; key_length >= 4; key_length -=4, key += 4)
+    w[i++] = LE_READ_UINT32(key);
+
+  if (i < 8)
+    {
+      /* Key must be padded according to the Serpent specification.
+         "aabbcc" -> "aabbcc0100...00" -> 0x01ccbbaa. */
+      uint32_t pad = 0x01;
+      
+      while (key_length > 0)
+       pad = pad << 8 | key[--key_length];
+
+      w[i++] = pad;
+
+      while (i < 8)
+       w[i++] = 0;
+    }
+}
+
+/* Initialize CONTEXT with the key KEY of KEY_LENGTH bits.  */
+void
+serpent_set_key (struct serpent_ctx *ctx,
+                unsigned length, const uint8_t * key)
+{
+  uint32_t w[8];
+  uint32_t (*keys)[4];
+  unsigned k;
+  
+  serpent_key_pad (key, length, w);
+
+  /* Derive the 33 subkeys from KEY and store them in SUBKEYS. We do
+     the recurrence in the key schedule using W as a circular buffer
+     of just 8 uint32_t. */
+
+  /* FIXME: Would be better to invoke SBOX with scalar variables as
+     arguments, no arrays. To do that, unpack w into separate
+     variables, use temporary variables as the SBOX destination. */
+
+  keys = ctx->keys;
+  k = 0;
+  for (;;)
+    {
+      KS(keys, 3, w, 0, k);
+      if (k == 132)
+       break;
+      KS(keys, 2, w, 4, k);
+      KS(keys, 1, w, 0, k);
+      KS(keys, 0, w, 4, k);
+      KS(keys, 7, w, 0, k);
+      KS(keys, 6, w, 4, k);
+      KS(keys, 5, w, 0, k);
+      KS(keys, 4, w, 4, k);
+    }
+  assert (keys == ctx->keys + 33);
+}
diff --git a/serpent.h b/serpent.h
new file mode 100644 (file)
index 0000000..2ae1da7
--- /dev/null
+++ b/serpent.h
@@ -0,0 +1,81 @@
+/* serpent.h
+ *
+ * The serpent block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* Serpent is a 128-bit block cipher that accepts a key size of 256
+ * bits, designed by Ross Anderson, Eli Biham, and Lars Knudsen. See
+ * http://www.cl.cam.ac.uk/~rja14/serpent.html for details.
+ */
+
+#ifndef NETTLE_SERPENT_H_INCLUDED
+#define NETTLE_SERPENT_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define serpent_set_key nettle_serpent_set_key
+#define serpent_encrypt nettle_serpent_encrypt
+#define serpent_decrypt nettle_serpent_decrypt
+
+#define SERPENT_BLOCK_SIZE 16
+
+/* Other key lengths are possible, but the design of Serpent makes
+ * smaller key lengths quite pointless; they cheated with the AES
+ * requirements, using a 256-bit key length exclusively and just
+ * padding it out if the desired key length was less, so there really
+ * is no advantage to using key lengths less than 256 bits. */
+#define SERPENT_KEY_SIZE 32
+
+/* Allow keys of size 128 <= bits <= 256 */
+
+#define SERPENT_MIN_KEY_SIZE 16
+#define SERPENT_MAX_KEY_SIZE 32
+
+struct serpent_ctx
+{
+  uint32_t keys[33][4];  /* key schedule */
+};
+
+void
+serpent_set_key(struct serpent_ctx *ctx,
+                unsigned length, const uint8_t *key);
+
+void
+serpent_encrypt(const struct serpent_ctx *ctx,
+                unsigned length, uint8_t *dst,
+                const uint8_t *src);
+void
+serpent_decrypt(const struct serpent_ctx *ctx,
+                unsigned length, uint8_t *dst,
+                const uint8_t *src);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_SERPENT_H_INCLUDED */
diff --git a/sexp-format.c b/sexp-format.c
new file mode 100644 (file)
index 0000000..a3e6d92
--- /dev/null
@@ -0,0 +1,333 @@
+/* sexp-format.c
+ *
+ * Writing s-expressions.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sexp.h"
+#include "buffer.h"
+
+#include "bignum.h"
+
+static unsigned
+format_prefix(struct nettle_buffer *buffer,
+             unsigned length)
+{
+  unsigned digit = 1;
+  unsigned prefix_length = 1;
+  
+  for (;;)
+    {
+      unsigned next = digit * 10;
+      if (next > length)
+       break;
+
+      prefix_length++;
+      digit = next;
+    }
+
+  if (buffer)
+    {
+      for (; digit; length %= digit, digit /= 10)
+       if (!NETTLE_BUFFER_PUTC(buffer, '0' + length / digit))
+         return 0;
+      
+      if (!NETTLE_BUFFER_PUTC(buffer, ':'))
+       return 0;
+    }
+
+  return prefix_length + 1;
+}
+
+static unsigned
+format_string(struct nettle_buffer *buffer,
+             unsigned length, const uint8_t *s)
+{
+  unsigned prefix_length = format_prefix(buffer, length);
+  if (!prefix_length)
+    return 0;
+
+  if (buffer && !nettle_buffer_write(buffer, length, s))
+    return 0;
+
+  return prefix_length + length;
+}
+
+unsigned
+sexp_vformat(struct nettle_buffer *buffer, const char *format, va_list args)
+{
+  unsigned nesting = 0;
+  unsigned done = 0;
+
+  for (;;)
+    switch (*format++)
+      {
+      default:
+       {
+         const char *start = format - 1;
+         unsigned length = 1 + strcspn(format, "()% \t");
+         unsigned output_length = format_string(buffer, length, start);
+         if (!output_length)
+           return 0;
+         
+         done += output_length;
+         format = start + length;
+
+         break;
+       }
+      case ' ': case '\t':
+       break;
+       
+      case '\0':
+       assert(!nesting);
+           
+       return done;
+
+      case '(':
+       if (buffer && !NETTLE_BUFFER_PUTC(buffer, '('))
+         return 0;
+
+       done++;
+       nesting++;
+       break;
+
+      case ')':
+       assert (nesting);
+       if (buffer && !NETTLE_BUFFER_PUTC(buffer, ')'))
+         return 0;
+
+       done++;
+       nesting--;
+       break;
+
+      case '%':
+       {
+         int nul_flag = 0;
+
+         if (*format == '0')
+           {
+             format++;
+             nul_flag = 1;
+           }
+         switch (*format++)
+           {
+           default:
+             abort();
+
+           case '(':
+           case ')':
+             /* Allow unbalanced parenthesis */
+             if (buffer && !NETTLE_BUFFER_PUTC(buffer, format[-1]))
+               return 0;
+             done++;
+             break;
+             
+           case 's':
+             {
+               const char *s;
+               unsigned length;
+               unsigned output_length;
+               
+               if (nul_flag)
+                 {
+                   s = va_arg(args, const char *);
+                   length = strlen(s);
+                 }
+               else
+                 {
+                   length = va_arg(args, unsigned);
+                   s = va_arg(args, const char *);
+                 }
+               
+               output_length = format_string(buffer, length, s);
+               if (!output_length)
+                 return 0;
+
+               done += output_length;
+               break;
+             }
+           case 't':
+             {
+               const char *s;
+               unsigned length;
+               unsigned output_length;
+               
+               if (nul_flag)
+                 {
+                   s = va_arg(args, const char *);
+                   if (!s)
+                     break;
+                   
+                   length = strlen(s);
+                 }
+               else
+                 {
+                   length = va_arg(args, unsigned);
+                   s = va_arg(args, const char *);
+                   if (!s)
+                     break;
+                 }
+               
+               if (buffer && !NETTLE_BUFFER_PUTC(buffer, '['))
+                 return 0;
+               done++;
+               
+               output_length = format_string(buffer, length, s);
+             
+               if (!output_length)
+                 return 0;
+
+               done += output_length;
+               
+               if (buffer && !NETTLE_BUFFER_PUTC(buffer, ']'))
+                 return 0;
+               done++;
+               
+               break;
+             }
+             
+           case 'l':
+             {
+               const char *s;
+               unsigned length;
+               
+               if (nul_flag)
+                 {
+                   s = va_arg(args, const char *);
+                   length = strlen(s);
+                 }
+               else
+                 {
+                   length = va_arg(args, unsigned);
+                   s = va_arg(args, const char *);
+                 }
+
+               if (buffer && !nettle_buffer_write(buffer, length, s))
+                 return 0;
+             
+               done += length;
+               break;
+             }
+           case 'i':
+             {
+               uint32_t x = va_arg(args, uint32_t);
+               unsigned length;
+             
+               if (x < 0x80)
+                 length = 1;
+               else if (x < 0x8000L)
+                 length = 2;
+               else if (x < 0x800000L)
+                 length = 3;
+               else if (x < 0x80000000L)
+                 length = 4;
+               else
+                 length = 5;
+             
+               if (buffer && !(NETTLE_BUFFER_PUTC(buffer, '0' + length)
+                               && NETTLE_BUFFER_PUTC(buffer, ':')))
+                 return 0;
+
+               done += (2 + length);
+
+               if (buffer)
+                 switch(length)
+                   {
+                   case 5:
+                     /* Leading byte needed for the sign. */
+                     if (!NETTLE_BUFFER_PUTC(buffer, 0))
+                       return 0;
+                     /* Fall through */
+                   case 4:
+                     if (!NETTLE_BUFFER_PUTC(buffer, x >> 24))
+                       return 0;
+                     /* Fall through */
+                   case 3:
+                     if (!NETTLE_BUFFER_PUTC(buffer, (x >> 16) & 0xff))
+                       return 0;
+                     /* Fall through */
+                   case 2:
+                     if (!NETTLE_BUFFER_PUTC(buffer, (x >> 8) & 0xff))
+                       return 0;
+                     /* Fall through */
+                   case 1:
+                     if (!NETTLE_BUFFER_PUTC(buffer, x & 0xff))
+                       return 0;
+                     break;
+                   default:
+                     abort();
+                   }
+               break;
+             }
+           case 'b':
+             {
+               const MP_INT *n = va_arg(args, const MP_INT *);
+               unsigned length;
+               unsigned prefix_length;
+             
+               length = nettle_mpz_sizeinbase_256_s(n);
+               prefix_length = format_prefix(buffer, length);
+               if (!prefix_length)
+                 return 0;
+
+               done += prefix_length;
+
+               if (buffer)
+                 {
+                   uint8_t *space = nettle_buffer_space(buffer, length);
+                   if (!space)
+                     return 0;
+                 
+                   nettle_mpz_get_str_256(length, space, n);
+                 }
+
+               done += length;
+             
+               break;
+             }
+           }
+       }
+      }
+}
+
+unsigned
+sexp_format(struct nettle_buffer *buffer, const char *format, ...)
+{
+  va_list args;
+  unsigned done;
+  
+  va_start(args, format);
+  done = sexp_vformat(buffer, format, args);
+  va_end(args);
+
+  return done;
+}
diff --git a/sexp-transport-format.c b/sexp-transport-format.c
new file mode 100644 (file)
index 0000000..db4b193
--- /dev/null
@@ -0,0 +1,85 @@
+/* sexp-transport-format.c
+ *
+ * Writing s-expressions in transport format.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "sexp.h"
+
+#include "base64.h"
+#include "buffer.h"
+
+unsigned
+sexp_transport_vformat(struct nettle_buffer *buffer,
+                      const char *format, va_list args)
+{
+  unsigned start = 0;
+  unsigned length;
+  unsigned base64_length;
+
+  if (buffer)
+    {
+      if (!NETTLE_BUFFER_PUTC(buffer, '{'))
+       return 0;
+
+      start = buffer->size;
+    }
+  
+  length = sexp_vformat(buffer, format, args);
+
+  if (!length)
+    return 0;
+
+  base64_length = BASE64_ENCODE_RAW_LENGTH(length);
+
+  if (buffer)
+    {
+      if (!nettle_buffer_space(buffer, base64_length - length))
+       return 0;
+
+      base64_encode_raw(buffer->contents + start,
+                       length, buffer->contents + start);
+      
+      if (!NETTLE_BUFFER_PUTC(buffer, '}'))
+       return 0;
+    }
+  
+  return base64_length + 2;
+}
+
+unsigned
+sexp_transport_format(struct nettle_buffer *buffer,
+                     const char *format, ...)
+{
+  unsigned done;
+  va_list args;
+
+  va_start(args, format);
+  done = sexp_transport_vformat(buffer, format, args);
+  va_end(args);
+  
+  return done;
+}
diff --git a/sexp-transport.c b/sexp-transport.c
new file mode 100644 (file)
index 0000000..37865e7
--- /dev/null
@@ -0,0 +1,128 @@
+/* sexp-transport.c
+ *
+ * Parsing s-expressions in transport format.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <string.h>
+
+#include "sexp.h"
+
+#include "base64.h"
+
+/* NOTE: Decodes the input string in place */
+int
+sexp_transport_iterator_first(struct sexp_iterator *iterator,
+                             unsigned length, uint8_t *input)
+{
+  /* We first base64 decode any transport encoded sexp at the start of
+   * the input. */
+
+  unsigned in = 0;
+  unsigned out = 0;
+
+  while (in < length)
+    switch(input[in])
+      {
+      case ' ':  /* SPC, TAB, LF, CR */
+      case '\t':
+      case '\n':
+      case '\r':
+       in++;
+       break;
+         
+      case ';':  /* Comments */
+       while (++in < length && input[in] != '\n')
+         ;
+       break;
+         
+      case '{':
+       {
+         /* Found transport encoding */
+         struct base64_decode_ctx ctx;
+         unsigned coded_length;
+         unsigned end;
+
+         for (end = ++in; end < length && input[end] != '}'; end++)
+           ;
+
+         if (end == length)
+           return 0;
+           
+         base64_decode_init(&ctx);
+         coded_length = end - in;
+         
+         if (base64_decode_update(&ctx, &coded_length, input + out,
+                                  coded_length, input + in)
+             && base64_decode_final(&ctx))
+           {     
+             out += coded_length;
+             in = end + 1;
+           }
+         else
+           return 0;
+         
+         break;
+       }
+      default:
+       /* Expression isn't in transport encoding. Rest of the input
+        * should be in canonical encoding. */
+       goto transport_done;
+      }
+  
+ transport_done:
+
+  /* Here, we have two, possibly empty, input parts in canonical
+   * encoding:
+   *
+   * 0...out-1,  in...length -1
+   *
+   * If the input was already in canonical encoding, out = 0 and in =
+   * amount of leading space.
+   *
+   * If all input was in transport encoding, in == length.
+   */
+  if (!out)
+    {
+      input += in;
+      length -= in;
+    }
+  else if (in == length)
+    length = out;
+  else if (out == in)
+    /* Unusual case, nothing happens */
+    ;
+  else
+    {
+      /* Both parts non-empty */
+      assert(out < in);
+      memmove(input + out, input + in, length - in);
+      length -= (in - out);
+    }
+
+  return sexp_iterator_first(iterator, length, input);
+}
diff --git a/sexp.c b/sexp.c
new file mode 100644 (file)
index 0000000..0933e68
--- /dev/null
+++ b/sexp.c
@@ -0,0 +1,391 @@
+/* sexp.c
+ *
+ * Parsing s-expressions.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "sexp.h"
+
+#include "macros.h"
+#include "nettle-internal.h"
+
+/* Initializes the iterator, but one has to call next to get to the
+ * first element. */
+static void
+sexp_iterator_init(struct sexp_iterator *iterator,
+                  unsigned length, const uint8_t *input)
+{
+  iterator->length = length;
+  iterator->buffer = input;
+  iterator->pos = 0;
+  iterator->level = 0;
+  iterator->type = SEXP_END; /* Value doesn't matter */
+  iterator->display_length = 0;
+  iterator->display = NULL;
+  iterator->atom_length = 0;
+  iterator->atom = NULL;
+}
+
+#define EMPTY(i) ((i)->pos == (i)->length)
+#define NEXT(i) ((i)->buffer[(i)->pos++])
+
+static int
+sexp_iterator_simple(struct sexp_iterator *iterator,
+                    unsigned *size,
+                    const uint8_t **string)
+{
+  unsigned length = 0;
+  uint8_t c;
+  
+  if (EMPTY(iterator)) return 0;
+  c = NEXT(iterator);
+  if (EMPTY(iterator)) return 0;
+
+  if (c >= '1' && c <= '9')
+    do
+      {
+       length = length * 10 + (c - '0');
+       if (length > (iterator->length - iterator->pos))
+         return 0;
+
+       if (EMPTY(iterator)) return 0;
+       c = NEXT(iterator);
+      }
+    while (c >= '0' && c <= '9');
+
+  else if (c == '0')
+    /* There can be only one */
+    c = NEXT(iterator);
+  else 
+    return 0;
+
+  if (c != ':')
+    return 0;
+
+  *size = length;
+  *string = iterator->buffer + iterator->pos;
+  iterator->pos += length;
+
+  return 1;
+}
+
+/* All these functions return 1 on success, 0 on failure */
+
+/* Look at the current position in the data. Sets iterator->type, and
+ * ignores the old value. */
+
+static int
+sexp_iterator_parse(struct sexp_iterator *iterator)
+{
+  iterator->start = iterator->pos;
+  
+  if (EMPTY(iterator))
+    {
+      if (iterator->level)
+       return 0;
+      
+      iterator->type = SEXP_END;
+      return 1;
+    }
+  switch (iterator->buffer[iterator->pos])
+    {
+    case '(': /* A list */
+      iterator->type = SEXP_LIST;
+      return 1;
+
+    case ')':
+      if (!iterator->level)
+       return 0;
+      
+      iterator->pos++;
+      iterator->type = SEXP_END;      
+      return 1;
+      
+    case '[': /* Atom with display type */
+      iterator->pos++;
+      if (!sexp_iterator_simple(iterator,
+                               &iterator->display_length,
+                               &iterator->display))
+       return 0;
+      if (EMPTY(iterator) || NEXT(iterator) != ']')
+       return 0;
+
+      break;
+
+    default:
+      /* Must be either a decimal digit or a syntax error.
+       * Errors are detected by sexp_iterator_simple. */
+      iterator->display_length = 0;
+      iterator->display = NULL;
+
+      break;
+    }
+
+  iterator->type = SEXP_ATOM;
+      
+  return sexp_iterator_simple(iterator,
+                             &iterator->atom_length,
+                             &iterator->atom);
+}
+
+int
+sexp_iterator_first(struct sexp_iterator *iterator,
+                   unsigned length, const uint8_t *input)
+{
+  sexp_iterator_init(iterator, length, input);
+  return sexp_iterator_parse(iterator);
+}
+
+int
+sexp_iterator_next(struct sexp_iterator *iterator)
+{
+  switch (iterator->type)
+    {
+    case SEXP_END:
+      return 1;
+    case SEXP_LIST:
+      /* Skip this list */
+      return sexp_iterator_enter_list(iterator)
+       && sexp_iterator_exit_list(iterator);
+    case SEXP_ATOM:
+      /* iterator->pos should already point at the start of the next
+       * element. */
+      return sexp_iterator_parse(iterator);
+    }
+  /* If we get here, we have a bug. */
+  abort();
+}
+
+/* Current element must be a list. */
+int
+sexp_iterator_enter_list(struct sexp_iterator *iterator)
+{
+  if (iterator->type != SEXP_LIST)
+    return 0;
+
+  if (EMPTY(iterator) || NEXT(iterator) != '(')
+    /* Internal error */
+    abort();
+
+  iterator->level++;
+
+  return sexp_iterator_parse(iterator);
+}
+
+/* Skips the rest of the current list */
+int
+sexp_iterator_exit_list(struct sexp_iterator *iterator)
+{
+  if (!iterator->level)
+    return 0;
+
+  while(iterator->type != SEXP_END)
+    if (!sexp_iterator_next(iterator))
+      return 0;
+      
+  iterator->level--;
+
+  return sexp_iterator_parse(iterator);
+}
+
+#if 0
+/* What's a reasonable interface for this? */
+int
+sexp_iterator_exit_lists(struct sexp_iterator *iterator,
+                        unsigned level)
+{
+  assert(iterator->level >= level);
+
+  while (iterator->level > level)
+    if (!sexp_iterator_exit_list(iterator))
+      return 0;
+
+  return 1;
+}
+#endif
+
+const uint8_t *
+sexp_iterator_subexpr(struct sexp_iterator *iterator,
+                     unsigned *length)
+{
+  unsigned start = iterator->start;
+  if (!sexp_iterator_next(iterator))
+    return 0;
+
+  *length = iterator->start - start;
+  return iterator->buffer + start;
+}
+
+int
+sexp_iterator_get_uint32(struct sexp_iterator *iterator,
+                        uint32_t *x)
+{
+  if (iterator->type == SEXP_ATOM
+      && !iterator->display
+      && iterator->atom_length
+      && iterator->atom[0] < 0x80)
+    {
+      unsigned length = iterator->atom_length;
+      const uint8_t *p = iterator->atom;
+
+      /* Skip leading zeros. */
+      while(length && !*p)
+       {
+         length--; p++;
+       }
+
+      switch(length)
+       {
+       case 0:
+         *x = 0;
+         break;
+       case 1:
+         *x = p[0];
+         break;
+       case 2:
+         *x = READ_UINT16(p);
+         break;
+       case 3:
+         *x = READ_UINT24(p);
+         break;
+       case 4:
+         *x = READ_UINT32(p);
+         break;
+       default:
+         return 0;
+       }
+      return sexp_iterator_next(iterator);
+    }
+  return 0;
+}
+
+int
+sexp_iterator_check_type(struct sexp_iterator *iterator,
+                        const uint8_t *type)
+{
+  return (sexp_iterator_enter_list(iterator)
+         && iterator->type == SEXP_ATOM
+         && !iterator->display
+         && strlen(type) == iterator->atom_length
+         && !memcmp(type, iterator->atom, iterator->atom_length)
+         && sexp_iterator_next(iterator));
+}
+
+const uint8_t *
+sexp_iterator_check_types(struct sexp_iterator *iterator,
+                         unsigned ntypes,
+                         const uint8_t * const *types)
+{
+  if (sexp_iterator_enter_list(iterator)
+      && iterator->type == SEXP_ATOM
+      && !iterator->display)
+    {
+      unsigned i;
+      for (i = 0; i<ntypes; i++)
+       if (strlen(types[i]) == iterator->atom_length
+           && !memcmp(types[i], iterator->atom,
+                      iterator->atom_length))
+         return sexp_iterator_next(iterator) ? types[i] : NULL;
+    }
+  return NULL;
+}
+
+int
+sexp_iterator_assoc(struct sexp_iterator *iterator,
+                   unsigned nkeys,
+                   const uint8_t * const *keys,
+                   struct sexp_iterator *values)
+{
+  TMP_DECL(found, int, NETTLE_MAX_SEXP_ASSOC);
+  unsigned nfound;
+  unsigned i;
+
+  TMP_ALLOC(found, nkeys);
+  for (i = 0; i<nkeys; i++)
+    found[i] = 0;
+
+  nfound = 0;
+  
+  for (;;)
+    {
+      switch (iterator->type)
+       {
+       case SEXP_LIST:
+
+         if (!sexp_iterator_enter_list(iterator))
+           return 0;
+         
+         if (iterator->type == SEXP_ATOM
+             && !iterator->display)
+           {
+             /* Compare to the given keys */
+             for (i = 0; i<nkeys; i++)
+               {
+                 /* NOTE: The strlen could be put outside of the
+                  * loop */
+                 if (strlen(keys[i]) == iterator->atom_length
+                     && !memcmp(keys[i], iterator->atom,
+                                iterator->atom_length))
+                   {
+                     if (found[i])
+                       /* We don't allow duplicates */
+                       return 0;
+
+                     /* Advance to point to value */
+                     if (!sexp_iterator_next(iterator))
+                       return 0;
+
+                     found[i] = 1;
+                     nfound++;
+                     
+                     /* Record this position. */
+                     values[i] = *iterator;
+                     
+                     break;
+                   }
+               }
+           }
+         if (!sexp_iterator_exit_list(iterator))
+           return 0;
+         break;
+       case SEXP_ATOM:
+         /* Just ignore */
+         if (!sexp_iterator_next(iterator))
+           return 0;
+         break;
+         
+       case SEXP_END:
+         return sexp_iterator_exit_list(iterator)
+           && (nfound == nkeys);
+
+       default:
+         abort();
+       }
+    }
+}
diff --git a/sexp.h b/sexp.h
new file mode 100644 (file)
index 0000000..53a90a1
--- /dev/null
+++ b/sexp.h
@@ -0,0 +1,212 @@
+/* sexp.h
+ *
+ * Parsing s-expressions.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_SEXP_H_INCLUDED
+#define NETTLE_SEXP_H_INCLUDED
+
+#include <stdarg.h>
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define sexp_iterator_first nettle_sexp_iterator_first
+#define sexp_transport_iterator_first nettle_sexp_transport_iterator_first
+#define sexp_iterator_next nettle_sexp_iterator_next
+#define sexp_iterator_enter_list nettle_sexp_iterator_enter_list
+#define sexp_iterator_exit_list nettle_sexp_iterator_exit_list
+#define sexp_iterator_subexpr nettle_sexp_iterator_subexpr
+#define sexp_iterator_get_uint32 nettle_sexp_iterator_get_uint32
+#define sexp_iterator_check_type nettle_sexp_iterator_check_type
+#define sexp_iterator_check_types nettle_sexp_iterator_check_types
+#define sexp_iterator_assoc nettle_sexp_iterator_assoc
+#define sexp_format nettle_sexp_format
+#define sexp_vformat nettle_sexp_vformat
+#define sexp_transport_format nettle_sexp_transport_format
+#define sexp_transport_vformat nettle_sexp_transport_vformat
+#define sexp_token_chars nettle_sexp_token_chars
+
+enum sexp_type
+  { SEXP_ATOM, SEXP_LIST, SEXP_END };
+
+struct sexp_iterator
+{
+  unsigned length;
+  const uint8_t *buffer;
+
+  /* Points at the start of the current sub expression. */
+  unsigned start;
+  /* If type is SEXP_LIST, pos points at the start of the current
+   * element. Otherwise, it points at the end. */
+  unsigned pos;
+  unsigned level;
+
+  enum sexp_type type;
+  
+  unsigned display_length;
+  const uint8_t *display;
+
+  unsigned atom_length;
+  const uint8_t *atom;
+};
+
+
+/* All these functions return 1 on success, 0 on failure */
+
+/* Initializes the iterator. */
+int
+sexp_iterator_first(struct sexp_iterator *iterator,
+                   unsigned length, const uint8_t *input);
+
+/* NOTE: Decodes the input string in place */
+int
+sexp_transport_iterator_first(struct sexp_iterator *iterator,
+                             unsigned length, uint8_t *input);
+
+int
+sexp_iterator_next(struct sexp_iterator *iterator);
+
+/* Current element must be a list. */
+int
+sexp_iterator_enter_list(struct sexp_iterator *iterator);
+
+/* Skips the rest of the current list */
+int
+sexp_iterator_exit_list(struct sexp_iterator *iterator);
+
+#if 0
+/* Skips out of as many lists as necessary to get back to the given
+ * level. */
+int
+sexp_iterator_exit_lists(struct sexp_iterator *iterator,
+                        unsigned level);
+#endif
+
+/* Gets start and length of the current subexpression. Implies
+ * sexp_iterator_next. */
+const uint8_t *
+sexp_iterator_subexpr(struct sexp_iterator *iterator,
+                     unsigned *length);
+
+int
+sexp_iterator_get_uint32(struct sexp_iterator *iterator,
+                        uint32_t *x);
+
+\f
+/* Checks the type of the current expression, which should be a list
+ *
+ *  (<type> ...)
+ */
+int
+sexp_iterator_check_type(struct sexp_iterator *iterator,
+                        const uint8_t *type);
+
+const uint8_t *
+sexp_iterator_check_types(struct sexp_iterator *iterator,
+                         unsigned ntypes,
+                         const uint8_t * const *types);
+
+/* Current element must be a list. Looks up element of type
+ *
+ *   (key rest...)
+ *
+ * For a matching key, the corresponding iterator is initialized
+ * pointing at the start of REST.
+ *
+ * On success, exits the current list.
+ */
+int
+sexp_iterator_assoc(struct sexp_iterator *iterator,
+                   unsigned nkeys,
+                   const uint8_t * const *keys,
+                   struct sexp_iterator *values);
+
+\f
+/* Output functions. What is a reasonable API for this? It seems
+ * ugly to have to reimplement string streams. */
+
+/* Declared for real in buffer.h */
+struct nettle_buffer;
+
+/* Returns the number of output characters, or 0 on out of memory. If
+ * buffer == NULL, just compute length.
+ *
+ * Format strings can contained matched parentheses, tokens ("foo" in
+ * the format string is formatted as "3:foo"), whitespace (which
+ * separates tokens but is otherwise ignored) and the following
+ * formatting specifiers:
+ *
+ *   %s   String represented as unsigned length, const uint8_t *data.
+ *
+ *   %t   Optional display type, represented as
+ *        unsigned display_length, const uint8_t *display,
+ *        display == NULL means no display type.
+ *
+ *   %i   Non-negative small integer, uint32_t.
+ *
+ *   %b   Non-negative bignum, mpz_t.
+ *
+ *   %l   Literal string (no length added), typically a balanced
+ *        subexpression. Represented as unsigned length, const uint8_t
+ *        *data.
+ *
+ *   %(, %)  Allows insertion of unbalanced parenthesis.
+ *
+ * Modifiers:
+ *
+ *   %0   For %s, %t and %l, says that there's no length argument,
+ *        instead the string is NUL-terminated, and there's only one
+ *        const uint8_t * argument.
+ */
+unsigned
+sexp_format(struct nettle_buffer *buffer,
+           const char *format, ...);
+
+unsigned
+sexp_vformat(struct nettle_buffer *buffer,
+            const char *format, va_list args);
+
+unsigned
+sexp_transport_format(struct nettle_buffer *buffer,
+                     const char *format, ...);
+
+unsigned
+sexp_transport_vformat(struct nettle_buffer *buffer,
+                      const char *format, va_list args);
+
+/* Classification for advanced syntax. */
+extern const char
+sexp_token_chars[0x80];
+
+#define TOKEN_CHAR(c) ((c) < 0x80 && sexp_token_chars[(c)])
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_SEXP_H_INCLUDED */
diff --git a/sexp2bignum.c b/sexp2bignum.c
new file mode 100644 (file)
index 0000000..eca790e
--- /dev/null
@@ -0,0 +1,53 @@
+/* sexp2bignum.c
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "sexp.h"
+#include "bignum.h"
+
+int
+nettle_mpz_set_sexp(mpz_t x, unsigned limit, struct sexp_iterator *i)
+{
+  if (i->type == SEXP_ATOM
+      && i->atom_length
+      && !i->display)
+    {
+      /* Allow some extra here, for leading sign octets. */
+      if (limit && (8 * i->atom_length > (16 + limit)))
+       return 0;
+      
+      nettle_mpz_set_str_256_s(x, i->atom_length, i->atom);
+
+      /* FIXME: How to interpret a limit for negative numbers? */
+      if (limit && mpz_sizeinbase(x, 2) > limit)
+       return 0;
+      
+      return sexp_iterator_next(i);
+    }
+  else
+    return 0;
+}
diff --git a/sexp2dsa.c b/sexp2dsa.c
new file mode 100644 (file)
index 0000000..a3bc5e3
--- /dev/null
@@ -0,0 +1,120 @@
+/* sexp2dsa.c
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+
+#include "dsa.h"
+
+#include "bignum.h"
+#include "sexp.h"
+
+#define GET(x, l, v)                           \
+do {                                           \
+  if (!nettle_mpz_set_sexp((x), (l), (v))      \
+      || mpz_sgn(x) <= 0)                      \
+    return 0;                                  \
+} while(0)
+
+/* Iterator should point past the algorithm tag, e.g.
+ *
+ *   (public-key (dsa (p |xxxx|) ...)
+ *                    ^ here
+ */
+
+int
+dsa_keypair_from_sexp_alist(struct dsa_public_key *pub,
+                           struct dsa_private_key *priv,
+                           unsigned p_max_bits,
+                           unsigned q_bits,
+                           struct sexp_iterator *i)
+{
+  static const uint8_t * const names[5]
+    = { "p", "q", "g", "y", "x" };
+  struct sexp_iterator values[5];
+  unsigned nvalues = priv ? 5 : 4;
+  
+  if (!sexp_iterator_assoc(i, nvalues, names, values))
+    return 0;
+
+  if (priv)
+    GET(priv->x, q_bits, &values[4]);
+  
+  GET(pub->p, p_max_bits, &values[0]);
+  GET(pub->q, q_bits, &values[1]);
+  if (mpz_sizeinbase(pub->q, 2) != q_bits)
+    return 0;
+  GET(pub->g, p_max_bits, &values[2]);
+  GET(pub->y, p_max_bits, &values[3]);
+  
+  return 1;
+}
+
+int
+dsa_sha1_keypair_from_sexp(struct dsa_public_key *pub,
+                          struct dsa_private_key *priv,
+                          unsigned p_max_bits, 
+                          unsigned length, const uint8_t *expr)
+{
+  struct sexp_iterator i;
+
+  return sexp_iterator_first(&i, length, expr)
+    && sexp_iterator_check_type(&i, priv ? "private-key" : "public-key")
+    && sexp_iterator_check_type(&i, "dsa")
+    && dsa_keypair_from_sexp_alist(pub, priv, p_max_bits, DSA_SHA1_Q_BITS, &i);
+}
+
+int
+dsa_sha256_keypair_from_sexp(struct dsa_public_key *pub,
+                            struct dsa_private_key *priv,
+                            unsigned p_max_bits, 
+                            unsigned length, const uint8_t *expr)
+{
+  struct sexp_iterator i;
+
+  return sexp_iterator_first(&i, length, expr)
+    && sexp_iterator_check_type(&i, priv ? "private-key" : "public-key")
+    && sexp_iterator_check_type(&i, "dsa-sha256")
+    && dsa_keypair_from_sexp_alist(pub, priv, p_max_bits, DSA_SHA256_Q_BITS, &i);
+}
+
+int
+dsa_signature_from_sexp(struct dsa_signature *rs,
+                       struct sexp_iterator *i,
+                       unsigned q_bits)
+{
+  static const uint8_t * const names[2] = { "r", "s" };
+  struct sexp_iterator values[2];
+
+  if (!sexp_iterator_assoc(i, 2, names, values))
+    return 0;
+
+  GET(rs->r, q_bits, &values[0]);
+  GET(rs->s, q_bits, &values[1]);
+
+  return 1;
+}
diff --git a/sexp2rsa.c b/sexp2rsa.c
new file mode 100644 (file)
index 0000000..e3faf68
--- /dev/null
@@ -0,0 +1,108 @@
+/* sexp2rsa.c
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+
+#include "rsa.h"
+
+#include "bignum.h"
+#include "sexp.h"
+
+#define GET(x, l, v)                           \
+do {                                           \
+  if (!nettle_mpz_set_sexp((x), (l), (v))      \
+      || mpz_sgn(x) <= 0)                      \
+    return 0;                                  \
+} while(0)
+
+/* Iterator should point past the algorithm tag, e.g.
+ *
+ *   (public-key (rsa (n |xxxx|) (e |xxxx|))
+ *                    ^ here
+ */
+
+int
+rsa_keypair_from_sexp_alist(struct rsa_public_key *pub,
+                           struct rsa_private_key *priv,
+                           unsigned limit,
+                           struct sexp_iterator *i)
+{
+  static const uint8_t * const names[8]
+    = { "n", "e", "d", "p", "q", "a", "b", "c" };
+  struct sexp_iterator values[8];
+  unsigned nvalues = priv ? 8 : 2;
+  
+  if (!sexp_iterator_assoc(i, nvalues, names, values))
+    return 0;
+
+  if (priv)
+    {
+      GET(priv->d, limit, &values[2]);
+      GET(priv->p, limit, &values[3]);
+      GET(priv->q, limit, &values[4]);
+      GET(priv->a, limit, &values[5]);
+      GET(priv->b, limit, &values[6]);
+      GET(priv->c, limit, &values[7]);
+
+      if (!rsa_private_key_prepare(priv))
+       return 0;
+    }
+
+  if (pub)
+    {
+      GET(pub->n, limit, &values[0]);
+      GET(pub->e, limit, &values[1]);
+
+      if (!rsa_public_key_prepare(pub))
+       return 0;
+    }
+  
+  return 1;
+}
+
+int
+rsa_keypair_from_sexp(struct rsa_public_key *pub,
+                     struct rsa_private_key *priv,
+                     unsigned limit, 
+                     unsigned length, const uint8_t *expr)
+{
+  struct sexp_iterator i;
+  static const uint8_t * const names[3]
+    = { "rsa", "rsa-pkcs1", "rsa-pkcs1-sha1" };
+
+  if (!sexp_iterator_first(&i, length, expr))
+    return 0;
+  
+  if (!sexp_iterator_check_type(&i, priv ? "private-key" : "public-key"))
+    return 0;
+
+  if (!sexp_iterator_check_types(&i, 3, names))
+    return 0;
+
+  return rsa_keypair_from_sexp_alist(pub, priv, limit, &i);
+}
diff --git a/sha-example.c b/sha-example.c
new file mode 100644 (file)
index 0000000..8b3d505
--- /dev/null
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <nettle/sha.h>
+
+#define BUF_SIZE 1000
+
+static void
+display_hex(unsigned length, uint8_t *data)
+{
+  unsigned i;
+
+  for (i = 0; i<length; i++)
+    printf("%02x ", data[i]);
+
+  printf("\n");
+}
+
+int
+main(int argc, char **argv)
+{
+  struct sha1_ctx ctx;
+  uint8_t buffer[BUF_SIZE];
+  uint8_t digest[SHA1_DIGEST_SIZE];
+  
+  sha1_init(&ctx);
+  for (;;)
+  {
+    int done = fread(buffer, 1, sizeof(buffer), stdin);
+    sha1_update(&ctx, done, buffer);
+    if (done < sizeof(buffer))
+      break;
+  }
+  if (ferror(stdin))
+    return EXIT_FAILURE;
+
+  sha1_digest(&ctx, SHA1_DIGEST_SIZE, digest);
+
+  display_hex(SHA1_DIGEST_SIZE, digest);
+  return EXIT_SUCCESS;  
+}
diff --git a/sha.h b/sha.h
new file mode 100644 (file)
index 0000000..74beff3
--- /dev/null
+++ b/sha.h
@@ -0,0 +1,193 @@
+/* sha.h
+ *
+ * The sha1 and sha256 hash functions.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_SHA_H_INCLUDED
+#define NETTLE_SHA_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define sha1_init nettle_sha1_init
+#define sha1_update nettle_sha1_update
+#define sha1_digest nettle_sha1_digest
+#define sha224_init nettle_sha224_init
+#define sha224_digest nettle_sha224_digest
+#define sha256_init nettle_sha256_init
+#define sha256_update nettle_sha256_update
+#define sha256_digest nettle_sha256_digest
+#define sha384_init nettle_sha384_init
+#define sha384_digest nettle_sha384_digest
+#define sha512_init nettle_sha512_init
+#define sha512_update nettle_sha512_update
+#define sha512_digest nettle_sha512_digest
+
+/* SHA1 */
+
+#define SHA1_DIGEST_SIZE 20
+#define SHA1_DATA_SIZE 64
+
+/* Digest is kept internally as 5 32-bit words. */
+#define _SHA1_DIGEST_LENGTH 5
+
+struct sha1_ctx
+{
+  uint32_t state[_SHA1_DIGEST_LENGTH];    /* State variables */
+  uint32_t count_low, count_high;         /* 64-bit block count */
+  uint8_t block[SHA1_DATA_SIZE];          /* SHA1 data buffer */
+  unsigned int index;                     /* index into buffer */
+};
+
+void
+sha1_init(struct sha1_ctx *ctx);
+
+void
+sha1_update(struct sha1_ctx *ctx,
+           unsigned length,
+           const uint8_t *data);
+
+void
+sha1_digest(struct sha1_ctx *ctx,
+           unsigned length,
+           uint8_t *digest);
+
+/* Internal compression function. STATE points to 5 uint32_t words,
+   and DATA points to 64 bytes of input data, possibly unaligned. */
+void
+_nettle_sha1_compress(uint32_t *state, const uint8_t *data);
+
+/* SHA256 */
+
+#define SHA256_DIGEST_SIZE 32
+#define SHA256_DATA_SIZE 64
+
+/* Digest is kept internally as 8 32-bit words. */
+#define _SHA256_DIGEST_LENGTH 8
+
+struct sha256_ctx
+{
+  uint32_t state[_SHA256_DIGEST_LENGTH];    /* State variables */
+  uint32_t count_low, count_high;           /* 64-bit block count */
+  uint8_t block[SHA256_DATA_SIZE];          /* SHA256 data buffer */
+  unsigned int index;                       /* index into buffer */
+};
+
+void
+sha256_init(struct sha256_ctx *ctx);
+
+void
+sha256_update(struct sha256_ctx *ctx,
+             unsigned length,
+             const uint8_t *data);
+
+void
+sha256_digest(struct sha256_ctx *ctx,
+             unsigned length,
+             uint8_t *digest);
+
+/* Internal compression function. STATE points to 8 uint32_t words,
+   DATA points to 64 bytes of input data, possibly unaligned, and K
+   points to the table of constants. */
+void
+_nettle_sha256_compress(uint32_t *state, const uint8_t *data, const uint32_t *k);
+
+
+/* SHA224, a truncated SHA256 with different initial state. */
+
+#define SHA224_DIGEST_SIZE 28
+#define SHA224_DATA_SIZE SHA256_DATA_SIZE
+#define sha224_ctx sha256_ctx
+
+void
+sha224_init(struct sha256_ctx *ctx);
+
+#define sha224_update nettle_sha256_update
+
+void
+sha224_digest(struct sha256_ctx *ctx,
+             unsigned length,
+             uint8_t *digest);
+
+
+/* SHA512 */
+
+#define SHA512_DIGEST_SIZE 64
+#define SHA512_DATA_SIZE 128
+
+/* Digest is kept internally as 8 64-bit words. */
+#define _SHA512_DIGEST_LENGTH 8
+
+struct sha512_ctx
+{
+  uint64_t state[_SHA512_DIGEST_LENGTH];    /* State variables */
+  uint64_t count_low, count_high;           /* 128-bit block count */
+  uint8_t block[SHA512_DATA_SIZE];          /* SHA512 data buffer */
+  unsigned int index;                       /* index into buffer */
+};
+
+void
+sha512_init(struct sha512_ctx *ctx);
+
+void
+sha512_update(struct sha512_ctx *ctx,
+             unsigned length,
+             const uint8_t *data);
+
+void
+sha512_digest(struct sha512_ctx *ctx,
+             unsigned length,
+             uint8_t *digest);
+
+/* Internal compression function. STATE points to 8 uint64_t words,
+   DATA points to 128 bytes of input data, possibly unaligned, and K
+   points to the table of constants. */
+void
+_nettle_sha512_compress(uint64_t *state, const uint8_t *data, const uint64_t *k);
+
+
+/* SHA384, a truncated SHA512 with different initial state. */
+
+#define SHA384_DIGEST_SIZE 48
+#define SHA384_DATA_SIZE SHA512_DATA_SIZE
+#define sha384_ctx sha512_ctx
+
+void
+sha384_init(struct sha512_ctx *ctx);
+
+#define sha384_update nettle_sha512_update
+
+void
+sha384_digest(struct sha512_ctx *ctx,
+             unsigned length,
+             uint8_t *digest);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_SHA_H_INCLUDED */
diff --git a/sha1-compress.c b/sha1-compress.c
new file mode 100644 (file)
index 0000000..ed843bf
--- /dev/null
@@ -0,0 +1,249 @@
+/* sha1-compress.c
+ *
+ * The compression function of the sha1 hash function.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2004 Peter Gutmann, Andrew Kuchling, Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* Here's the first paragraph of Peter Gutmann's posting,
+ * <30ajo5$oe8@ccu2.auckland.ac.nz>: 
+ *
+ * The following is my SHA (FIPS 180) code updated to allow use of the "fixed"
+ * SHA, thanks to Jim Gillogly and an anonymous contributor for the information on
+ * what's changed in the new version.  The fix is a simple change which involves
+ * adding a single rotate in the initial expansion function.  It is unknown
+ * whether this is an optimal solution to the problem which was discovered in the
+ * SHA or whether it's simply a bandaid which fixes the problem with a minimum of
+ * effort (for example the reengineering of a great many Capstone chips).
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifndef SHA1_DEBUG
+# define SHA1_DEBUG 0
+#endif
+
+#if SHA1_DEBUG
+# include <stdio.h>
+# define DEBUG(i) \
+  fprintf(stderr, "%2d: %8x %8x %8x %8x %8x\n", i, A, B, C, D ,E)
+#else
+# define DEBUG(i)
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sha.h"
+
+#include "macros.h"
+
+/* A block, treated as a sequence of 32-bit words. */
+#define SHA1_DATA_LENGTH 16
+
+/* The SHA f()-functions.  The f1 and f3 functions can be optimized to
+   save one boolean operation each - thanks to Rich Schroeppel,
+   rcs@cs.arizona.edu for discovering this */
+
+/* FIXME: Can save a temporary in f3 by using ( (x & y) + (z & (x ^
+   y)) ), and then, in the round, compute one of the terms and add it
+   into the destination word before computing the second term. Credits
+   to George Spelvin for pointing this out. Unfortunately, gcc
+   doesn't seem to be smart enough to take advantage of this. */
+
+/* #define f1(x,y,z) ( ( x & y ) | ( ~x & z ) )            Rounds  0-19 */
+#define f1(x,y,z)   ( z ^ ( x & ( y ^ z ) ) )           /* Rounds  0-19 */
+#define f2(x,y,z)   ( x ^ y ^ z )                       /* Rounds 20-39 */
+/* #define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) Rounds 40-59 */
+#define f3(x,y,z)   ( ( x & y ) | ( z & ( x | y ) ) )   /* Rounds 40-59 */
+#define f4 f2
+
+/* The SHA Mysterious Constants */
+
+#define K1  0x5A827999L                                 /* Rounds  0-19 */
+#define K2  0x6ED9EBA1L                                 /* Rounds 20-39 */
+#define K3  0x8F1BBCDCL                                 /* Rounds 40-59 */
+#define K4  0xCA62C1D6L                                 /* Rounds 60-79 */
+
+/* 32-bit rotate left - kludged with shifts */
+
+#define ROTL(n,X)  ( ( (X) << (n) ) | ( (X) >> ( 32 - (n) ) ) )
+
+/* The initial expanding function.  The hash function is defined over an
+   80-word expanded input array W, where the first 16 are copies of the input
+   data, and the remaining 64 are defined by
+
+        W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
+
+   This implementation generates these values on the fly in a circular
+   buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
+   optimization.
+
+   The updated SHA changes the expanding function by adding a rotate of 1
+   bit.  Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
+   for this information */
+
+#define expand(W,i) ( W[ i & 15 ] = \
+                     ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
+                                W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
+
+
+/* The prototype SHA sub-round.  The fundamental sub-round is:
+
+        a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
+        b' = a;
+        c' = ROTL( 30, b );
+        d' = c;
+        e' = d;
+
+   but this is implemented by unrolling the loop 5 times and renaming the
+   variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
+   This code is then replicated 20 times for each of the 4 functions, using
+   the next 20 values from the W[] array each time */
+
+#define subRound(a, b, c, d, e, f, k, data) \
+    ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
+
+/* Perform the SHA transformation.  Note that this code, like MD5, seems to
+   break some optimizing compilers due to the complexity of the expressions
+   and the size of the basic block.  It may be necessary to split it into
+   sections, e.g. based on the four subrounds. */
+
+void
+_nettle_sha1_compress(uint32_t *state, const uint8_t *input)
+{
+  uint32_t data[SHA1_DATA_LENGTH];
+  uint32_t A, B, C, D, E;     /* Local vars */
+  int i;
+
+  for (i = 0; i < SHA1_DATA_LENGTH; i++, input+= 4)
+    {
+      data[i] = READ_UINT32(input);
+    }
+
+  /* Set up first buffer and local data buffer */
+  A = state[0];
+  B = state[1];
+  C = state[2];
+  D = state[3];
+  E = state[4];
+
+  DEBUG(-1);
+  /* Heavy mangling, in 4 sub-rounds of 20 interations each. */
+  subRound( A, B, C, D, E, f1, K1, data[ 0] ); DEBUG(0);
+  subRound( E, A, B, C, D, f1, K1, data[ 1] ); DEBUG(1);
+  subRound( D, E, A, B, C, f1, K1, data[ 2] );
+  subRound( C, D, E, A, B, f1, K1, data[ 3] );
+  subRound( B, C, D, E, A, f1, K1, data[ 4] );
+  subRound( A, B, C, D, E, f1, K1, data[ 5] );
+  subRound( E, A, B, C, D, f1, K1, data[ 6] );
+  subRound( D, E, A, B, C, f1, K1, data[ 7] );
+  subRound( C, D, E, A, B, f1, K1, data[ 8] );
+  subRound( B, C, D, E, A, f1, K1, data[ 9] );
+  subRound( A, B, C, D, E, f1, K1, data[10] );
+  subRound( E, A, B, C, D, f1, K1, data[11] );
+  subRound( D, E, A, B, C, f1, K1, data[12] );
+  subRound( C, D, E, A, B, f1, K1, data[13] );
+  subRound( B, C, D, E, A, f1, K1, data[14] );
+  subRound( A, B, C, D, E, f1, K1, data[15] ); DEBUG(15);
+  subRound( E, A, B, C, D, f1, K1, expand( data, 16 ) ); DEBUG(16);
+  subRound( D, E, A, B, C, f1, K1, expand( data, 17 ) ); DEBUG(17);
+  subRound( C, D, E, A, B, f1, K1, expand( data, 18 ) ); DEBUG(18);
+  subRound( B, C, D, E, A, f1, K1, expand( data, 19 ) ); DEBUG(19);
+
+  subRound( A, B, C, D, E, f2, K2, expand( data, 20 ) ); DEBUG(20);
+  subRound( E, A, B, C, D, f2, K2, expand( data, 21 ) ); DEBUG(21);
+  subRound( D, E, A, B, C, f2, K2, expand( data, 22 ) );
+  subRound( C, D, E, A, B, f2, K2, expand( data, 23 ) );
+  subRound( B, C, D, E, A, f2, K2, expand( data, 24 ) );
+  subRound( A, B, C, D, E, f2, K2, expand( data, 25 ) );
+  subRound( E, A, B, C, D, f2, K2, expand( data, 26 ) );
+  subRound( D, E, A, B, C, f2, K2, expand( data, 27 ) );
+  subRound( C, D, E, A, B, f2, K2, expand( data, 28 ) );
+  subRound( B, C, D, E, A, f2, K2, expand( data, 29 ) );
+  subRound( A, B, C, D, E, f2, K2, expand( data, 30 ) );
+  subRound( E, A, B, C, D, f2, K2, expand( data, 31 ) );
+  subRound( D, E, A, B, C, f2, K2, expand( data, 32 ) );
+  subRound( C, D, E, A, B, f2, K2, expand( data, 33 ) );
+  subRound( B, C, D, E, A, f2, K2, expand( data, 34 ) );
+  subRound( A, B, C, D, E, f2, K2, expand( data, 35 ) );
+  subRound( E, A, B, C, D, f2, K2, expand( data, 36 ) );
+  subRound( D, E, A, B, C, f2, K2, expand( data, 37 ) );
+  subRound( C, D, E, A, B, f2, K2, expand( data, 38 ) ); DEBUG(38);
+  subRound( B, C, D, E, A, f2, K2, expand( data, 39 ) ); DEBUG(39);
+
+  subRound( A, B, C, D, E, f3, K3, expand( data, 40 ) ); DEBUG(40);
+  subRound( E, A, B, C, D, f3, K3, expand( data, 41 ) ); DEBUG(41);
+  subRound( D, E, A, B, C, f3, K3, expand( data, 42 ) );
+  subRound( C, D, E, A, B, f3, K3, expand( data, 43 ) );
+  subRound( B, C, D, E, A, f3, K3, expand( data, 44 ) );
+  subRound( A, B, C, D, E, f3, K3, expand( data, 45 ) );
+  subRound( E, A, B, C, D, f3, K3, expand( data, 46 ) );
+  subRound( D, E, A, B, C, f3, K3, expand( data, 47 ) );
+  subRound( C, D, E, A, B, f3, K3, expand( data, 48 ) );
+  subRound( B, C, D, E, A, f3, K3, expand( data, 49 ) );
+  subRound( A, B, C, D, E, f3, K3, expand( data, 50 ) );
+  subRound( E, A, B, C, D, f3, K3, expand( data, 51 ) );
+  subRound( D, E, A, B, C, f3, K3, expand( data, 52 ) );
+  subRound( C, D, E, A, B, f3, K3, expand( data, 53 ) );
+  subRound( B, C, D, E, A, f3, K3, expand( data, 54 ) );
+  subRound( A, B, C, D, E, f3, K3, expand( data, 55 ) );
+  subRound( E, A, B, C, D, f3, K3, expand( data, 56 ) );
+  subRound( D, E, A, B, C, f3, K3, expand( data, 57 ) );
+  subRound( C, D, E, A, B, f3, K3, expand( data, 58 ) ); DEBUG(58);
+  subRound( B, C, D, E, A, f3, K3, expand( data, 59 ) ); DEBUG(59);
+
+  subRound( A, B, C, D, E, f4, K4, expand( data, 60 ) ); DEBUG(60);
+  subRound( E, A, B, C, D, f4, K4, expand( data, 61 ) ); DEBUG(61);
+  subRound( D, E, A, B, C, f4, K4, expand( data, 62 ) );
+  subRound( C, D, E, A, B, f4, K4, expand( data, 63 ) );
+  subRound( B, C, D, E, A, f4, K4, expand( data, 64 ) );
+  subRound( A, B, C, D, E, f4, K4, expand( data, 65 ) );
+  subRound( E, A, B, C, D, f4, K4, expand( data, 66 ) );
+  subRound( D, E, A, B, C, f4, K4, expand( data, 67 ) );
+  subRound( C, D, E, A, B, f4, K4, expand( data, 68 ) );
+  subRound( B, C, D, E, A, f4, K4, expand( data, 69 ) );
+  subRound( A, B, C, D, E, f4, K4, expand( data, 70 ) );
+  subRound( E, A, B, C, D, f4, K4, expand( data, 71 ) );
+  subRound( D, E, A, B, C, f4, K4, expand( data, 72 ) );
+  subRound( C, D, E, A, B, f4, K4, expand( data, 73 ) );
+  subRound( B, C, D, E, A, f4, K4, expand( data, 74 ) );
+  subRound( A, B, C, D, E, f4, K4, expand( data, 75 ) );
+  subRound( E, A, B, C, D, f4, K4, expand( data, 76 ) );
+  subRound( D, E, A, B, C, f4, K4, expand( data, 77 ) );
+  subRound( C, D, E, A, B, f4, K4, expand( data, 78 ) ); DEBUG(78);
+  subRound( B, C, D, E, A, f4, K4, expand( data, 79 ) ); DEBUG(79);
+
+  /* Build message digest */
+  state[0] += A;
+  state[1] += B;
+  state[2] += C;
+  state[3] += D;
+  state[4] += E;
+
+#if SHA1_DEBUG
+  fprintf(stderr, "99: %8x %8x %8x %8x %8x\n",
+         state[0], state[1], state[2], state[3], state[4]);
+#endif
+}
diff --git a/sha1-meta.c b/sha1-meta.c
new file mode 100644 (file)
index 0000000..d201da8
--- /dev/null
@@ -0,0 +1,32 @@
+/* sha1-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "sha.h"
+
+const struct nettle_hash nettle_sha1
+= _NETTLE_HASH(sha1, SHA1);
diff --git a/sha1.c b/sha1.c
new file mode 100644 (file)
index 0000000..41fa65c
--- /dev/null
+++ b/sha1.c
@@ -0,0 +1,106 @@
+/* sha1.c
+ *
+ * The sha1 hash function.
+ * Defined by http://www.itl.nist.gov/fipspubs/fip180-1.htm.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Peter Gutmann, Andrew Kuchling, Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* Here's the first paragraph of Peter Gutmann's posting,
+ * <30ajo5$oe8@ccu2.auckland.ac.nz>: 
+ *
+ * The following is my SHA (FIPS 180) code updated to allow use of the "fixed"
+ * SHA, thanks to Jim Gillogly and an anonymous contributor for the information on
+ * what's changed in the new version.  The fix is a simple change which involves
+ * adding a single rotate in the initial expansion function.  It is unknown
+ * whether this is an optimal solution to the problem which was discovered in the
+ * SHA or whether it's simply a bandaid which fixes the problem with a minimum of
+ * effort (for example the reengineering of a great many Capstone chips).
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sha.h"
+
+#include "macros.h"
+#include "nettle-write.h"
+
+/* Initialize the SHA values */
+void
+sha1_init(struct sha1_ctx *ctx)
+{
+  /* FIXME: Put the buffer last in the struct, and arrange so that we
+     can initialize with a single memcpy. */
+  static const uint32_t iv[_SHA1_DIGEST_LENGTH] = 
+    {
+      /* SHA initial values */
+      0x67452301L,
+      0xEFCDAB89L,
+      0x98BADCFEL,
+      0x10325476L,
+      0xC3D2E1F0L,
+    };
+
+  memcpy(ctx->state, iv, sizeof(ctx->state));
+  ctx->count_low = ctx->count_high = 0;
+  
+  /* Initialize buffer */
+  ctx->index = 0;
+}
+
+#define COMPRESS(ctx, data) (_nettle_sha1_compress((ctx)->state, data))
+
+void
+sha1_update(struct sha1_ctx *ctx,
+           unsigned length, const uint8_t *data)
+{
+  MD_UPDATE (ctx, length, data, COMPRESS, MD_INCR(ctx));
+}
+         
+void
+sha1_digest(struct sha1_ctx *ctx,
+           unsigned length,
+           uint8_t *digest)
+{
+  uint32_t high, low;
+
+  assert(length <= SHA1_DIGEST_SIZE);
+
+  MD_PAD(ctx, 8, COMPRESS);
+
+  /* There are 512 = 2^9 bits in one block */  
+  high = (ctx->count_high << 9) | (ctx->count_low >> 23);
+  low = (ctx->count_low << 9) | (ctx->index << 3);
+
+  /* append the 64 bit count */
+  WRITE_UINT32(ctx->block + (SHA1_DATA_SIZE - 8), high);
+  WRITE_UINT32(ctx->block + (SHA1_DATA_SIZE - 4), low);
+  _nettle_sha1_compress(ctx->state, ctx->block);
+
+  _nettle_write_be32(length, digest, ctx->state);
+  sha1_init(ctx);
+}
diff --git a/sha224-meta.c b/sha224-meta.c
new file mode 100644 (file)
index 0000000..a8bbafc
--- /dev/null
@@ -0,0 +1,32 @@
+/* sha224-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002, 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "sha.h"
+
+const struct nettle_hash nettle_sha224
+= _NETTLE_HASH(sha224, SHA224);
diff --git a/sha256-compress.c b/sha256-compress.c
new file mode 100644 (file)
index 0000000..ad03039
--- /dev/null
@@ -0,0 +1,168 @@
+/* sha256-compress.c
+ *
+ * The compression function of the sha256 hash function.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sha.h"
+
+#include "macros.h"
+
+/* A block, treated as a sequence of 32-bit words. */
+#define SHA256_DATA_LENGTH 16
+
+#define ROTR(n,x) ((x)>>(n) | ((x)<<(32-(n))))
+#define SHR(n,x) ((x)>>(n))
+
+/* The SHA256 functions. The Choice function is the same as the SHA1
+   function f1, and the majority function is the same as the SHA1 f3
+   function. They can be optimized to save one boolean operation each
+   - thanks to Rich Schroeppel, rcs@cs.arizona.edu for discovering
+   this */
+
+/* #define Choice(x,y,z) ( ( (x) & (y) ) | ( ~(x) & (z) ) ) */
+#define Choice(x,y,z)   ( (z) ^ ( (x) & ( (y) ^ (z) ) ) ) 
+/* #define Majority(x,y,z) ( ((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)) ) */
+#define Majority(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) )
+
+#define S0(x) (ROTR(2,(x)) ^ ROTR(13,(x)) ^ ROTR(22,(x))) 
+#define S1(x) (ROTR(6,(x)) ^ ROTR(11,(x)) ^ ROTR(25,(x)))
+
+#define s0(x) (ROTR(7,(x)) ^ ROTR(18,(x)) ^ SHR(3,(x)))
+#define s1(x) (ROTR(17,(x)) ^ ROTR(19,(x)) ^ SHR(10,(x)))
+
+/* The initial expanding function.  The hash function is defined over an
+   64-word expanded input array W, where the first 16 are copies of the input
+   data, and the remaining 64 are defined by
+
+        W[ t ] = s1(W[t-2]) + W[t-7] + s0(W[i-15]) + W[i-16]
+
+   This implementation generates these values on the fly in a circular
+   buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
+   optimization.
+*/
+
+#define EXPAND(W,i) \
+( W[(i) & 15 ] += (s1(W[((i)-2) & 15]) + W[((i)-7) & 15] + s0(W[((i)-15) & 15])) )
+
+/* The prototype SHA sub-round.  The fundamental sub-round is:
+
+        T1 = h + S1(e) + Choice(e,f,g) + K[t] + W[t]
+       T2 = S0(a) + Majority(a,b,c)
+       a' = T1+T2
+       b' = a
+       c' = b
+       d' = c
+       e' = d + T1
+       f' = e
+       g' = f
+       h' = g
+
+   but this is implemented by unrolling the loop 8 times and renaming
+   the variables
+   ( h, a, b, c, d, e, f, g ) = ( a, b, c, d, e, f, g, h ) each
+   iteration. */
+
+/* It's crucial that DATA is only used once, as that argument will
+ * have side effects. */
+#define ROUND(a,b,c,d,e,f,g,h,k,data) do {             \
+  uint32_t T = h + S1(e) + Choice(e,f,g) + k + data;   \
+  d += T;                                              \
+  h = T + S0(a) + Majority(a,b,c);                     \
+} while (0)
+
+void
+_nettle_sha256_compress(uint32_t *state, const uint8_t *input, const uint32_t *k)
+{
+  uint32_t data[SHA256_DATA_LENGTH];
+  uint32_t A, B, C, D, E, F, G, H;     /* Local vars */
+  unsigned i;
+  uint32_t *d;
+
+  for (i = 0; i < SHA256_DATA_LENGTH; i++, input+= 4)
+    {
+      data[i] = READ_UINT32(input);
+    }
+
+  /* Set up first buffer and local data buffer */
+  A = state[0];
+  B = state[1];
+  C = state[2];
+  D = state[3];
+  E = state[4];
+  F = state[5];
+  G = state[6];
+  H = state[7];
+  
+  /* Heavy mangling */
+  /* First 16 subrounds that act on the original data */
+
+  for (i = 0, d = data; i<16; i+=8, k += 8, d+= 8)
+    {
+      ROUND(A, B, C, D, E, F, G, H, k[0], d[0]);
+      ROUND(H, A, B, C, D, E, F, G, k[1], d[1]);
+      ROUND(G, H, A, B, C, D, E, F, k[2], d[2]);
+      ROUND(F, G, H, A, B, C, D, E, k[3], d[3]);
+      ROUND(E, F, G, H, A, B, C, D, k[4], d[4]);
+      ROUND(D, E, F, G, H, A, B, C, k[5], d[5]);
+      ROUND(C, D, E, F, G, H, A, B, k[6], d[6]);
+      ROUND(B, C, D, E, F, G, H, A, k[7], d[7]);
+    }
+  
+  for (; i<64; i += 16, k+= 16)
+    {
+      ROUND(A, B, C, D, E, F, G, H, k[ 0], EXPAND(data,  0));
+      ROUND(H, A, B, C, D, E, F, G, k[ 1], EXPAND(data,  1));
+      ROUND(G, H, A, B, C, D, E, F, k[ 2], EXPAND(data,  2));
+      ROUND(F, G, H, A, B, C, D, E, k[ 3], EXPAND(data,  3));
+      ROUND(E, F, G, H, A, B, C, D, k[ 4], EXPAND(data,  4));
+      ROUND(D, E, F, G, H, A, B, C, k[ 5], EXPAND(data,  5));
+      ROUND(C, D, E, F, G, H, A, B, k[ 6], EXPAND(data,  6));
+      ROUND(B, C, D, E, F, G, H, A, k[ 7], EXPAND(data,  7));
+      ROUND(A, B, C, D, E, F, G, H, k[ 8], EXPAND(data,  8));
+      ROUND(H, A, B, C, D, E, F, G, k[ 9], EXPAND(data,  9));
+      ROUND(G, H, A, B, C, D, E, F, k[10], EXPAND(data, 10));
+      ROUND(F, G, H, A, B, C, D, E, k[11], EXPAND(data, 11));
+      ROUND(E, F, G, H, A, B, C, D, k[12], EXPAND(data, 12));
+      ROUND(D, E, F, G, H, A, B, C, k[13], EXPAND(data, 13));
+      ROUND(C, D, E, F, G, H, A, B, k[14], EXPAND(data, 14));
+      ROUND(B, C, D, E, F, G, H, A, k[15], EXPAND(data, 15));
+    }
+
+  /* Update state */
+  state[0] += A;
+  state[1] += B;
+  state[2] += C;
+  state[3] += D;
+  state[4] += E;
+  state[5] += F;
+  state[6] += G;
+  state[7] += H;
+}
diff --git a/sha256-meta.c b/sha256-meta.c
new file mode 100644 (file)
index 0000000..c21c792
--- /dev/null
@@ -0,0 +1,32 @@
+/* sha256-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "sha.h"
+
+const struct nettle_hash nettle_sha256
+= _NETTLE_HASH(sha256, SHA256);
diff --git a/sha256.c b/sha256.c
new file mode 100644 (file)
index 0000000..c0500a2
--- /dev/null
+++ b/sha256.c
@@ -0,0 +1,157 @@
+/* sha256.c
+ *
+ * The sha256 hash function.
+ *
+ * See http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* Modelled after the sha1.c code by Peter Gutmann. */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sha.h"
+
+#include "macros.h"
+#include "nettle-write.h"
+
+/* Generated by the shadata program. */
+static const uint32_t
+K[64] =
+{
+  0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 
+  0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 
+  0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 
+  0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 
+  0xe49b69c1UL, 0xefbe4786UL, 0xfc19dc6UL, 0x240ca1ccUL, 
+  0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 
+  0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 
+  0xc6e00bf3UL, 0xd5a79147UL, 0x6ca6351UL, 0x14292967UL, 
+  0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 
+  0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 
+  0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 
+  0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 
+  0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 
+  0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, 
+  0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 
+  0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL, 
+};
+
+#define COMPRESS(ctx, data) (_nettle_sha256_compress((ctx)->state, (data), K))
+
+/* Initialize the SHA values */
+
+void
+sha256_init(struct sha256_ctx *ctx)
+{
+  /* Initial values, also generated by the shadata program. */
+  static const uint32_t H0[_SHA256_DIGEST_LENGTH] =
+  {
+    0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, 
+    0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL, 
+  };
+
+  memcpy(ctx->state, H0, sizeof(H0));
+
+  /* Initialize bit count */
+  ctx->count_low = ctx->count_high = 0;
+  
+  /* Initialize buffer */
+  ctx->index = 0;
+}
+
+void
+sha256_update(struct sha256_ctx *ctx,
+             unsigned length, const uint8_t *data)
+{
+  MD_UPDATE (ctx, length, data, COMPRESS, MD_INCR(ctx));
+}
+
+static void
+sha256_write_digest(struct sha256_ctx *ctx,
+                   unsigned length,
+                   uint8_t *digest)
+{
+  uint32_t high, low;
+
+  assert(length <= SHA256_DIGEST_SIZE);
+
+  MD_PAD(ctx, 8, COMPRESS);
+
+  /* There are 512 = 2^9 bits in one block */  
+  high = (ctx->count_high << 9) | (ctx->count_low >> 23);
+  low = (ctx->count_low << 9) | (ctx->index << 3);
+
+  /* This is slightly inefficient, as the numbers are converted to
+     big-endian format, and will be converted back by the compression
+     function. It's probably not worth the effort to fix this. */
+  WRITE_UINT32(ctx->block + (SHA256_DATA_SIZE - 8), high);
+  WRITE_UINT32(ctx->block + (SHA256_DATA_SIZE - 4), low);
+  COMPRESS(ctx, ctx->block);
+
+  _nettle_write_be32(length, digest, ctx->state);
+}
+
+void
+sha256_digest(struct sha256_ctx *ctx,
+             unsigned length,
+             uint8_t *digest)
+{
+  sha256_write_digest(ctx, length, digest);
+  sha256_init(ctx);
+}
+
+/* sha224 variant. FIXME: Move to seperate file? */
+
+void
+sha224_init(struct sha256_ctx *ctx)
+{
+  /* Initial values. I's unclear how they are chosen. */
+  static const uint32_t H0[_SHA256_DIGEST_LENGTH] =
+  {
+    0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
+    0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,
+  };
+
+  memcpy(ctx->state, H0, sizeof(H0));
+
+  /* Initialize bit count */
+  ctx->count_low = ctx->count_high = 0;
+  
+  /* Initialize buffer */
+  ctx->index = 0;
+}
+
+void
+sha224_digest(struct sha256_ctx *ctx,
+             unsigned length,
+             uint8_t *digest)
+{
+  sha256_write_digest(ctx, length, digest);
+  sha224_init(ctx);
+}
diff --git a/sha384-meta.c b/sha384-meta.c
new file mode 100644 (file)
index 0000000..0c02239
--- /dev/null
@@ -0,0 +1,32 @@
+/* sha384-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002, 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "sha.h"
+
+const struct nettle_hash nettle_sha384
+= _NETTLE_HASH(sha384, SHA384);
diff --git a/sha512-compress.c b/sha512-compress.c
new file mode 100644 (file)
index 0000000..f11226e
--- /dev/null
@@ -0,0 +1,164 @@
+/* sha512-compress.c
+ *
+ * The compression function of the sha512 hash function.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sha.h"
+
+#include "macros.h"
+
+/* A block, treated as a sequence of 64-bit words. */
+#define SHA512_DATA_LENGTH 16
+
+#define ROTR(n,x) ((x)>>(n) | ((x)<<(64-(n))))
+#define SHR(n,x) ((x)>>(n))
+
+/* The SHA512 functions. The Choice function is the same as the SHA1
+   function f1, and the majority function is the same as the SHA1 f3
+   function, and the same as for SHA256. */
+
+#define Choice(x,y,z)   ( (z) ^ ( (x) & ( (y) ^ (z) ) ) ) 
+#define Majority(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) )
+
+#define S0(x) (ROTR(28,(x)) ^ ROTR(34,(x)) ^ ROTR(39,(x))) 
+#define S1(x) (ROTR(14,(x)) ^ ROTR(18,(x)) ^ ROTR(41,(x)))
+
+#define s0(x) (ROTR(1,(x)) ^ ROTR(8,(x)) ^ SHR(7,(x)))
+#define s1(x) (ROTR(19,(x)) ^ ROTR(61,(x)) ^ SHR(6,(x)))
+
+/* The initial expanding function. The hash function is defined over
+   an 64-word expanded input array W, where the first 16 are copies of
+   the input data, and the remaining 64 are defined by
+
+        W[ t ] = s1(W[t-2]) + W[t-7] + s0(W[i-15]) + W[i-16]
+
+   This implementation generates these values on the fly in a circular
+   buffer.
+*/
+
+#define EXPAND(W,i) \
+( W[(i) & 15 ] += (s1(W[((i)-2) & 15]) + W[((i)-7) & 15] + s0(W[((i)-15) & 15])) )
+
+/* The prototype SHA sub-round.  The fundamental sub-round is:
+
+        T1 = h + S1(e) + Choice(e,f,g) + K[t] + W[t]
+       T2 = S0(a) + Majority(a,b,c)
+       a' = T1+T2
+       b' = a
+       c' = b
+       d' = c
+       e' = d + T1
+       f' = e
+       g' = f
+       h' = g
+
+   but this is implemented by unrolling the loop 8 times and renaming
+   the variables
+   ( h, a, b, c, d, e, f, g ) = ( a, b, c, d, e, f, g, h ) each
+   iteration. This code is then replicated 8, using the next 8 values
+   from the W[] array each time */
+
+/* It's crucial that DATA is only used once, as that argument will
+ * have side effects. */
+#define ROUND(a,b,c,d,e,f,g,h,k,data) do {             \
+  uint64_t T = h + S1(e) + Choice(e,f,g) + k + data;   \
+  d += T;                                              \
+  h = T + S0(a) + Majority(a,b,c);                     \
+} while (0)
+
+void
+_nettle_sha512_compress(uint64_t *state, const uint8_t *input, const uint64_t *k)
+{
+  uint64_t data[SHA512_DATA_LENGTH];
+  uint64_t A, B, C, D, E, F, G, H;     /* Local vars */
+  unsigned i;
+  uint64_t *d;
+
+  for (i = 0; i < SHA512_DATA_LENGTH; i++, input += 8)
+    {
+      data[i] = READ_UINT64(input);
+    }
+
+  /* Set up first buffer and local data buffer */
+  A = state[0];
+  B = state[1];
+  C = state[2];
+  D = state[3];
+  E = state[4];
+  F = state[5];
+  G = state[6];
+  H = state[7];
+  
+  /* Heavy mangling */
+  /* First 16 subrounds that act on the original data */
+
+  for (i = 0, d = data; i<16; i+=8, k += 8, d+= 8)
+    {
+      ROUND(A, B, C, D, E, F, G, H, k[0], d[0]);
+      ROUND(H, A, B, C, D, E, F, G, k[1], d[1]);
+      ROUND(G, H, A, B, C, D, E, F, k[2], d[2]);
+      ROUND(F, G, H, A, B, C, D, E, k[3], d[3]);
+      ROUND(E, F, G, H, A, B, C, D, k[4], d[4]);
+      ROUND(D, E, F, G, H, A, B, C, k[5], d[5]);
+      ROUND(C, D, E, F, G, H, A, B, k[6], d[6]);
+      ROUND(B, C, D, E, F, G, H, A, k[7], d[7]);
+    }
+  
+  for (; i<80; i += 16, k+= 16)
+    {
+      ROUND(A, B, C, D, E, F, G, H, k[ 0], EXPAND(data,  0));
+      ROUND(H, A, B, C, D, E, F, G, k[ 1], EXPAND(data,  1));
+      ROUND(G, H, A, B, C, D, E, F, k[ 2], EXPAND(data,  2));
+      ROUND(F, G, H, A, B, C, D, E, k[ 3], EXPAND(data,  3));
+      ROUND(E, F, G, H, A, B, C, D, k[ 4], EXPAND(data,  4));
+      ROUND(D, E, F, G, H, A, B, C, k[ 5], EXPAND(data,  5));
+      ROUND(C, D, E, F, G, H, A, B, k[ 6], EXPAND(data,  6));
+      ROUND(B, C, D, E, F, G, H, A, k[ 7], EXPAND(data,  7));
+      ROUND(A, B, C, D, E, F, G, H, k[ 8], EXPAND(data,  8));
+      ROUND(H, A, B, C, D, E, F, G, k[ 9], EXPAND(data,  9));
+      ROUND(G, H, A, B, C, D, E, F, k[10], EXPAND(data, 10));
+      ROUND(F, G, H, A, B, C, D, E, k[11], EXPAND(data, 11));
+      ROUND(E, F, G, H, A, B, C, D, k[12], EXPAND(data, 12));
+      ROUND(D, E, F, G, H, A, B, C, k[13], EXPAND(data, 13));
+      ROUND(C, D, E, F, G, H, A, B, k[14], EXPAND(data, 14));
+      ROUND(B, C, D, E, F, G, H, A, k[15], EXPAND(data, 15));
+    }
+
+  /* Update state */
+  state[0] += A;
+  state[1] += B;
+  state[2] += C;
+  state[3] += D;
+  state[4] += E;
+  state[5] += F;
+  state[6] += G;
+  state[7] += H;
+}
diff --git a/sha512-meta.c b/sha512-meta.c
new file mode 100644 (file)
index 0000000..d9ba03e
--- /dev/null
@@ -0,0 +1,32 @@
+/* sha512-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002, 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "sha.h"
+
+const struct nettle_hash nettle_sha512
+= _NETTLE_HASH(sha512, SHA512);
diff --git a/sha512.c b/sha512.c
new file mode 100644 (file)
index 0000000..eb7a29e
--- /dev/null
+++ b/sha512.c
@@ -0,0 +1,239 @@
+/* sha512.c
+ *
+ * The sha512 hash function FIXME: Add the SHA384 variant.
+ *
+ * See http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2010 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/* Modelled after the sha1.c code by Peter Gutmann. */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sha.h"
+
+#include "macros.h"
+
+/* Generated by the gp script
+
+     {
+       print("obase=16");
+       for (i = 1,80,
+         root = prime(i)^(1/3);
+         fraction = root - floor(root);
+         print(floor(2^64 * fraction));
+       );
+       quit();
+     }
+
+   piped through
+
+     |grep -v '^[' | bc \
+       |awk '{printf("0x%sULL,%s", $1, NR%3 == 0 ? "\n" : "");}'
+
+   to convert it to hex.
+*/
+
+static const uint64_t
+K[80] =
+{
+  0x428A2F98D728AE22ULL,0x7137449123EF65CDULL,
+  0xB5C0FBCFEC4D3B2FULL,0xE9B5DBA58189DBBCULL,
+  0x3956C25BF348B538ULL,0x59F111F1B605D019ULL,
+  0x923F82A4AF194F9BULL,0xAB1C5ED5DA6D8118ULL,
+  0xD807AA98A3030242ULL,0x12835B0145706FBEULL,
+  0x243185BE4EE4B28CULL,0x550C7DC3D5FFB4E2ULL,
+  0x72BE5D74F27B896FULL,0x80DEB1FE3B1696B1ULL,
+  0x9BDC06A725C71235ULL,0xC19BF174CF692694ULL,
+  0xE49B69C19EF14AD2ULL,0xEFBE4786384F25E3ULL,
+  0xFC19DC68B8CD5B5ULL,0x240CA1CC77AC9C65ULL,
+  0x2DE92C6F592B0275ULL,0x4A7484AA6EA6E483ULL,
+  0x5CB0A9DCBD41FBD4ULL,0x76F988DA831153B5ULL,
+  0x983E5152EE66DFABULL,0xA831C66D2DB43210ULL,
+  0xB00327C898FB213FULL,0xBF597FC7BEEF0EE4ULL,
+  0xC6E00BF33DA88FC2ULL,0xD5A79147930AA725ULL,
+  0x6CA6351E003826FULL,0x142929670A0E6E70ULL,
+  0x27B70A8546D22FFCULL,0x2E1B21385C26C926ULL,
+  0x4D2C6DFC5AC42AEDULL,0x53380D139D95B3DFULL,
+  0x650A73548BAF63DEULL,0x766A0ABB3C77B2A8ULL,
+  0x81C2C92E47EDAEE6ULL,0x92722C851482353BULL,
+  0xA2BFE8A14CF10364ULL,0xA81A664BBC423001ULL,
+  0xC24B8B70D0F89791ULL,0xC76C51A30654BE30ULL,
+  0xD192E819D6EF5218ULL,0xD69906245565A910ULL,
+  0xF40E35855771202AULL,0x106AA07032BBD1B8ULL,
+  0x19A4C116B8D2D0C8ULL,0x1E376C085141AB53ULL,
+  0x2748774CDF8EEB99ULL,0x34B0BCB5E19B48A8ULL,
+  0x391C0CB3C5C95A63ULL,0x4ED8AA4AE3418ACBULL,
+  0x5B9CCA4F7763E373ULL,0x682E6FF3D6B2B8A3ULL,
+  0x748F82EE5DEFB2FCULL,0x78A5636F43172F60ULL,
+  0x84C87814A1F0AB72ULL,0x8CC702081A6439ECULL,
+  0x90BEFFFA23631E28ULL,0xA4506CEBDE82BDE9ULL,
+  0xBEF9A3F7B2C67915ULL,0xC67178F2E372532BULL,
+  0xCA273ECEEA26619CULL,0xD186B8C721C0C207ULL,
+  0xEADA7DD6CDE0EB1EULL,0xF57D4F7FEE6ED178ULL,
+  0x6F067AA72176FBAULL,0xA637DC5A2C898A6ULL,
+  0x113F9804BEF90DAEULL,0x1B710B35131C471BULL,
+  0x28DB77F523047D84ULL,0x32CAAB7B40C72493ULL,
+  0x3C9EBE0A15C9BEBCULL,0x431D67C49C100D4CULL,
+  0x4CC5D4BECB3E42B6ULL,0x597F299CFC657E2AULL,
+  0x5FCB6FAB3AD6FAECULL,0x6C44198C4A475817ULL,
+};
+
+#define COMPRESS(ctx, data) (_nettle_sha512_compress((ctx)->state, (data), K))
+
+void
+sha512_init(struct sha512_ctx *ctx)
+{
+  /* Initial values, generated by the gp script
+       {
+         for (i = 1,8,
+          root = prime(i)^(1/2);
+          fraction = root - floor(root);
+          print(floor(2^64 * fraction));
+        );
+       }
+. */
+  static const uint64_t H0[_SHA512_DIGEST_LENGTH] =
+  {
+    0x6A09E667F3BCC908ULL,0xBB67AE8584CAA73BULL,
+    0x3C6EF372FE94F82BULL,0xA54FF53A5F1D36F1ULL,
+    0x510E527FADE682D1ULL,0x9B05688C2B3E6C1FULL,
+    0x1F83D9ABFB41BD6BULL,0x5BE0CD19137E2179ULL,
+  };
+
+  memcpy(ctx->state, H0, sizeof(H0));
+
+  /* Initialize bit count */
+  ctx->count_low = ctx->count_high = 0;
+  
+  /* Initialize buffer */
+  ctx->index = 0;
+}
+
+void
+sha512_update(struct sha512_ctx *ctx,
+             unsigned length, const uint8_t *data)
+{
+  MD_UPDATE (ctx, length, data, COMPRESS, MD_INCR(ctx));
+}
+
+static void
+sha512_write_digest(struct sha512_ctx *ctx,
+                   unsigned length,
+                   uint8_t *digest)
+{
+  uint64_t high, low;
+
+  unsigned i;
+  unsigned words;
+  unsigned leftover;
+
+  assert(length <= SHA512_DIGEST_SIZE);
+
+  MD_PAD(ctx, 16, COMPRESS);
+
+  /* There are 1024 = 2^10 bits in one block */  
+  high = (ctx->count_high << 10) | (ctx->count_low >> 54);
+  low = (ctx->count_low << 10) | (ctx->index << 3);
+
+  /* This is slightly inefficient, as the numbers are converted to
+     big-endian format, and will be converted back by the compression
+     function. It's probably not worth the effort to fix this. */
+  WRITE_UINT64(ctx->block + (SHA512_DATA_SIZE - 16), high);
+  WRITE_UINT64(ctx->block + (SHA512_DATA_SIZE - 8), low);
+  COMPRESS(ctx, ctx->block);
+
+  words = length / 8;
+  leftover = length % 8;
+
+  for (i = 0; i < words; i++, digest += 8)
+    WRITE_UINT64(digest, ctx->state[i]);
+
+  if (leftover)
+    {
+      /* Truncate to the right size */
+      uint64_t word = ctx->state[i] >> (8*(8 - leftover));
+
+      do {
+       digest[--leftover] = word & 0xff;
+       word >>= 8;
+      } while (leftover);
+    }
+}
+
+void
+sha512_digest(struct sha512_ctx *ctx,
+             unsigned length,
+             uint8_t *digest)
+{
+  assert(length <= SHA512_DIGEST_SIZE);
+
+  sha512_write_digest(ctx, length, digest);
+  sha512_init(ctx);
+}
+
+/* sha384 variant. FIXME: Move to separate file? */
+void
+sha384_init(struct sha512_ctx *ctx)
+{
+  /* Initial values, generated by the gp script
+       {
+         for (i = 9,16,
+          root = prime(i)^(1/2);
+          fraction = root - floor(root);
+          print(floor(2^64 * fraction));
+        );
+       }
+. */
+  static const uint64_t H0[_SHA512_DIGEST_LENGTH] =
+  {
+    0xCBBB9D5DC1059ED8ULL, 0x629A292A367CD507ULL,
+    0x9159015A3070DD17ULL, 0x152FECD8F70E5939ULL,
+    0x67332667FFC00B31ULL, 0x8EB44A8768581511ULL,
+    0xDB0C2E0D64F98FA7ULL, 0x47B5481DBEFA4FA4ULL,
+  };
+
+  memcpy(ctx->state, H0, sizeof(H0));
+
+  /* Initialize bit count */
+  ctx->count_low = ctx->count_high = 0;
+  
+  /* Initialize buffer */
+  ctx->index = 0;
+}
+
+void
+sha384_digest(struct sha512_ctx *ctx,
+             unsigned length,
+             uint8_t *digest)
+{
+  assert(length <= SHA384_DIGEST_SIZE);
+
+  sha512_write_digest(ctx, length, digest);
+  sha384_init(ctx);
+}
diff --git a/shadata.c b/shadata.c
new file mode 100644 (file)
index 0000000..3275f0c
--- /dev/null
+++ b/shadata.c
@@ -0,0 +1,50 @@
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <math.h>
+#include <stdio.h>
+
+static const unsigned primes[64] =
+{
+  2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 
+  31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 
+  73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 
+  127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 
+  179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 
+  233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 
+  283, 293, 307, 311
+};
+
+int main(int argc UNUSED, char **argv UNUSED)
+{
+  int i;
+  static const double third = 1.0/3;
+
+  printf("SHA-256 constants: \n");
+  for (i = 0; i < 64; )
+    {
+      double root = pow(primes[i++], third);
+      double fraction = root - floor(root);
+      double value = floor(ldexp(fraction, 32));
+
+      printf("0x%lxUL, ", (unsigned long) value);
+      if (!(i % 4))
+       printf("\n");
+    }
+
+  printf("\nSHA-256 initial values: \n");
+
+  for (i = 0; i < 8; )
+    {
+      double root = pow(primes[i++], 0.5);
+      double fraction = root - (floor(root));
+      double value = floor(ldexp(fraction, 32));
+
+      printf("0x%lxUL, ", (unsigned long) value);
+      if (!(i % 4))
+       printf("\n");
+    }
+  
+  return 0;
+}
diff --git a/sparc32/aes-decrypt-internal.asm b/sparc32/aes-decrypt-internal.asm
new file mode 100644 (file)
index 0000000..0d432e0
--- /dev/null
@@ -0,0 +1,132 @@
+C -*- mode: asm; asm-comment-char: ?C; -*-  
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2002, 2005 Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+include_src(<sparc32/aes.m4>)
+
+C      Arguments
+define(<CTX>,  <%i0>)
+define(<T>,    <%i1>)
+define(<LENGTH>,<%i2>)
+define(<DST>,  <%i3>)
+define(<SRC>,  <%i4>)
+
+C      AES state, two copies for unrolling
+
+define(<W0>,   <%l0>)
+define(<W1>,   <%l1>)
+define(<W2>,   <%l2>)
+define(<W3>,   <%l3>)
+
+define(<X0>,   <%l4>)
+define(<X1>,   <%l5>)
+define(<X2>,   <%l6>)
+define(<X3>,   <%l7>)
+
+C      %o0-%03 are used for loop invariants T0-T3
+define(<KEY>,  <%o4>)
+define(<ROUND>, <%o5>)
+
+C %g1, %g2, %g3 are TMP1, TMP2 and TMP3
+
+C The sparc32 stack frame looks like
+C
+C %fp -   4: OS-dependent link field
+C %fp -   8: OS-dependent link field
+C %fp - 104: OS register save area. 
+define(<FRAME_SIZE>, 104)
+
+       .file "aes-decrypt-internal.asm"
+
+       C _aes_decrypt(struct aes_context *ctx, 
+       C              const struct aes_table *T,
+       C              unsigned length, uint8_t *dst,
+       C              uint8_t *src)
+
+       .section        ".text"
+       .align 16
+       .proc   020
+       
+PROLOGUE(_nettle_aes_decrypt)
+
+       save    %sp, -FRAME_SIZE, %sp
+       cmp     LENGTH, 0
+       be      .Lend
+
+       C       Loop invariants
+       add     T, AES_TABLE0, T0
+       add     T, AES_TABLE1, T1
+       add     T, AES_TABLE2, T2
+       add     T, AES_TABLE3, T3
+
+.Lblock_loop:
+       C  Read src, and add initial subkey
+       add     CTX, AES_KEYS, KEY
+       AES_LOAD(0, SRC, KEY, W0)
+       AES_LOAD(1, SRC, KEY, W1)
+       AES_LOAD(2, SRC, KEY, W2)
+       AES_LOAD(3, SRC, KEY, W3)
+
+       C       Must be even, and includes the final round
+       ld      [AES_NROUNDS + CTX], ROUND
+       add     SRC, 16, SRC
+       add     KEY, 16, KEY
+
+       srl     ROUND, 1, ROUND
+       C       Last two rounds handled specially
+       sub     ROUND, 1, ROUND
+.Lround_loop:
+       C The AES_ROUND macro uses T0,... T3
+       C       Transform W -> X
+       AES_ROUND(0, W0, W3, W2, W1, KEY, X0)
+       AES_ROUND(1, W1, W0, W3, W2, KEY, X1)
+       AES_ROUND(2, W2, W1, W0, W3, KEY, X2)
+       AES_ROUND(3, W3, W2, W1, W0, KEY, X3)
+
+       C       Transform X -> W
+       AES_ROUND(4, X0, X3, X2, X1, KEY, W0)
+       AES_ROUND(5, X1, X0, X3, X2, KEY, W1)
+       AES_ROUND(6, X2, X1, X0, X3, KEY, W2)
+       AES_ROUND(7, X3, X2, X1, X0, KEY, W3)
+
+       subcc   ROUND, 1, ROUND
+       bne     .Lround_loop
+       add     KEY, 32, KEY
+
+       C       Penultimate round
+       AES_ROUND(0, W0, W3, W2, W1, KEY, X0)
+       AES_ROUND(1, W1, W0, W3, W2, KEY, X1)
+       AES_ROUND(2, W2, W1, W0, W3, KEY, X2)
+       AES_ROUND(3, W3, W2, W1, W0, KEY, X3)
+
+       add     KEY, 16, KEY
+       C       Final round
+       AES_FINAL_ROUND(0, T, X0, X3, X2, X1, KEY, DST)
+       AES_FINAL_ROUND(1, T, X1, X0, X3, X2, KEY, DST)
+       AES_FINAL_ROUND(2, T, X2, X1, X0, X3, KEY, DST)
+       AES_FINAL_ROUND(3, T, X3, X2, X1, X0, KEY, DST)
+
+       subcc   LENGTH, 16, LENGTH
+       bne     .Lblock_loop
+       add     DST, 16, DST
+
+.Lend:
+       ret
+       restore
+EPILOGUE(_nettle_aes_decrypt)
diff --git a/sparc32/aes-encrypt-internal.asm b/sparc32/aes-encrypt-internal.asm
new file mode 100644 (file)
index 0000000..e013822
--- /dev/null
@@ -0,0 +1,156 @@
+C -*- mode: asm; asm-comment-char: ?C; -*-  
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2002, 2005 Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+include_src(<sparc32/aes.m4>)
+
+C      Arguments
+define(<CTX>,  <%i0>)
+define(<T>,    <%i1>)
+define(<LENGTH>,<%i2>)
+define(<DST>,  <%i3>)
+define(<SRC>,  <%i4>)
+
+C      AES state, two copies for unrolling
+
+define(<W0>,   <%l0>)
+define(<W1>,   <%l1>)
+define(<W2>,   <%l2>)
+define(<W3>,   <%l3>)
+
+define(<X0>,   <%l4>)
+define(<X1>,   <%l5>)
+define(<X2>,   <%l6>)
+define(<X3>,   <%l7>)
+
+C      %o0-%03 are used for loop invariants T0-T3
+define(<KEY>,  <%o4>)
+define(<ROUND>, <%o5>)
+
+C %g1, %g2, %g3 are TMP1, TMP2 and TMP3
+
+C I'm still slightly confused by the frame layout, specified in
+C "SYSTEM V APPLICATION BINARY INTERFACE SPARC Processor Supplement".
+C However, Sun's cc generates a 104 byte stack frame for a function
+C with no local variables, so that should be good enough for us too.
+
+C The sparc32 stack frame looks like
+C
+C %fp -   4: OS-dependent link field
+C %fp -   8: OS-dependent link field
+C %fp - 104: OS register save area 
+define(<FRAME_SIZE>, 104)
+
+       .file "aes-encrypt-internal.asm"
+
+       C _aes_encrypt(struct aes_context *ctx, 
+       C              const struct aes_table *T,
+       C              unsigned length, uint8_t *dst,
+       C              uint8_t *src)
+
+       .section        ".text"
+       .align 16
+       .proc   020
+       
+PROLOGUE(_nettle_aes_encrypt)
+
+       save    %sp, -FRAME_SIZE, %sp
+       cmp     LENGTH, 0
+       be      .Lend
+
+       C       Loop invariants
+       add     T, AES_TABLE0, T0
+       add     T, AES_TABLE1, T1
+       add     T, AES_TABLE2, T2
+       add     T, AES_TABLE3, T3
+
+.Lblock_loop:
+       C  Read src, and add initial subkey
+       add     CTX, AES_KEYS, KEY
+       AES_LOAD(0, SRC, KEY, W0)
+       AES_LOAD(1, SRC, KEY, W1)
+       AES_LOAD(2, SRC, KEY, W2)
+       AES_LOAD(3, SRC, KEY, W3)
+
+       C       Must be even, and includes the final round
+       ld      [AES_NROUNDS + CTX], ROUND
+       add     SRC, 16, SRC
+       add     KEY, 16, KEY
+
+       srl     ROUND, 1, ROUND
+       C       Last two rounds handled specially
+       sub     ROUND, 1, ROUND
+.Lround_loop:
+       C The AES_ROUND macro uses T0,... T3
+       C       Transform W -> X
+       AES_ROUND(0, W0, W1, W2, W3, KEY, X0)
+       AES_ROUND(1, W1, W2, W3, W0, KEY, X1)
+       AES_ROUND(2, W2, W3, W0, W1, KEY, X2)
+       AES_ROUND(3, W3, W0, W1, W2, KEY, X3)
+
+       C       Transform X -> W
+       AES_ROUND(4, X0, X1, X2, X3, KEY, W0)
+       AES_ROUND(5, X1, X2, X3, X0, KEY, W1)
+       AES_ROUND(6, X2, X3, X0, X1, KEY, W2)
+       AES_ROUND(7, X3, X0, X1, X2, KEY, W3)
+
+       subcc   ROUND, 1, ROUND
+       bne     .Lround_loop
+       add     KEY, 32, KEY
+
+       C       Penultimate round
+       AES_ROUND(0, W0, W1, W2, W3, KEY, X0)
+       AES_ROUND(1, W1, W2, W3, W0, KEY, X1)
+       AES_ROUND(2, W2, W3, W0, W1, KEY, X2)
+       AES_ROUND(3, W3, W0, W1, W2, KEY, X3)
+
+       add     KEY, 16, KEY
+       C       Final round
+       AES_FINAL_ROUND(0, T, X0, X1, X2, X3, KEY, DST)
+       AES_FINAL_ROUND(1, T, X1, X2, X3, X0, KEY, DST)
+       AES_FINAL_ROUND(2, T, X2, X3, X0, X1, KEY, DST)
+       AES_FINAL_ROUND(3, T, X3, X0, X1, X2, KEY, DST)
+
+       subcc   LENGTH, 16, LENGTH
+       bne     .Lblock_loop
+       add     DST, 16, DST
+
+.Lend:
+       ret
+       restore
+EPILOGUE(_nettle_aes_encrypt)
+
+C Some stats from adriana.lysator.liu.se (SS1000$, 85 MHz), for AES 128
+
+C 1:   nettle-1.13 C-code
+C 2:   nettle-1.13 assembler
+C 3:   New C-code
+C 4:   New assembler, first correct version
+C 5:   New assembler, with basic scheduling of AES_ROUND.
+C 6:   New assembpler, with loop invariants T0-T3.
+C 7:   New assembler, with basic scheduling also of AES_FINAL_ROUND.
+       
+C      MB/s    cycles/block    Code size (bytes)
+C 1    1.2     1107            592
+C 2    2.3     572             1032
+C 3    2.1     627
+C 4    1.8     722
+C 5    2.6     496
+C 6    3.0     437
+C 7    3.1     415             1448
diff --git a/sparc32/aes.m4 b/sparc32/aes.m4
new file mode 100644 (file)
index 0000000..05f465e
--- /dev/null
@@ -0,0 +1,83 @@
+C Used as temporaries by the AES macros
+define(<TMP1>, <%g1>)
+define(<TMP2>, <%g2>)
+define(<TMP3>, <%g3>)
+
+C Loop invariants used by AES_ROUND
+define(<T0>,   <%o0>)
+define(<T1>,   <%o1>)
+define(<T2>,   <%o2>)
+define(<T3>,   <%o3>)
+
+C AES_LOAD(i, src, key, res)
+define(<AES_LOAD>, <
+       ldub    [$2 + 4*$1], $4
+       ldub    [$2 + 4*$1 + 1], TMP1
+       ldub    [$2 + 4*$1 + 2], TMP2
+       sll     TMP1, 8, TMP1
+       
+       or      $4, TMP1, $4
+       ldub    [$2 + 4*$1+3], TMP1
+       sll     TMP2, 16, TMP2
+       or      $4, TMP2, $4
+       
+       sll     TMP1, 24, TMP1
+       C       Get subkey
+       ld      [$3 + 4*$1], TMP2
+       or      $4, TMP1, $4
+       xor     $4, TMP2, $4>)dnl
+
+C AES_ROUND(i, a, b, c, d, key, res)
+C Computes one word of the AES round
+C FIXME: Could use registers pointing directly to the four tables
+C FIXME: Needs better instruction scheduling, and perhaps more temporaries
+C Alternatively, we can use a single table and some rotations
+define(<AES_ROUND>, <
+       and     $2, 0xff, TMP1          C  0
+       srl     $3, 6, TMP2             C  1
+       sll     TMP1, 2, TMP1           C  0
+       and     TMP2, 0x3fc, TMP2       C  1
+       ld      [T0 + TMP1], $7         C  0    E0
+       srl     $4, 14, TMP1            C  2
+       ld      [T1 + TMP2], TMP2       C  1
+       and     TMP1, 0x3fc, TMP1       C  2
+       xor     $7, TMP2, $7            C  1    E1
+       srl     $5, 22, TMP2            C  3
+       ld      [T2 + TMP1], TMP1       C  2
+       and     TMP2, 0x3fc, TMP2       C  3
+       xor     $7, TMP1, $7            C  2    E2
+       ld      [$6 + 4*$1], TMP1       C  4
+       ld      [T3 + TMP2], TMP2       C  3
+       xor     $7, TMP1, $7            C  4    E4
+       xor     $7, TMP2, $7            C  3    E3
+>)dnl
+
+C AES_FINAL_ROUND(i, T, a, b, c, d, key, dst)
+C Compute one word in the final round function. Output is converted to
+C octets and stored at dst. Relies on AES_SBOX being zero.
+define(<AES_FINAL_ROUND>, <
+       C       Load subkey
+       ld      [$7 + 4*$1], TMP3
+
+       and     $3, 0xff, TMP1          C  0
+       srl     $4, 8, TMP2             C  1
+       ldub    [T + TMP1], TMP1        C  0
+       and     TMP2, 0xff, TMP2        C  1
+       xor     TMP3, TMP1, TMP1        C  0
+       ldub    [T + TMP2], TMP2        C  1
+       stb     TMP1, [$8 + 4*$1]       C  0    E0
+       srl     $5, 16, TMP1            C  2
+       srl     TMP3, 8, TMP3           C  1
+       and     TMP1, 0xff, TMP1        C  2
+       xor     TMP3, TMP2, TMP2        C  1
+       ldub    [T + TMP1], TMP1        C  2
+       stb     TMP2, [$8 + 4*$1 + 1]   C  1    E1
+       srl     $6, 24, TMP2            C  3
+       srl     TMP3, 8, TMP3           C  2
+       ldub    [T + TMP2], TMP2        C  3
+       xor     TMP3, TMP1, TMP1        C  2
+       srl     TMP3, 8, TMP3           C  3
+       stb     TMP1, [$8 + 4*$1 + 2]   C  2    E2
+       xor     TMP3, TMP2, TMP2        C  3
+       stb     TMP2, [$8 + 4*$1 + 3]   C  3    E3
+>)
diff --git a/sparc32/arcfour-crypt.asm b/sparc32/arcfour-crypt.asm
new file mode 100644 (file)
index 0000000..4d8dac9
--- /dev/null
@@ -0,0 +1,230 @@
+C -*- mode: asm; asm-comment-char: ?C; -*-  
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2002, 2005 Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+C      Define to YES, to enable the complex code to special case SRC
+C      and DST with compatible alignment.
+       
+define(<WITH_ALIGN>, <YES>)
+
+C      Registers
+
+define(<CTX>,  <%i0>)
+define(<LENGTH>,<%i1>)
+define(<DST>,  <%i2>)
+define(<SRC>,  <%i3>)
+
+define(<I1>,   <%i4>)
+define(<I2>,   <%i5>)
+define(<J>,    <%g1>)
+define(<SI>,   <%g2>)
+define(<SJ>,   <%g3>)
+define(<TMP>,  <%o0>)
+define(<TMP2>, <%o1>)
+define(<N>,    <%o2>)
+define(<DATA>, <%o3>)
+
+C      Computes the next byte of the key stream. As input, i must
+C      already point to the index for the current access, the index
+C      for the next access is stored in ni. The resulting key byte is
+C      stored in res.
+C      ARCFOUR_BYTE(i, ni, res)
+define(<ARCFOUR_BYTE>, <
+       ldub    [CTX + $1], SI
+       add     $1, 1, $2
+       add     J, SI, J
+       and     J, 0xff, J
+       ldub    [CTX + J], SJ
+       and     $2, 0xff, $2
+       stb     SI, [CTX + J]
+       add     SI, SJ, SI
+       and     SI, 0xff, SI
+       stb     SJ, [CTX + $1]
+       ldub    [CTX + SI], $3
+>)dnl
+                       
+C      FIXME: Consider using the callers window
+define(<FRAME_SIZE>, 104)
+
+       .file "arcfour-crypt.asm"
+
+       C arcfour_crypt(struct arcfour_ctx *ctx,
+       C               unsigned length, uint8_t *dst,
+       C               const uint8_t *src)
+
+       .section        ".text"
+       .align 16
+       .proc   020
+       
+PROLOGUE(nettle_arcfour_crypt)
+
+       save    %sp, -FRAME_SIZE, %sp
+       cmp     LENGTH, 0
+       be      .Lend
+       nop
+       
+       C       Load both I and J
+       lduh    [CTX + ARCFOUR_I], I1
+       and     I1, 0xff, J
+       srl     I1, 8, I1
+
+       C       We want an even address for DST
+       andcc   DST, 1, %g0
+       add     I1, 1 ,I1
+       beq     .Laligned2
+       and     I1, 0xff, I1
+
+       mov     I1, I2
+       ldub    [SRC], DATA
+       ARCFOUR_BYTE(I2, I1, TMP)
+       subcc   LENGTH, 1, LENGTH
+       add     SRC, 1, SRC
+       xor     DATA, TMP, DATA
+       stb     DATA, [DST]
+       beq     .Ldone
+       add     DST, 1, DST
+
+.Laligned2:
+
+       cmp     LENGTH, 2
+       blu     .Lfinal1
+       C       Harmless delay slot instruction 
+       andcc   DST, 2, %g0
+       beq     .Laligned4
+       nop
+
+       ldub    [SRC], DATA
+       ARCFOUR_BYTE(I1, I2, TMP)
+       ldub    [SRC + 1], TMP2
+       add     SRC, 2, SRC
+       xor     DATA, TMP, DATA
+       sll     DATA, 8, DATA   
+
+       ARCFOUR_BYTE(I2, I1, TMP)
+       xor     TMP2, TMP, TMP
+       subcc   LENGTH, 2, LENGTH
+       or      DATA, TMP, DATA
+
+       sth     DATA, [DST]
+       beq     .Ldone
+       add     DST, 2, DST
+       
+.Laligned4:
+       cmp     LENGTH, 4
+       blu     .Lfinal2
+       C       Harmless delay slot instruction
+       srl     LENGTH, 2, N
+       
+.Loop:
+       C       Main loop, with aligned writes
+       
+       C       FIXME: Could check if SRC is aligned, and
+       C       use 32-bit reads in that case.
+
+       ldub    [SRC], DATA
+       ARCFOUR_BYTE(I1, I2, TMP)
+       ldub    [SRC + 1], TMP2
+       xor     TMP, DATA, DATA
+       sll     DATA, 8, DATA
+
+       ARCFOUR_BYTE(I2, I1, TMP)
+       xor     TMP2, TMP, TMP
+       ldub    [SRC + 2], TMP2
+       or      TMP, DATA, DATA
+       sll     DATA, 8, DATA
+
+       ARCFOUR_BYTE(I1, I2, TMP)
+       xor     TMP2, TMP, TMP
+       ldub    [SRC + 3], TMP2
+       or      TMP, DATA, DATA
+       sll     DATA, 8, DATA
+
+       ARCFOUR_BYTE(I2, I1, TMP)
+       xor     TMP2, TMP, TMP
+       or      TMP, DATA, DATA
+       subcc   N, 1, N
+       add     SRC, 4, SRC
+       st      DATA, [DST]
+       bne     .Loop
+       add     DST, 4, DST
+       
+       andcc   LENGTH, 3, LENGTH
+       beq     .Ldone
+       nop
+
+.Lfinal2:
+       C       DST address must be 2-aligned
+       cmp     LENGTH, 2
+       blu     .Lfinal1
+       nop
+
+       ldub    [SRC], DATA
+       ARCFOUR_BYTE(I1, I2, TMP)
+       ldub    [SRC + 1], TMP2
+       add     SRC, 2, SRC
+       xor     DATA, TMP, DATA
+       sll     DATA, 8, DATA   
+
+       ARCFOUR_BYTE(I2, I1, TMP)
+       xor     TMP2, TMP, TMP
+       or      DATA, TMP, DATA
+
+       sth     DATA, [DST]
+       beq     .Ldone
+       add     DST, 2, DST
+
+.Lfinal1:
+       mov     I1, I2
+       ldub    [SRC], DATA
+       ARCFOUR_BYTE(I2, I1, TMP)
+       xor     DATA, TMP, DATA
+       stb     DATA, [DST]
+
+.Ldone:
+       C       Save back I and J
+       sll     I2, 8, I2
+       or      I2, J, I2
+       stuh    I2, [CTX + ARCFOUR_I]
+
+.Lend:
+       ret
+       restore
+
+EPILOGUE(nettle_arcfour_crypt)
+
+C Some stats from adriana.lysator.liu.se (SS1000E, 85 MHz), for AES 128
+
+C 1:   nettle-1.13 C-code
+C 2:   First working version of the assembler code
+C 3:   Moved load of source byte
+C 4:   Better instruction scheduling
+C 5:   Special case SRC and DST with compatible alignment
+C 6:   After bugfix (reorder of ld [CTX+SI+SJ] and st [CTX + SI])
+C 7:   Unrolled only twice, with byte-accesses
+C 8:   Unrolled, using 8-bit reads and aligned 32-bit writes.
+
+C      MB/s    cycles/byte     Code size (bytes)
+C 1:   6.6     12.4            132
+C 2:   5.6     14.5            116
+C 3:   6.0     13.5            116
+C 4:   6.5     12.4            116
+C 5:   7.9     10.4            496
+C 6:   8.3     9.7             496
+C 7:   6.7     12.1            268
+C 8:   8.3     9.8             768
diff --git a/sparc32/machine.m4 b/sparc32/machine.m4
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sparc64/aes-decrypt-internal.asm b/sparc64/aes-decrypt-internal.asm
new file mode 100644 (file)
index 0000000..408dd72
--- /dev/null
@@ -0,0 +1,138 @@
+C -*- mode: asm; asm-comment-char: ?C; -*-  
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2002, 2005 Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+C The only difference between this code and the sparc32 code is the
+C frame offsets, and the magic BIAS when accessing the stack (which
+C doesn't matter, since we don't access any data on the stack).
+
+
+C Use the same AES macros as on sparc32.
+include_src(sparc32/aes.m4)
+
+C      Arguments
+define(<CTX>,  <%i0>)
+define(<T>,    <%i1>)
+define(<LENGTH>,<%i2>)
+define(<DST>,  <%i3>)
+define(<SRC>,  <%i4>)
+
+C      AES state, two copies for unrolling
+
+define(<W0>,   <%l0>)
+define(<W1>,   <%l1>)
+define(<W2>,   <%l2>)
+define(<W3>,   <%l3>)
+
+define(<X0>,   <%l4>)
+define(<X1>,   <%l5>)
+define(<X2>,   <%l6>)
+define(<X3>,   <%l7>)
+
+C      %o0-%03 are used for loop invariants T0-T3
+define(<KEY>,  <%o4>)
+define(<ROUND>, <%o5>)
+
+C %g1, %g2, %g3 are TMP1, TMP2 and TMP3
+
+C The sparc64 stack frame looks like
+C
+C %fp -   8: OS-dependent link field
+C %fp -  16: OS-dependent link field
+C %fp - 192: OS register save area (22*8 == 176 bytes) 
+define(<FRAME_SIZE>, 192)
+
+       .file "aes-decrypt-internal.asm"
+
+       C _aes_decrypt(struct aes_context *ctx, 
+       C              const struct aes_table *T,
+       C              unsigned length, uint8_t *dst,
+       C              uint8_t *src)
+
+       .section        ".text"
+       .align 16
+       .proc   020
+       
+PROLOGUE(_nettle_aes_decrypt)
+
+       save    %sp, -FRAME_SIZE, %sp
+       cmp     LENGTH, 0
+       be      .Lend
+
+       C       Loop invariants
+       add     T, AES_TABLE0, T0
+       add     T, AES_TABLE1, T1
+       add     T, AES_TABLE2, T2
+       add     T, AES_TABLE3, T3
+
+.Lblock_loop:
+       C  Read src, and add initial subkey
+       add     CTX, AES_KEYS, KEY
+       AES_LOAD(0, SRC, KEY, W0)
+       AES_LOAD(1, SRC, KEY, W1)
+       AES_LOAD(2, SRC, KEY, W2)
+       AES_LOAD(3, SRC, KEY, W3)
+
+       C       Must be even, and includes the final round
+       ld      [AES_NROUNDS + CTX], ROUND
+       add     SRC, 16, SRC
+       add     KEY, 16, KEY
+
+       srl     ROUND, 1, ROUND
+       C       Last two rounds handled specially
+       sub     ROUND, 1, ROUND
+.Lround_loop:
+       C The AES_ROUND macro uses T0,... T3
+       C       Transform W -> X
+       AES_ROUND(0, W0, W3, W2, W1, KEY, X0)
+       AES_ROUND(1, W1, W0, W3, W2, KEY, X1)
+       AES_ROUND(2, W2, W1, W0, W3, KEY, X2)
+       AES_ROUND(3, W3, W2, W1, W0, KEY, X3)
+
+       C       Transform X -> W
+       AES_ROUND(4, X0, X3, X2, X1, KEY, W0)
+       AES_ROUND(5, X1, X0, X3, X2, KEY, W1)
+       AES_ROUND(6, X2, X1, X0, X3, KEY, W2)
+       AES_ROUND(7, X3, X2, X1, X0, KEY, W3)
+
+       subcc   ROUND, 1, ROUND
+       bne     .Lround_loop
+       add     KEY, 32, KEY
+
+       C       Penultimate round
+       AES_ROUND(0, W0, W3, W2, W1, KEY, X0)
+       AES_ROUND(1, W1, W0, W3, W2, KEY, X1)
+       AES_ROUND(2, W2, W1, W0, W3, KEY, X2)
+       AES_ROUND(3, W3, W2, W1, W0, KEY, X3)
+
+       add     KEY, 16, KEY
+       C       Final round
+       AES_FINAL_ROUND(0, T, X0, X3, X2, X1, KEY, DST)
+       AES_FINAL_ROUND(1, T, X1, X0, X3, X2, KEY, DST)
+       AES_FINAL_ROUND(2, T, X2, X1, X0, X3, KEY, DST)
+       AES_FINAL_ROUND(3, T, X3, X2, X1, X0, KEY, DST)
+
+       subcc   LENGTH, 16, LENGTH
+       bne     .Lblock_loop
+       add     DST, 16, DST
+
+.Lend:
+       ret
+       restore
+EPILOGUE(_nettle_aes_decrypt)
diff --git a/sparc64/aes-encrypt-internal.asm b/sparc64/aes-encrypt-internal.asm
new file mode 100644 (file)
index 0000000..5462056
--- /dev/null
@@ -0,0 +1,149 @@
+C -*- mode: asm; asm-comment-char: ?C; -*-  
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2002, 2005 Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+C The only difference between this code and the sparc32 code is the
+C frame offsets, and the magic BIAS when accessing the stack (which
+C doesn't matter, since we don't access any data on the stack).
+
+
+C Use the same AES macros as on sparc32.
+include_src(sparc32/aes.m4)
+
+C      Arguments
+define(<CTX>,  <%i0>)
+define(<T>,    <%i1>)
+define(<LENGTH>,<%i2>)
+define(<DST>,  <%i3>)
+define(<SRC>,  <%i4>)
+
+C      AES state, two copies for unrolling
+
+define(<W0>,   <%l0>)
+define(<W1>,   <%l1>)
+define(<W2>,   <%l2>)
+define(<W3>,   <%l3>)
+
+define(<X0>,   <%l4>)
+define(<X1>,   <%l5>)
+define(<X2>,   <%l6>)
+define(<X3>,   <%l7>)
+
+C      %o0-%03 are used for loop invariants T0-T3
+define(<KEY>,  <%o4>)
+define(<ROUND>, <%o5>)
+
+C %g1, %g2, %g3 are TMP1, TMP2 and TMP3
+               
+C The sparc64 stack frame looks like
+C
+C %fp -   8: OS-dependent link field
+C %fp -  16: OS-dependent link field
+C %fp - 192: OS register save area (22*8 == 176 bytes) 
+define(<FRAME_SIZE>, 192)
+
+       .file "aes-encrypt-internal.asm"
+
+       C _aes_encrypt(struct aes_context *ctx, 
+       C              const struct aes_table *T,
+       C              unsigned length, uint8_t *dst,
+       C              uint8_t *src)
+
+       .section        ".text"
+       .align 16
+       .proc   020
+       
+PROLOGUE(_nettle_aes_encrypt)
+
+       save    %sp, -FRAME_SIZE, %sp
+       cmp     LENGTH, 0
+       be      .Lend
+
+       C       Loop invariants
+       add     T, AES_TABLE0, T0
+       add     T, AES_TABLE1, T1
+       add     T, AES_TABLE2, T2
+       add     T, AES_TABLE3, T3
+
+.Lblock_loop:
+       C  Read src, and add initial subkey
+       add     CTX, AES_KEYS, KEY
+       AES_LOAD(0, SRC, KEY, W0)
+       AES_LOAD(1, SRC, KEY, W1)
+       AES_LOAD(2, SRC, KEY, W2)
+       AES_LOAD(3, SRC, KEY, W3)
+
+       C       Must be even, and includes the final round
+       ld      [AES_NROUNDS + CTX], ROUND
+       add     SRC, 16, SRC
+       add     KEY, 16, KEY
+
+       srl     ROUND, 1, ROUND
+       C       Last two rounds handled specially
+       sub     ROUND, 1, ROUND
+.Lround_loop:
+       C The AES_ROUND macro uses T0,... T3
+       C       Transform W -> X
+       AES_ROUND(0, W0, W1, W2, W3, KEY, X0)
+       AES_ROUND(1, W1, W2, W3, W0, KEY, X1)
+       AES_ROUND(2, W2, W3, W0, W1, KEY, X2)
+       AES_ROUND(3, W3, W0, W1, W2, KEY, X3)
+
+       C       Transform X -> W
+       AES_ROUND(4, X0, X1, X2, X3, KEY, W0)
+       AES_ROUND(5, X1, X2, X3, X0, KEY, W1)
+       AES_ROUND(6, X2, X3, X0, X1, KEY, W2)
+       AES_ROUND(7, X3, X0, X1, X2, KEY, W3)
+
+       subcc   ROUND, 1, ROUND
+       bne     .Lround_loop
+       add     KEY, 32, KEY
+
+       C       Penultimate round
+       AES_ROUND(0, W0, W1, W2, W3, KEY, X0)
+       AES_ROUND(1, W1, W2, W3, W0, KEY, X1)
+       AES_ROUND(2, W2, W3, W0, W1, KEY, X2)
+       AES_ROUND(3, W3, W0, W1, W2, KEY, X3)
+
+       add     KEY, 16, KEY
+       C       Final round
+       AES_FINAL_ROUND(0, T, X0, X1, X2, X3, KEY, DST)
+       AES_FINAL_ROUND(1, T, X1, X2, X3, X0, KEY, DST)
+       AES_FINAL_ROUND(2, T, X2, X3, X0, X1, KEY, DST)
+       AES_FINAL_ROUND(3, T, X3, X0, X1, X2, KEY, DST)
+
+       subcc   LENGTH, 16, LENGTH
+       bne     .Lblock_loop
+       add     DST, 16, DST
+
+.Lend:
+       ret
+       restore
+EPILOGUE(_nettle_aes_encrypt)
+
+C      Stats for AES 128 on sellafield.lysator.liu.se (UE450, 296 MHz)
+
+C 1. nettle-1.13 C-code (nettle-1.13 assembler was broken for sparc64)
+C 2. New C-code
+C 3. New assembler code (basically the same as for sparc32)
+       
+C      MB/s    cycles/block
+C 1    0.8     5781
+C 2    1.8     2460
+C 3    8.2     548
diff --git a/sparc64/arcfour-crypt.asm b/sparc64/arcfour-crypt.asm
new file mode 100644 (file)
index 0000000..0e407d1
--- /dev/null
@@ -0,0 +1,217 @@
+C -*- mode: asm; asm-comment-char: ?C; -*-  
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2002, 2005 Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+C      Define to YES, to enable the complex code to special case SRC
+C      and DST with compatible alignment.
+       
+define(<WITH_ALIGN>, <YES>)
+
+C      Registers
+
+define(<CTX>,  <%i0>)
+define(<LENGTH>,<%i1>)
+define(<DST>,  <%i2>)
+define(<SRC>,  <%i3>)
+
+define(<I1>,   <%i4>)
+define(<I2>,   <%i5>)
+define(<J>,    <%g1>)
+define(<SI>,   <%g2>)
+define(<SJ>,   <%g3>)
+define(<TMP>,  <%o0>)
+define(<TMP2>, <%o1>)
+define(<N>,    <%o2>)
+define(<DATA>, <%o3>)
+
+C      Computes the next byte of the key stream. As input, i must
+C      already point to the index for the current access, the index
+C      for the next access is stored in ni. The resulting key byte is
+C      stored in res.
+C      ARCFOUR_BYTE(i, ni, res)
+define(<ARCFOUR_BYTE>, <
+       ldub    [CTX + $1], SI
+       add     $1, 1, $2
+       add     J, SI, J
+       and     J, 0xff, J
+       ldub    [CTX + J], SJ
+       and     $2, 0xff, $2
+       stb     SI, [CTX + J]
+       add     SI, SJ, SI
+       and     SI, 0xff, SI
+       stb     SJ, [CTX + $1]
+       ldub    [CTX + SI], $3
+>)dnl
+                       
+define(<FRAME_SIZE>, 192)
+
+       .file "arcfour-crypt.asm"
+
+       C arcfour_crypt(struct arcfour_ctx *ctx,
+       C               unsigned length, uint8_t *dst,
+       C               const uint8_t *src)
+
+       .section        ".text"
+       .align 16
+       .proc   020
+       
+PROLOGUE(nettle_arcfour_crypt)
+
+       save    %sp, -FRAME_SIZE, %sp
+       cmp     LENGTH, 0
+       be      .Lend
+       nop
+       
+       C       Load both I and J
+       lduh    [CTX + ARCFOUR_I], I1
+       and     I1, 0xff, J
+       srl     I1, 8, I1
+
+       C       We want an even address for DST
+       andcc   DST, 1, %g0
+       add     I1, 1 ,I1
+       beq     .Laligned2
+       and     I1, 0xff, I1
+
+       mov     I1, I2
+       ldub    [SRC], DATA
+       ARCFOUR_BYTE(I2, I1, TMP)
+       subcc   LENGTH, 1, LENGTH
+       add     SRC, 1, SRC
+       xor     DATA, TMP, DATA
+       stb     DATA, [DST]
+       beq     .Ldone
+       add     DST, 1, DST
+
+.Laligned2:
+
+       cmp     LENGTH, 2
+       blu     .Lfinal1
+       C       Harmless delay slot instruction 
+       andcc   DST, 2, %g0
+       beq     .Laligned4
+       nop
+
+       ldub    [SRC], DATA
+       ARCFOUR_BYTE(I1, I2, TMP)
+       ldub    [SRC + 1], TMP2
+       add     SRC, 2, SRC
+       xor     DATA, TMP, DATA
+       sll     DATA, 8, DATA   
+
+       ARCFOUR_BYTE(I2, I1, TMP)
+       xor     TMP2, TMP, TMP
+       subcc   LENGTH, 2, LENGTH
+       or      DATA, TMP, DATA
+
+       sth     DATA, [DST]
+       beq     .Ldone
+       add     DST, 2, DST
+       
+.Laligned4:
+       cmp     LENGTH, 4
+       blu     .Lfinal2
+       C       Harmless delay slot instruction
+       srl     LENGTH, 2, N
+       
+.Loop:
+       C       Main loop, with aligned writes
+       
+       C       FIXME: Could check if SRC is aligned, and
+       C       use 32-bit reads in that case.
+
+       ldub    [SRC], DATA
+       ARCFOUR_BYTE(I1, I2, TMP)
+       ldub    [SRC + 1], TMP2
+       xor     TMP, DATA, DATA
+       sll     DATA, 8, DATA
+
+       ARCFOUR_BYTE(I2, I1, TMP)
+       xor     TMP2, TMP, TMP
+       ldub    [SRC + 2], TMP2
+       or      TMP, DATA, DATA
+       sll     DATA, 8, DATA
+
+       ARCFOUR_BYTE(I1, I2, TMP)
+       xor     TMP2, TMP, TMP
+       ldub    [SRC + 3], TMP2
+       or      TMP, DATA, DATA
+       sll     DATA, 8, DATA
+
+       ARCFOUR_BYTE(I2, I1, TMP)
+       xor     TMP2, TMP, TMP
+       or      TMP, DATA, DATA
+       subcc   N, 1, N
+       add     SRC, 4, SRC
+       st      DATA, [DST]
+       bne     .Loop
+       add     DST, 4, DST
+       
+       andcc   LENGTH, 3, LENGTH
+       beq     .Ldone
+       nop
+
+.Lfinal2:
+       C       DST address must be 2-aligned
+       cmp     LENGTH, 2
+       blu     .Lfinal1
+       nop
+
+       ldub    [SRC], DATA
+       ARCFOUR_BYTE(I1, I2, TMP)
+       ldub    [SRC + 1], TMP2
+       add     SRC, 2, SRC
+       xor     DATA, TMP, DATA
+       sll     DATA, 8, DATA   
+
+       ARCFOUR_BYTE(I2, I1, TMP)
+       xor     TMP2, TMP, TMP
+       or      DATA, TMP, DATA
+
+       sth     DATA, [DST]
+       beq     .Ldone
+       add     DST, 2, DST
+
+.Lfinal1:
+       mov     I1, I2
+       ldub    [SRC], DATA
+       ARCFOUR_BYTE(I2, I1, TMP)
+       xor     DATA, TMP, DATA
+       stb     DATA, [DST]
+
+.Ldone:
+       C       Save back I and J
+       sll     I2, 8, I2
+       or      I2, J, I2
+       stuh    I2, [CTX + ARCFOUR_I]
+
+.Lend:
+       ret
+       restore
+
+EPILOGUE(nettle_arcfour_crypt)
+
+C      Stats for AES 128 on sellafield.lysator.liu.se (UE450, 296 MHz)
+
+C 1:   nettle-1.13 C-code
+C 2:   New assembler code (basically the same as for sparc32)
+
+C      MB/s    cycles/byte
+C 1:   3.6     77.7
+C 2:   21.8    13.0
diff --git a/sparc64/machine.m4 b/sparc64/machine.m4
new file mode 100644 (file)
index 0000000..4c1c0e5
--- /dev/null
@@ -0,0 +1,4 @@
+define(<BIAS>, 2047) C Magic stack bias for the Sparc64 ABI
+
+.register %g2,#scratch
+.register %g3,#scratch
diff --git a/stamp-h.in b/stamp-h.in
new file mode 100644 (file)
index 0000000..9788f70
--- /dev/null
@@ -0,0 +1 @@
+timestamp
diff --git a/testsuite/.test-rules.make b/testsuite/.test-rules.make
new file mode 100644 (file)
index 0000000..e8f6650
--- /dev/null
@@ -0,0 +1,144 @@
+aes-test$(EXEEXT): aes-test.$(OBJEXT)
+       $(LINK) aes-test.$(OBJEXT) $(TEST_OBJS) -o aes-test$(EXEEXT)
+
+arcfour-test$(EXEEXT): arcfour-test.$(OBJEXT)
+       $(LINK) arcfour-test.$(OBJEXT) $(TEST_OBJS) -o arcfour-test$(EXEEXT)
+
+arctwo-test$(EXEEXT): arctwo-test.$(OBJEXT)
+       $(LINK) arctwo-test.$(OBJEXT) $(TEST_OBJS) -o arctwo-test$(EXEEXT)
+
+blowfish-test$(EXEEXT): blowfish-test.$(OBJEXT)
+       $(LINK) blowfish-test.$(OBJEXT) $(TEST_OBJS) -o blowfish-test$(EXEEXT)
+
+cast128-test$(EXEEXT): cast128-test.$(OBJEXT)
+       $(LINK) cast128-test.$(OBJEXT) $(TEST_OBJS) -o cast128-test$(EXEEXT)
+
+base16-test$(EXEEXT): base16-test.$(OBJEXT)
+       $(LINK) base16-test.$(OBJEXT) $(TEST_OBJS) -o base16-test$(EXEEXT)
+
+base64-test$(EXEEXT): base64-test.$(OBJEXT)
+       $(LINK) base64-test.$(OBJEXT) $(TEST_OBJS) -o base64-test$(EXEEXT)
+
+camellia-test$(EXEEXT): camellia-test.$(OBJEXT)
+       $(LINK) camellia-test.$(OBJEXT) $(TEST_OBJS) -o camellia-test$(EXEEXT)
+
+des-test$(EXEEXT): des-test.$(OBJEXT)
+       $(LINK) des-test.$(OBJEXT) $(TEST_OBJS) -o des-test$(EXEEXT)
+
+des3-test$(EXEEXT): des3-test.$(OBJEXT)
+       $(LINK) des3-test.$(OBJEXT) $(TEST_OBJS) -o des3-test$(EXEEXT)
+
+des-compat-test$(EXEEXT): des-compat-test.$(OBJEXT)
+       $(LINK) des-compat-test.$(OBJEXT) $(TEST_OBJS) -o des-compat-test$(EXEEXT)
+
+md2-test$(EXEEXT): md2-test.$(OBJEXT)
+       $(LINK) md2-test.$(OBJEXT) $(TEST_OBJS) -o md2-test$(EXEEXT)
+
+md4-test$(EXEEXT): md4-test.$(OBJEXT)
+       $(LINK) md4-test.$(OBJEXT) $(TEST_OBJS) -o md4-test$(EXEEXT)
+
+md5-test$(EXEEXT): md5-test.$(OBJEXT)
+       $(LINK) md5-test.$(OBJEXT) $(TEST_OBJS) -o md5-test$(EXEEXT)
+
+md5-compat-test$(EXEEXT): md5-compat-test.$(OBJEXT)
+       $(LINK) md5-compat-test.$(OBJEXT) $(TEST_OBJS) -o md5-compat-test$(EXEEXT)
+
+memxor-test$(EXEEXT): memxor-test.$(OBJEXT)
+       $(LINK) memxor-test.$(OBJEXT) $(TEST_OBJS) -o memxor-test$(EXEEXT)
+
+ripemd160-test$(EXEEXT): ripemd160-test.$(OBJEXT)
+       $(LINK) ripemd160-test.$(OBJEXT) $(TEST_OBJS) -o ripemd160-test$(EXEEXT)
+
+sha1-test$(EXEEXT): sha1-test.$(OBJEXT)
+       $(LINK) sha1-test.$(OBJEXT) $(TEST_OBJS) -o sha1-test$(EXEEXT)
+
+sha224-test$(EXEEXT): sha224-test.$(OBJEXT)
+       $(LINK) sha224-test.$(OBJEXT) $(TEST_OBJS) -o sha224-test$(EXEEXT)
+
+sha256-test$(EXEEXT): sha256-test.$(OBJEXT)
+       $(LINK) sha256-test.$(OBJEXT) $(TEST_OBJS) -o sha256-test$(EXEEXT)
+
+sha384-test$(EXEEXT): sha384-test.$(OBJEXT)
+       $(LINK) sha384-test.$(OBJEXT) $(TEST_OBJS) -o sha384-test$(EXEEXT)
+
+sha512-test$(EXEEXT): sha512-test.$(OBJEXT)
+       $(LINK) sha512-test.$(OBJEXT) $(TEST_OBJS) -o sha512-test$(EXEEXT)
+
+serpent-test$(EXEEXT): serpent-test.$(OBJEXT)
+       $(LINK) serpent-test.$(OBJEXT) $(TEST_OBJS) -o serpent-test$(EXEEXT)
+
+twofish-test$(EXEEXT): twofish-test.$(OBJEXT)
+       $(LINK) twofish-test.$(OBJEXT) $(TEST_OBJS) -o twofish-test$(EXEEXT)
+
+knuth-lfib-test$(EXEEXT): knuth-lfib-test.$(OBJEXT)
+       $(LINK) knuth-lfib-test.$(OBJEXT) $(TEST_OBJS) -o knuth-lfib-test$(EXEEXT)
+
+cbc-test$(EXEEXT): cbc-test.$(OBJEXT)
+       $(LINK) cbc-test.$(OBJEXT) $(TEST_OBJS) -o cbc-test$(EXEEXT)
+
+ctr-test$(EXEEXT): ctr-test.$(OBJEXT)
+       $(LINK) ctr-test.$(OBJEXT) $(TEST_OBJS) -o ctr-test$(EXEEXT)
+
+gcm-test$(EXEEXT): gcm-test.$(OBJEXT)
+       $(LINK) gcm-test.$(OBJEXT) $(TEST_OBJS) -o gcm-test$(EXEEXT)
+
+hmac-test$(EXEEXT): hmac-test.$(OBJEXT)
+       $(LINK) hmac-test.$(OBJEXT) $(TEST_OBJS) -o hmac-test$(EXEEXT)
+
+meta-hash-test$(EXEEXT): meta-hash-test.$(OBJEXT)
+       $(LINK) meta-hash-test.$(OBJEXT) $(TEST_OBJS) -o meta-hash-test$(EXEEXT)
+
+meta-cipher-test$(EXEEXT): meta-cipher-test.$(OBJEXT)
+       $(LINK) meta-cipher-test.$(OBJEXT) $(TEST_OBJS) -o meta-cipher-test$(EXEEXT)
+
+meta-armor-test$(EXEEXT): meta-armor-test.$(OBJEXT)
+       $(LINK) meta-armor-test.$(OBJEXT) $(TEST_OBJS) -o meta-armor-test$(EXEEXT)
+
+buffer-test$(EXEEXT): buffer-test.$(OBJEXT)
+       $(LINK) buffer-test.$(OBJEXT) $(TEST_OBJS) -o buffer-test$(EXEEXT)
+
+yarrow-test$(EXEEXT): yarrow-test.$(OBJEXT)
+       $(LINK) yarrow-test.$(OBJEXT) $(TEST_OBJS) -o yarrow-test$(EXEEXT)
+
+sexp-test$(EXEEXT): sexp-test.$(OBJEXT)
+       $(LINK) sexp-test.$(OBJEXT) $(TEST_OBJS) -o sexp-test$(EXEEXT)
+
+sexp-format-test$(EXEEXT): sexp-format-test.$(OBJEXT)
+       $(LINK) sexp-format-test.$(OBJEXT) $(TEST_OBJS) -o sexp-format-test$(EXEEXT)
+
+rsa2sexp-test$(EXEEXT): rsa2sexp-test.$(OBJEXT)
+       $(LINK) rsa2sexp-test.$(OBJEXT) $(TEST_OBJS) -o rsa2sexp-test$(EXEEXT)
+
+sexp2rsa-test$(EXEEXT): sexp2rsa-test.$(OBJEXT)
+       $(LINK) sexp2rsa-test.$(OBJEXT) $(TEST_OBJS) -o sexp2rsa-test$(EXEEXT)
+
+bignum-test$(EXEEXT): bignum-test.$(OBJEXT)
+       $(LINK) bignum-test.$(OBJEXT) $(TEST_OBJS) -o bignum-test$(EXEEXT)
+
+random-prime-test$(EXEEXT): random-prime-test.$(OBJEXT)
+       $(LINK) random-prime-test.$(OBJEXT) $(TEST_OBJS) -o random-prime-test$(EXEEXT)
+
+pkcs1-test$(EXEEXT): pkcs1-test.$(OBJEXT)
+       $(LINK) pkcs1-test.$(OBJEXT) $(TEST_OBJS) -o pkcs1-test$(EXEEXT)
+
+rsa-test$(EXEEXT): rsa-test.$(OBJEXT)
+       $(LINK) rsa-test.$(OBJEXT) $(TEST_OBJS) -o rsa-test$(EXEEXT)
+
+rsa-encrypt-test$(EXEEXT): rsa-encrypt-test.$(OBJEXT)
+       $(LINK) rsa-encrypt-test.$(OBJEXT) $(TEST_OBJS) -o rsa-encrypt-test$(EXEEXT)
+
+rsa-keygen-test$(EXEEXT): rsa-keygen-test.$(OBJEXT)
+       $(LINK) rsa-keygen-test.$(OBJEXT) $(TEST_OBJS) -o rsa-keygen-test$(EXEEXT)
+
+dsa-test$(EXEEXT): dsa-test.$(OBJEXT)
+       $(LINK) dsa-test.$(OBJEXT) $(TEST_OBJS) -o dsa-test$(EXEEXT)
+
+dsa-keygen-test$(EXEEXT): dsa-keygen-test.$(OBJEXT)
+       $(LINK) dsa-keygen-test.$(OBJEXT) $(TEST_OBJS) -o dsa-keygen-test$(EXEEXT)
+
+sha1-huge-test$(EXEEXT): sha1-huge-test.$(OBJEXT)
+       $(LINK) sha1-huge-test.$(OBJEXT) $(TEST_OBJS) -o sha1-huge-test$(EXEEXT)
+
+cxx-test$(EXEEXT): cxx-test.$(OBJEXT)
+       $(LINK_CXX) cxx-test.$(OBJEXT) $(TEST_OBJS) -o cxx-test$(EXEEXT)
+
diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in
new file mode 100644 (file)
index 0000000..6a28d67
--- /dev/null
@@ -0,0 +1,113 @@
+@SET_MAKE@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+top_srcdir = @top_srcdir@
+
+include ../config.make
+
+PRE_CPPFLAGS = -I.. -I$(top_srcdir)
+PRE_LDFLAGS = -L..
+
+TS_NETTLE_SOURCES = aes-test.c arcfour-test.c arctwo-test.c \
+                   blowfish-test.c cast128-test.c \
+                   base16-test.c base64-test.c \
+                   camellia-test.c \
+                   des-test.c des3-test.c des-compat-test.c \
+                   md2-test.c md4-test.c md5-test.c md5-compat-test.c \
+                   memxor-test.c \
+                   ripemd160-test.c \
+                   sha1-test.c sha224-test.c sha256-test.c \
+                   sha384-test.c sha512-test.c \
+                   serpent-test.c twofish-test.c \
+                   knuth-lfib-test.c \
+                   cbc-test.c ctr-test.c gcm-test.c hmac-test.c \
+                   meta-hash-test.c meta-cipher-test.c meta-armor-test.c \
+                   buffer-test.c yarrow-test.c
+
+TS_HOGWEED_SOURCES = sexp-test.c sexp-format-test.c \
+                    rsa2sexp-test.c sexp2rsa-test.c \
+                    bignum-test.c random-prime-test.c \
+                    pkcs1-test.c \
+                    rsa-test.c rsa-encrypt-test.c rsa-keygen-test.c \
+                    dsa-test.c dsa-keygen-test.c
+
+TS_SOURCES = $(TS_NETTLE_SOURCES) @IF_HOGWEED@ $(TS_HOGWEED_SOURCES)
+
+TS_NETTLE = $(TS_NETTLE_SOURCES:.c=$(EXEEXT))
+TS_HOGWEED = $(TS_HOGWEED_SOURCES:.c=$(EXEEXT))
+TS_C = $(TS_NETTLE) @IF_HOGWEED@ $(TS_HOGWEED)
+TS_CXX = @CXX_TESTS@
+TARGETS = $(TS_C) $(TS_CXX)
+TS_SH = sexp-conv-test pkcs1-conv-test symbols-test
+TS_ALL = $(TARGETS) $(TS_SH)
+EXTRA_SOURCES = sha1-huge-test.c
+EXTRA_TARGETS = $(EXTRA_SOURCES:.c=$(EXEEXT))
+
+SOURCES = $(TS_SOURCES) testutils.c
+
+DISTFILES = $(SOURCES) $(EXTRA_SOURCES) cxx-test.cxx Makefile.in .test-rules.make \
+       $(TS_SH) run-tests teardown-env \
+       gold-bug.txt testutils.h
+
+all: $(TARGETS) $(EXTRA_TARGETS)
+
+.c.$(OBJEXT):
+       $(COMPILE) -c $< && $(DEP_PROCESS)
+
+.SUFFIXES: .cxx
+.cxx.$(OBJEXT):
+       $(COMPILE_CXX) -c $< && $(DEP_PROCESS)
+
+# BSD (and Solaris) make doesn't allow extra dependencies together one
+# single-suffix rules, which makes it impossible or almost impossible
+# to use suffix rules to build the test executables. So we use an
+# explicit rule for each and every executable.
+
+LIB_HOGWEED = @IF_HOGWEED@ -lhogweed
+TEST_OBJS = testutils.$(OBJEXT) $(LIB_HOGWEED) -lnettle $(LIBS)
+
+.PHONY: test-rules
+test-rules:
+       (for f in $(TS_NETTLE) $(TS_HOGWEED) $(EXTRA_TARGETS) ; do \
+         echo $$f'$$(EXEEXT): '$$f'.$$(OBJEXT)' ; \
+         echo '        $$(LINK) '$$f'.$$(OBJEXT) $$(TEST_OBJS) -o '$$f'$$(EXEEXT)' ; \
+         echo ; \
+       done ; \
+       for f in $(TS_CXX) ; do \
+         echo $$f'$$(EXEEXT): '$$f'.$$(OBJEXT)' ; \
+         echo '        $$(LINK_CXX) '$$f'.$$(OBJEXT) $$(TEST_OBJS) -o '$$f'$$(EXEEXT)' ; \
+         echo ; \
+       done) > $(srcdir)/.test-rules.make
+
+include $(srcdir)/.test-rules.make
+
+$(TARGETS) $(EXTRA_TARGETS): testutils.$(OBJEXT) \
+       ../libnettle.a @IF_HOGWEED@ ../libhogweed.a
+
+# The PATH update is for locating dlls on w*ndows.
+check: $(TS_ALL) $(srcdir)/run-tests
+       LD_LIBRARY_PATH=../.lib PATH="../.lib:$$PATH" srcdir="$(srcdir)" \
+         $(srcdir)/run-tests $(TS_ALL)
+
+
+Makefile: $(srcdir)/Makefile.in ../config.status
+       cd .. && $(SHELL) ./config.status testsuite/$@
+
+install uninstall:
+       true
+
+distdir: $(DISTFILES)
+       cp $? $(distdir)
+
+clean:
+       -rm -f $(TARGETS) $(EXTRA_TARGETS) *.o test.in test1.out test2.out
+
+distclean: clean
+       -rm -f Makefile *.d
+
+tags:
+       etags -o $(srcdir)/TAGS --include $(top_srcdir) $(srcdir)/*.c $(srcdir)/*.h
+
+@DEP_INCLUDE@ $(SOURCES:.c=.$(OBJEXT).d)
diff --git a/testsuite/aes-test.c b/testsuite/aes-test.c
new file mode 100644 (file)
index 0000000..87be806
--- /dev/null
@@ -0,0 +1,171 @@
+#include "testutils.h"
+#include "aes.h"
+
+static void
+test_invert(unsigned key_length, const uint8_t *key,
+           unsigned length, const uint8_t *cleartext,
+           const uint8_t *ciphertext)
+{
+  struct aes_ctx encrypt;
+  struct aes_ctx decrypt;
+  uint8_t *data = xalloc(length);
+
+  aes_set_encrypt_key (&encrypt, key_length, key);
+  aes_encrypt (&encrypt, length, data, cleartext);
+  
+  if (!MEMEQ(length, data, ciphertext))
+    {
+      fprintf(stderr, "test_invert: Encrypt failed:\nInput:");
+      print_hex(length, cleartext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      print_hex(length, ciphertext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+
+  aes_invert_key (&decrypt, &encrypt);
+  aes_decrypt (&decrypt, length, data, data);
+
+  if (!MEMEQ(length, data, cleartext))
+    {
+      fprintf(stderr, "test_invert: Decrypt failed:\nInput:");
+      print_hex(length, ciphertext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      print_hex(length, cleartext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+  free (data);
+}
+
+int
+test_main(void)
+{
+  /* 128 bit keys */
+  test_cipher(&nettle_aes128, 
+             HL("0001020305060708 0A0B0C0D0F101112"),
+             HL("506812A45F08C889 B97F5980038B8359"),
+             H("D8F532538289EF7D 06B506A4FD5BE9C9"));
+  
+  test_cipher(&nettle_aes128, 
+             HL("14151617191A1B1C 1E1F202123242526"),
+             HL("5C6D71CA30DE8B8B 00549984D2EC7D4B"),
+             H("59AB30F4D4EE6E4F F9907EF65B1FB68C"));
+
+  test_cipher(&nettle_aes128, 
+             HL("28292A2B2D2E2F30 323334353738393A"),
+             HL("53F3F4C64F8616E4 E7C56199F48F21F6"),
+             H("BF1ED2FCB2AF3FD4 1443B56D85025CB1"));
+  
+  test_cipher(&nettle_aes128, 
+             HL("A0A1A2A3A5A6A7A8 AAABACADAFB0B1B2"),
+             HL("F5F4F7F684878689 A6A7A0A1D2CDCCCF"),
+             H("CE52AF650D088CA5 59425223F4D32694"));
+
+  /* 192 bit keys */
+  
+  test_cipher(&nettle_aes192, 
+             HL("0001020305060708 0A0B0C0D0F101112"
+               "14151617191A1B1C"),
+             HL("2D33EEF2C0430A8A 9EBF45E809C40BB6"),
+             H("DFF4945E0336DF4C 1C56BC700EFF837F"));
+
+  /* 256 bit keys */
+  
+  test_cipher(&nettle_aes256,
+             HL("0001020305060708 0A0B0C0D0F101112"
+               "14151617191A1B1C 1E1F202123242526"),
+             HL("834EADFCCAC7E1B30664B1ABA44815AB"),
+             H("1946DABF6A03A2A2 C3D0B05080AED6FC"));
+
+  
+  /* This test case has been problematic with the CBC test case */
+  test_cipher(&nettle_aes256,
+             HL("8d ae 93 ff fc 78 c9 44"
+               "2a bd 0c 1e 68 bc a6 c7"
+               "05 c7 84 e3 5a a9 11 8b"
+               "d3 16 aa 54 9b 44 08 9e"),
+             HL("a5 ce 55 d4 21 15 a1 c6 4a a4 0c b2 ca a6 d1 37"),
+             /* In the cbc test, I once got the bad value
+              *   "b2 a0 6c d2 2f df 7d 2c  26 d2 42 88 8f 20 74 a2" */
+             H("1f 94 fc 85 f2 36 21 06"
+               "4a ea e3 c9 cc 38 01 0e"));
+  
+  /* From draft NIST spec on AES modes.
+   *
+   * F.1 ECB Example Vectors
+   * F.1.1 ECB-AES128-Encrypt
+   */
+
+  test_cipher(&nettle_aes128,
+             HL("2b7e151628aed2a6abf7158809cf4f3c"),
+             HL("6bc1bee22e409f96e93d7e117393172a"
+               "ae2d8a571e03ac9c9eb76fac45af8e51"
+               "30c81c46a35ce411e5fbc1191a0a52ef"
+               "f69f2445df4f9b17ad2b417be66c3710"),
+             H("3ad77bb40d7a3660a89ecaf32466ef97"
+               "f5d3d58503b9699de785895a96fdbaaf"
+               "43b1cd7f598ece23881b00e3ed030688"
+               "7b0c785e27e8ad3f8223207104725dd4"));
+
+  /* F.1.3 ECB-AES192-Encrypt */
+
+  test_cipher(&nettle_aes192,
+             HL("8e73b0f7da0e6452c810f32b809079e5 62f8ead2522c6b7b"),
+             HL("6bc1bee22e409f96e93d7e117393172a"
+               "ae2d8a571e03ac9c9eb76fac45af8e51"
+               "30c81c46a35ce411e5fbc1191a0a52ef"
+               "f69f2445df4f9b17ad2b417be66c3710"),
+             H("bd334f1d6e45f25ff712a214571fa5cc"
+               "974104846d0ad3ad7734ecb3ecee4eef"
+               "ef7afd2270e2e60adce0ba2face6444e"
+               "9a4b41ba738d6c72fb16691603c18e0e"));
+
+  /* F.1.5 ECB-AES256-Encrypt */
+  test_cipher(&nettle_aes256,
+             HL("603deb1015ca71be2b73aef0857d7781"
+               "1f352c073b6108d72d9810a30914dff4"),
+             HL("6bc1bee22e409f96e93d7e117393172a"
+               "ae2d8a571e03ac9c9eb76fac45af8e51" 
+               "30c81c46a35ce411e5fbc1191a0a52ef"
+               "f69f2445df4f9b17ad2b417be66c3710"),
+             H("f3eed1bdb5d2a03c064b5a7e3db181f8"
+               "591ccb10d410ed26dc5ba74a31362870"
+               "b6ed21b99ca6f4f9f153e7b1beafed1d"
+               "23304b7a39f9f3ff067d8d8f9e24ecc7"));
+
+  /* Test aes_invert_key with src != dst */
+  test_invert(HL("0001020305060708 0A0B0C0D0F101112"),
+             HL("506812A45F08C889 B97F5980038B8359"),
+             H("D8F532538289EF7D 06B506A4FD5BE9C9"));
+  test_invert(HL("0001020305060708 0A0B0C0D0F101112"
+               "14151617191A1B1C"),
+             HL("2D33EEF2C0430A8A 9EBF45E809C40BB6"),
+             H("DFF4945E0336DF4C 1C56BC700EFF837F"));
+  test_invert(HL("0001020305060708 0A0B0C0D0F101112"
+               "14151617191A1B1C 1E1F202123242526"),
+             HL("834EADFCCAC7E1B30664B1ABA44815AB"),
+             H("1946DABF6A03A2A2 C3D0B05080AED6FC"));
+
+  SUCCESS();
+}
+
+/* Internal state for the first test case:
+
+   0: a7106950 81cf0e5a 8d5574b3 4b929b0c
+   1: aa1e31c4 c19a8917  12282e4 b23e51eb
+   2: 14be6dac fede8fdc 8fb98878 a27dfb5c
+   3: e80a6f32 431515bb 72e8a651 7daf188b
+   4: c50438c0 d464b2b6 76b875e9 b2b5f574
+   5: d81ab740 746b4d89 ff033aac 44d5ffa2
+   6: 52e6bb4a edadc170 24867df4 6e2ad5d5
+   7: ab1c7365 64d09f00 7718d521 46a3df32
+   8: f1eaad16  1aefdfb 7ba5724d d8499631
+   9:  1020300  2030001  3000102    10203
+  99: 5332f5d8 7def8982 a406b506 c9e95bfd
+
+*/
diff --git a/testsuite/arcfour-test.c b/testsuite/arcfour-test.c
new file mode 100644 (file)
index 0000000..6027c54
--- /dev/null
@@ -0,0 +1,97 @@
+#include "testutils.h"
+#include "arcfour.h"
+
+int
+test_main(void)
+{
+  test_cipher_stream(&nettle_arcfour128,
+                    HL("01234567 89ABCDEF 00000000 00000000"),
+                    HL("01234567 89ABCDEF"),
+                    H("69723659 1B5242B1"));
+
+  /* More data. This ensures that we get some collisions between the S
+     accesses at index i,j and the access at si + sj. I.e. the cases
+     where the ordering of loads and stores matter. */
+  test_cipher_stream(&nettle_arcfour128,
+                    HL("aaaaaaaa bbbbbbbb cccccccc dddddddd"),
+                    HL("00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"
+                       "00000000 00000000 00000000 00000000"),
+                    H("a2b35dc7 bf95ae1e 1c432d15 f4fb8c1c"
+                      "f264e1d0 bd090831 6caa7d17 5401ae67"
+                      "3cfbd140 fd3dee42 1012d674 2fb69fa3"
+                      "6522631e bb3d4703 535de1ce 4a81ddce"
+
+                      "5780cfe0 b5fc9fae ebe14c96 26451bd9"
+                      "992f2204 119cbe37 cbdc453c 7afa08c7"
+                      "1380ccf8 48f81e53 a535cdfb 96c64faa"
+                      "c3f759d0 fa1ff920 008d95cf 39d52324"
+
+                      "d0aac3f9 749b22e2 6a065145 06fb249d"
+                      "ffb8e05e cb0381fe 5346a04a 63dac61c"
+                      "10b6683e 3ab427de d4c6bc60 6366545e"
+                      "77d0e121 96037717 a745d49e e72a70aa"
+
+                      "a50a612d 879b0580 fd4a89ae 3ee49871"
+                      "2cf6c98d a62dfbc7 d7b2d901 2c3aaf27"
+                      "42b7e089 ef2466ac 450b440c 138daa1a"
+                      "cf9ebef6 f66a7a64 2677b213 06640130"
+
+                      "de6651df 0065180d 4db366ba 9c377712"
+                      "53d21cac 82ed72a4 c6c4d81e 4375fea3"
+                      "1f935909 95322c83 13c64d8e 829c93a6"
+                      "d540a1b3 20f41541 96800888 1a7afc9b"
+
+                      "e39e89fc 3ac78be5 cdbbf774 33c36863"
+                      "da2a3b1b d06e54a9 aa4b7edd 70b34941"
+                      "b886f7db f36c3def f9fc4c80 7ce55ea5"
+                      "98a7257b f68a9e1d caf4bfd6 43bd9853"
+
+                      "c966629d 54e34221 6e140780 d48c69bb"
+                      "5e77e886 86f2ebcb 807732d5 d29bc384"
+                      "a4ca1c31 c7c1b5b9 85dbfcf1 8d845905"
+                      "a0ff487a b4a3f252 a75caebf 857ba48b"
+
+                      "613e3067 92cada3e 0e07f599 2f4794f3"
+                      "af01f15a 491732fb 22aa09a3 d2e1e408"
+                      "fe94bdb4 993c68b1 1bb79eb1 bb7ec446"
+                      "760ef7bf 2caa8713 479760e5 a6e143cd"));
+  
+  SUCCESS();
+}
diff --git a/testsuite/arctwo-test.c b/testsuite/arctwo-test.c
new file mode 100644 (file)
index 0000000..17c3503
--- /dev/null
@@ -0,0 +1,115 @@
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2004 Simon Josefsson
+ * Copyright (C) 2004 Niels Möller
+ *
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#include "testutils.h"
+#include "arctwo.h"
+
+/* For tests with obscure values of ebk. */
+static void
+test_arctwo(unsigned ekb,
+           unsigned key_length,
+           const uint8_t *key,
+           unsigned length,
+           const uint8_t *cleartext,
+           const uint8_t *ciphertext)
+{
+  struct arctwo_ctx ctx;
+  uint8_t *data = xalloc(length);
+
+  arctwo_set_key_ekb(&ctx, key_length, key, ekb);
+  arctwo_encrypt(&ctx, length, data, cleartext);
+
+  if (!MEMEQ(length, data, ciphertext))
+    FAIL();
+
+  arctwo_decrypt(&ctx, length, data, data);
+
+  if (!MEMEQ(length, data, cleartext))
+    FAIL();
+
+  free(data);
+}
+
+int
+test_main(void)
+{
+  /* Test vectors from Peter Gutmann's paper. */
+  test_cipher(&nettle_arctwo_gutmann128,
+             HL("00000000 00000000 00000000 00000000"),
+             HL("00000000 00000000"),
+             H ("1c198a83 8df028b7"));
+
+  test_cipher(&nettle_arctwo_gutmann128,
+             HL("00010203 04050607 08090a0b 0c0d0e0f"),
+             HL("00000000 00000000"),
+             H ("50dc0162 bd757f31"));
+
+  /* This one was checked against libmcrypt's RFC2268. */
+  test_cipher(&nettle_arctwo_gutmann128,
+             HL("30000000 00000000 00000000 00000000"),
+             HL("10000000 00000000"),
+             H ("8fd10389 336bf95e"));
+
+  /* Test vectors from RFC 2268. */
+  test_cipher(&nettle_arctwo64,
+             HL("ffffffff ffffffff"),
+             HL("ffffffff ffffffff"),
+             H ("278b27e4 2e2f0d49"));
+
+  test_cipher(&nettle_arctwo64,
+             HL("30000000 00000000"),
+             HL("10000000 00000001"),
+             H ("30649edf 9be7d2c2"));
+
+  test_cipher(&nettle_arctwo128,
+             HL("88bca90e 90875a7f 0f79c384 627bafb2"),
+             HL("00000000 00000000"),
+             H ("2269552a b0f85ca6"));
+
+  /* More obscure tests from RFC 2286 */
+  test_arctwo(63,
+             HL("00000000 00000000"),
+             HL("00000000 00000000"),
+             H ("ebb773f9 93278eff"));
+
+  test_arctwo(64,
+             HL("88"),
+             HL("00000000 00000000"),
+             H ("61a8a244 adacccf0"));
+
+  test_arctwo(64,
+             HL("88bca90e 90875a"),
+             HL("00000000 00000000"),
+             H ("6ccf4308 974c267f"));
+
+  test_arctwo(64,
+             HL("88bca90e 90875a7f 0f79c384 627bafb2"),
+             HL("00000000 00000000"),
+             H ("1a807d27 2bbe5db1"));
+
+  test_arctwo(129,
+             HL("88bca90e 90875a7f 0f79c384 627bafb2"
+                "16f80a6f 85920584 c42fceb0 be255daf 1e"),
+             HL("00000000 00000000"),
+             H ("5b78d3a4 3dfff1f1"));
+
+  SUCCESS ();
+}
diff --git a/testsuite/base16-test.c b/testsuite/base16-test.c
new file mode 100644 (file)
index 0000000..fe8fe92
--- /dev/null
@@ -0,0 +1,27 @@
+#include "testutils.h"
+#include "base16.h"
+
+int
+test_main(void)
+{
+  ASSERT(BASE16_ENCODE_LENGTH(0) == 0);
+  ASSERT(BASE16_ENCODE_LENGTH(1) == 2);
+  ASSERT(BASE16_ENCODE_LENGTH(2) == 4);
+
+  ASSERT(BASE16_DECODE_LENGTH(0) == 0);
+  ASSERT(BASE16_DECODE_LENGTH(1) == 1);
+  ASSERT(BASE16_DECODE_LENGTH(2) == 1);
+  ASSERT(BASE16_DECODE_LENGTH(3) == 2);
+  ASSERT(BASE16_DECODE_LENGTH(4) == 2);
+  
+  test_armor(&nettle_base16, 0, "", "");
+  test_armor(&nettle_base16, 1, "H", "48");
+  test_armor(&nettle_base16, 2, "He", "4865");
+  test_armor(&nettle_base16, 3, "Hel", "48656c");
+  test_armor(&nettle_base16, 4, "Hell", "48656c6c");
+  test_armor(&nettle_base16, 5, "Hello", "48656c6c6f");
+  test_armor(&nettle_base16, 6, "Hello", "48656c6c6f00");
+  
+  SUCCESS();
+}
+  
diff --git a/testsuite/base64-test.c b/testsuite/base64-test.c
new file mode 100644 (file)
index 0000000..b4d0917
--- /dev/null
@@ -0,0 +1,50 @@
+#include "testutils.h"
+#include "base64.h"
+
+int
+test_main(void)
+{
+  ASSERT(BASE64_ENCODE_LENGTH(0) == 0);   /* At most   4 bits */
+  ASSERT(BASE64_ENCODE_LENGTH(1) == 2);   /* At most  12 bits */
+  ASSERT(BASE64_ENCODE_LENGTH(2) == 3);   /* At most  20 bits */
+  ASSERT(BASE64_ENCODE_LENGTH(3) == 4);   /* At most  28 bits */
+  ASSERT(BASE64_ENCODE_LENGTH(4) == 6);   /* At most  36 bits */
+  ASSERT(BASE64_ENCODE_LENGTH(5) == 7);   /* At most  44 bits */
+  ASSERT(BASE64_ENCODE_LENGTH(12) == 16); /* At most 100 bits */
+  ASSERT(BASE64_ENCODE_LENGTH(13) == 18); /* At most 108 bits */
+
+  ASSERT(BASE64_DECODE_LENGTH(0) == 0); /* At most  6 bits */
+  ASSERT(BASE64_DECODE_LENGTH(1) == 1); /* At most 12 bits */
+  ASSERT(BASE64_DECODE_LENGTH(2) == 2); /* At most 18 bits */
+  ASSERT(BASE64_DECODE_LENGTH(3) == 3); /* At most 24 bits */
+  ASSERT(BASE64_DECODE_LENGTH(4) == 3); /* At most 30 bits */
+  
+  test_armor(&nettle_base64, 0, "", "");
+  test_armor(&nettle_base64, 1, "H", "SA==");
+  test_armor(&nettle_base64, 2, "He", "SGU=");
+  test_armor(&nettle_base64, 3, "Hel", "SGVs");
+  test_armor(&nettle_base64, 4, "Hell", "SGVsbA==");
+  test_armor(&nettle_base64, 5, "Hello", "SGVsbG8=");
+  test_armor(&nettle_base64, 6, "Hello", "SGVsbG8A");
+  test_armor(&nettle_base64, 4, "\xff\xff\xff\xff", "/////w==");
+
+  {
+    /* Test overlapping areas */
+    uint8_t buffer[] = "Helloxxxx";
+    struct base64_decode_ctx ctx;
+    unsigned dst_length;
+    
+    ASSERT(BASE64_ENCODE_RAW_LENGTH(5) == 8);
+    base64_encode_raw(buffer, 5, buffer);
+    ASSERT(MEMEQ(9, buffer, "SGVsbG8=x"));
+
+    base64_decode_init(&ctx);
+    dst_length = 8;
+    ASSERT(base64_decode_update(&ctx, &dst_length, buffer, 8, buffer));
+    ASSERT(dst_length == 5);
+    
+    ASSERT(MEMEQ(9, buffer, "HelloG8=x"));
+  }
+  
+  SUCCESS();
+}
diff --git a/testsuite/bignum-test.c b/testsuite/bignum-test.c
new file mode 100644 (file)
index 0000000..84e0483
--- /dev/null
@@ -0,0 +1,97 @@
+#include "testutils.h"
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_LIBGMP
+#include "bignum.h"
+
+static void
+test_bignum(const char *hex, unsigned length, const uint8_t *base256)
+{
+  mpz_t a;
+  mpz_t b;
+  uint8_t *buf;
+  
+  mpz_init_set_str(a, hex, 16);
+  nettle_mpz_init_set_str_256_s(b, length, base256);
+
+  if (mpz_cmp(a, b))
+    FAIL();
+
+  buf = xalloc(length + 1);
+  memset(buf, 17, length + 1);
+
+  nettle_mpz_get_str_256(length, buf, a);
+  if (!MEMEQ(length, buf, base256))
+    FAIL();
+
+  if (buf[length] != 17)
+    FAIL();
+
+  mpz_clear(a); mpz_clear(b);
+  free(buf);
+}
+
+static void
+test_size(long x, unsigned size)
+{
+  mpz_t t;
+
+  mpz_init_set_si(t, x);
+  ASSERT(nettle_mpz_sizeinbase_256_s(t) == size);
+  mpz_clear(t);
+}
+#endif /* HAVE_LIBGMP */
+
+
+int
+test_main(void)
+{
+#if HAVE_LIBGMP
+  test_size(0, 1);
+  test_size(1, 1);
+  test_size(0x7f, 1);
+  test_size(0x80, 2);
+  test_size(0x81, 2);
+  test_size(0xff, 2);
+  test_size(0x100, 2);
+  test_size(0x101, 2);
+  test_size(0x1111, 2);
+  test_size(0x7fff, 2);
+  test_size(0x8000, 3);
+  test_size(0x8001, 3);
+
+  test_size(-      1, 1); /*     ff */
+  test_size(-   0x7f, 1); /*     81 */
+  test_size(-   0x80, 1); /*     80 */
+  test_size(-   0x81, 2); /*   ff7f */
+  test_size(-   0xff, 2); /*   ff01 */
+  test_size(-  0x100, 2); /*   ff00 */
+  test_size(-  0x101, 2); /*   feff */
+  test_size(- 0x1111, 2); /*   eeef */
+  test_size(- 0x7fff, 2); /*   8001 */
+  test_size(- 0x8000, 2); /*   8000 */
+  test_size(- 0x8001, 3); /* ff7fff */
+
+  test_bignum("0", HL("00"));
+  test_bignum("010203040506", HL("010203040506"));
+  test_bignum("80010203040506", HL("0080010203040506"));
+
+  test_bignum(   "-1", HL(    "ff"));
+  test_bignum(  "-7f", HL(    "81"));
+  test_bignum(  "-80", HL(    "80"));
+  test_bignum(  "-81", HL(  "ff7f"));
+  test_bignum("-7fff", HL(  "8001"));
+  test_bignum("-8000", HL(  "8000"));
+  test_bignum("-8001", HL("ff7fff"));
+  
+  SUCCESS();
+#else /* !HAVE_LIBGMP */
+  SKIP();
+#endif /* !HAVE_LIBGMP */
+}
diff --git a/testsuite/blowfish-test.c b/testsuite/blowfish-test.c
new file mode 100644 (file)
index 0000000..c4311bb
--- /dev/null
@@ -0,0 +1,89 @@
+#include "testutils.h"
+#include "nettle-internal.h"
+#include "blowfish.h"
+
+int
+test_main(void)
+{
+  /* 208 bit key. Test from GNUPG. */
+  test_cipher(&nettle_blowfish128,
+             26, "abcdefghijklmnopqrstuvwxyz",
+             BLOWFISH_BLOCK_SIZE, "BLOWFISH",
+             H("32 4E D0 FE F4 13 A2 03"));
+
+  SUCCESS();
+}
+/* FIXME: All values below are bogus. */
+#if 0
+
+/* 128 bit keys */
+H(msg, "506812A45F08C889 B97F5980038B8359");
+
+blowfish_set_key(&ctx, 16,  H("0001020305060708 0A0B0C0D0F101112"));
+blowfish_encrypt(&ctx, BLOWFISH_BLOCK_SIZE, cipher, msg);
+if (!MEMEQ(16, cipher, H("D8F532538289EF7D 06B506A4FD5BE9C9")))
+  FAIL;
+
+blowfish_decrypt(&ctx, BLOWFISH_BLOCK_SIZE, clear, cipher);
+if (!MEMEQ(16, msg, clear))
+  FAIL;
+
+H(msg, "5C6D71CA30DE8B8B 00549984D2EC7D4B");
+
+blowfish_set_key(&ctx, 16,  H("14151617191A1B1C 1E1F202123242526"));
+blowfish_encrypt(&ctx, BLOWFISH_BLOCK_SIZE, cipher, msg);
+if (!MEMEQ(16, cipher, H("59AB30F4D4EE6E4F F9907EF65B1FB68C")))
+  FAIL;
+
+blowfish_decrypt(&ctx, BLOWFISH_BLOCK_SIZE, clear, cipher);
+if (!MEMEQ(16, msg, clear))
+  FAIL;
+
+H(msg, "53F3F4C64F8616E4 E7C56199F48F21F6");
+
+blowfish_set_key(&ctx, 16,  H("28292A2B2D2E2F30 323334353738393A"));
+blowfish_encrypt(&ctx, BLOWFISH_BLOCK_SIZE, cipher, msg);
+if (!MEMEQ(16, cipher, H("BF1ED2FCB2AF3FD4 1443B56D85025CB1")))
+  FAIL;
+
+blowfish_decrypt(&ctx, BLOWFISH_BLOCK_SIZE, clear, cipher);
+if (!MEMEQ(16, msg, clear))
+  FAIL;
+
+H(msg, "F5F4F7F684878689 A6A7A0A1D2CDCCCF");
+
+blowfish_set_key(&ctx, 16,  H("A0A1A2A3A5A6A7A8 AAABACADAFB0B1B2"));
+blowfish_encrypt(&ctx, BLOWFISH_BLOCK_SIZE, cipher, msg);
+if (!MEMEQ(16, cipher, H("CE52AF650D088CA5 59425223F4D32694")))
+  FAIL;
+
+blowfish_decrypt(&ctx, BLOWFISH_BLOCK_SIZE, clear, cipher);
+if (!MEMEQ(16, msg, clear))
+  FAIL;
+
+/* 192 bit keys */
+H(msg, "2D33EEF2C0430A8A 9EBF45E809C40BB6");
+
+blowfish_set_key(&ctx, 24,  H("0001020305060708 0A0B0C0D0F101112"
+                        "14151617191A1B1C"));
+blowfish_encrypt(&ctx, BLOWFISH_BLOCK_SIZE, cipher, msg);
+if (!MEMEQ(16, cipher, H("DFF4945E0336DF4C 1C56BC700EFF837F")))
+  FAIL;
+
+blowfish_decrypt(&ctx, BLOWFISH_BLOCK_SIZE, clear, cipher);
+if (!MEMEQ(16, msg, clear))
+  FAIL;
+
+/* 256 bit keys */
+H(msg, "834EADFCCAC7E1B30664B1ABA44815AB");
+
+blowfish_set_key(&ctx, 32,  H("0001020305060708 0A0B0C0D0F101112"
+                        "14151617191A1B1C 1E1F202123242526"));
+blowfish_encrypt(&ctx, BLOWFISH_BLOCK_SIZE, cipher, msg);
+if (!MEMEQ(16, cipher, H("1946DABF6A03A2A2 C3D0B05080AED6FC")))
+  FAIL;
+
+blowfish_decrypt(&ctx, BLOWFISH_BLOCK_SIZE, clear, cipher);
+if (!MEMEQ(16, msg, clear))
+  FAIL;
+#endif
diff --git a/testsuite/buffer-test.c b/testsuite/buffer-test.c
new file mode 100644 (file)
index 0000000..3ac4b20
--- /dev/null
@@ -0,0 +1,29 @@
+#include "testutils.h"
+#include "buffer.h"
+
+int
+test_main(void)
+{
+  struct nettle_buffer buffer;
+  uint8_t s[5];
+  
+  nettle_buffer_init(&buffer);
+  ASSERT(nettle_buffer_write(&buffer, LDATA("foo")));
+  
+  ASSERT(NETTLE_BUFFER_PUTC(&buffer, 'x'));
+
+  ASSERT(buffer.size == 4);
+  ASSERT(buffer.alloc >= 4);
+  ASSERT(MEMEQ(4, buffer.contents, "foox"));
+
+  nettle_buffer_clear(&buffer);
+  
+  nettle_buffer_init_size(&buffer, sizeof(s), s);
+  ASSERT(buffer.alloc == sizeof(s));
+  ASSERT(nettle_buffer_write(&buffer, LDATA("foo")));
+  ASSERT(buffer.size == 3);
+
+  ASSERT(!nettle_buffer_write(&buffer, LDATA("bar")));
+
+  SUCCESS();
+}
diff --git a/testsuite/camellia-test.c b/testsuite/camellia-test.c
new file mode 100644 (file)
index 0000000..4f1d118
--- /dev/null
@@ -0,0 +1,84 @@
+#include "testutils.h"
+#include "camellia.h"
+
+static void
+test_invert(unsigned key_length, const uint8_t *key,
+           unsigned length, const uint8_t *cleartext,
+           const uint8_t *ciphertext)
+{
+  struct camellia_ctx encrypt;
+  struct camellia_ctx decrypt;
+  uint8_t *data = xalloc(length);
+
+  camellia_set_encrypt_key (&encrypt, key_length, key);
+  camellia_crypt (&encrypt, length, data, cleartext);
+  
+  if (!MEMEQ(length, data, ciphertext))
+    {
+      fprintf(stderr, "test_invert: Encrypt failed:\nInput:");
+      print_hex(length, cleartext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      print_hex(length, ciphertext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+
+  camellia_invert_key (&decrypt, &encrypt);
+  camellia_crypt (&decrypt, length, data, data);
+
+  if (!MEMEQ(length, data, cleartext))
+    {
+      fprintf(stderr, "test_invert: Decrypt failed:\nInput:");
+      print_hex(length, ciphertext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      print_hex(length, cleartext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+  free (data);
+}
+
+int
+test_main(void)
+{
+  /* Test vectors from RFC 3713 */
+  /* 128 bit keys */
+  test_cipher(&nettle_camellia128,
+             HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"),
+             HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"),
+             H("67 67 31 38 54 96 69 73 08 57 06 56 48 ea be 43"));
+
+  /* 192 bit keys */
+  test_cipher(&nettle_camellia192, 
+             HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"
+                 "00 11 22 33 44 55 66 77"),
+             HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"),
+             H("b4 99 34 01 b3 e9 96 f8 4e e5 ce e7 d7 9b 09 b9"));
+
+  /* 256 bit keys */
+  test_cipher(&nettle_camellia256, 
+             HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"
+                 "00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff"),
+             HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"),
+             H("9a cc 23 7d ff 16 d7 6c 20 ef 7c 91 9e 3a 75 09"));
+
+  /* Test camellia_invert_key with src != dst */
+  test_invert(HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"),
+             HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"),
+             H("67 67 31 38 54 96 69 73 08 57 06 56 48 ea be 43"));
+  
+  test_invert(HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"
+                 "00 11 22 33 44 55 66 77"),
+             HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"),
+             H("b4 99 34 01 b3 e9 96 f8 4e e5 ce e7 d7 9b 09 b9"));
+
+  test_invert(HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"
+                 "00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff"),
+             HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"),
+             H("9a cc 23 7d ff 16 d7 6c 20 ef 7c 91 9e 3a 75 09"));
+  SUCCESS();
+}
diff --git a/testsuite/cast128-test.c b/testsuite/cast128-test.c
new file mode 100644 (file)
index 0000000..e4b7830
--- /dev/null
@@ -0,0 +1,30 @@
+#include "testutils.h"
+#include "cast128.h"
+
+int
+test_main(void)
+{
+  /* Test vectors from B.1. Single Plaintext-Key-Ciphertext Sets, RFC
+   * 2144 */
+
+  /* 128 bit key */
+  test_cipher(&nettle_cast128,
+             HL("01 23 45 67 12 34 56 78"
+                "23 45 67 89 34 56 78 9A"),
+             HL("01 23 45 67 89 AB CD EF"),
+             H("23 8B 4F E5 84 7E 44 B2"));
+  
+  /* 80 bit key */
+  test_cipher(&nettle_cast128,
+             HL("01 23 45 67 12 34 56 78 23 45"),
+             HL("01 23 45 67 89 AB CD EF"),
+             H("EB 6A 71 1A 2C 02 27 1B"));
+
+  /* 40 bit key */
+  test_cipher(&nettle_cast128,
+             HL("01 23 45 67 12"),
+             HL("01 23 45 67 89 AB CD EF"),
+             H("7A C8 16 D1 6E 9B 30 2E"));
+
+  SUCCESS();
+}
diff --git a/testsuite/cbc-test.c b/testsuite/cbc-test.c
new file mode 100644 (file)
index 0000000..b7bd2dd
--- /dev/null
@@ -0,0 +1,329 @@
+#include "testutils.h"
+#include "aes.h"
+#include "cbc.h"
+#include "knuth-lfib.h"
+
+/* Test with more data and inplace decryption, to check that the
+ * cbc_decrypt buffering works. */
+#define CBC_BULK_DATA 0x2710 /* 10000 */
+
+static void
+test_cbc_bulk(void)
+{
+  struct knuth_lfib_ctx random;
+  
+  uint8_t clear[CBC_BULK_DATA];
+  
+  uint8_t cipher[CBC_BULK_DATA + 1];
+
+  const uint8_t *key = H("966c7bf00bebe6dc 8abd37912384958a"
+                        "743008105a08657d dcaad4128eee38b3");
+  
+  const uint8_t *start_iv = H("11adbff119749103 207619cfa0e8d13a");
+  const uint8_t *end_iv = H("c7a42a569b421224 d0c23e52f46f97f5");
+  
+  struct CBC_CTX(struct aes_ctx, AES_BLOCK_SIZE) aes;
+  
+  knuth_lfib_init(&random, CBC_BULK_DATA);
+  knuth_lfib_random(&random, CBC_BULK_DATA, clear);
+
+  /* Byte that should not be overwritten */
+  cipher[CBC_BULK_DATA] = 17;
+  
+  aes_set_encrypt_key(&aes.ctx, 32, key);
+  CBC_SET_IV(&aes, start_iv);
+
+  CBC_ENCRYPT(&aes, aes_encrypt, CBC_BULK_DATA, cipher, clear);
+
+  if (cipher[CBC_BULK_DATA] != 17)
+    FAIL();
+
+  if (verbose)
+    {
+      printf("IV after bulk encryption: ");
+      print_hex(AES_BLOCK_SIZE, aes.iv);
+      printf("\n");
+    }
+
+  if (!MEMEQ(AES_BLOCK_SIZE, aes.iv, end_iv))
+    FAIL();
+  
+  /* Decrypt, in place */
+  aes_set_decrypt_key(&aes.ctx, 32, key);
+  CBC_SET_IV(&aes, start_iv);
+  CBC_DECRYPT(&aes, aes_decrypt, CBC_BULK_DATA, cipher, cipher);
+
+  if (cipher[CBC_BULK_DATA] != 17)
+    FAIL();
+
+  if (verbose)
+    {
+      printf("IV after bulk decryption: ");
+      print_hex(AES_BLOCK_SIZE, aes.iv);
+      printf("\n");
+    }
+
+  if (!MEMEQ(AES_BLOCK_SIZE, aes.iv, end_iv))
+    FAIL();
+
+  if (!MEMEQ(CBC_BULK_DATA, clear, cipher))
+    FAIL();
+}
+
+int
+test_main(void)
+{
+  static const uint8_t msg[2 * AES_BLOCK_SIZE] = "Listen, I'll say this only once!";
+  
+  /* Intermediate values:
+   *   iv XOR first message block:
+   *       "a5 ce 55 d4 21 15 a1 c6 4a a4 0c b2 ca a6 d1 37"
+   *   First ciphertext block, c1:
+   *       "1f 94 fc 85 f2 36 21 06 4a ea e3 c9 cc 38 01 0e"
+   *   c1 XOR second message block:
+   *       "3f e0 94 ec 81 16 4e 68 26 93 c3 a6 a2 5b 64 2f"
+   *   Second ciphertext block, c1:
+   *       "7b f6 5f c5 02 59 2e 71 af bf 34 87 c0 36 2a 16"
+   */
+
+  test_cipher_cbc(&nettle_aes256,
+                 HL("8d ae 93 ff fc 78 c9 44"
+                    "2a bd 0c 1e 68 bc a6 c7"
+                    "05 c7 84 e3 5a a9 11 8b"
+                    "d3 16 aa 54 9b 44 08 9e"),
+                 2 * AES_BLOCK_SIZE, msg,
+                 H("1f 94 fc 85 f2 36 21 06"
+                   "4a ea e3 c9 cc 38 01 0e"
+                   "7b f6 5f c5 02 59 2e 71"
+                   "af bf 34 87 c0 36 2a 16"),
+                 H("e9 a7 26 a0 44 7b 8d e6  03 83 60 de ea d5 b0 4e"));
+
+  /* From NIST spec 800-38a on AES modes.
+   *
+   * F.2  CBC Example Vectors 
+   * F.2.1 CBC-AES128.Encrypt
+   */
+
+  /* Intermediate values, blocks input to AES:
+   *
+   *   6bc0bce12a459991e134741a7f9e1925 
+   *   d86421fb9f1a1eda505ee1375746972c 
+   *   604ed7ddf32efdff7020d0238b7c2a5d 
+   *   8521f2fd3c8eef2cdc3da7e5c44ea206 
+   */
+  test_cipher_cbc(&nettle_aes128,
+                 HL("2b7e151628aed2a6abf7158809cf4f3c"),
+                 HL("6bc1bee22e409f96e93d7e117393172a"
+                    "ae2d8a571e03ac9c9eb76fac45af8e51"
+                    "30c81c46a35ce411e5fbc1191a0a52ef"
+                    "f69f2445df4f9b17ad2b417be66c3710"),
+                 H("7649abac8119b246cee98e9b12e9197d"
+                   "5086cb9b507219ee95db113a917678b2"
+                   "73bed6b8e3c1743b7116e69e22229516"
+                   "3ff1caa1681fac09120eca307586e1a7"),
+                 H("000102030405060708090a0b0c0d0e0f"));
+  
+  /* F.2.3 CBC-AES192.Encrypt */
+  
+  /* Intermediate values, blcoks input to AES:
+   *
+   *   6bc0bce12a459991e134741a7f9e1925 
+   *   e12f97e55dbfcfa1efcf7796da0fffb9
+   *   8411b1ef0e2109e5001cf96f256346b5 
+   *   a1840065cdb4e1f7d282fbd7db9d35f0
+   */
+
+  test_cipher_cbc(&nettle_aes192,
+                 HL("8e73b0f7da0e6452c810f32b809079e5"
+                    "62f8ead2522c6b7b"),
+                 HL("6bc1bee22e409f96e93d7e117393172a"
+                    "ae2d8a571e03ac9c9eb76fac45af8e51"
+                    "30c81c46a35ce411e5fbc1191a0a52ef"
+                    "f69f2445df4f9b17ad2b417be66c3710"),
+                 H("4f021db243bc633d7178183a9fa071e8"
+                   "b4d9ada9ad7dedf4e5e738763f69145a"
+                   "571b242012fb7ae07fa9baac3df102e0"
+                   "08b0e27988598881d920a9e64f5615cd"),
+                 H("000102030405060708090a0b0c0d0e0f"));
+   
+  /* F.2.5 CBC-AES256.Encrypt */
+
+  /* Intermediate values, blcoks input to AES:
+   *
+   *   6bc0bce12a459991e134741a7f9e1925 
+   *   5ba1c653c8e65d26e929c4571ad47587 
+   *   ac3452d0dd87649c8264b662dc7a7e92
+   *   cf6d172c769621d8081ba318e24f2371 
+   */
+
+  test_cipher_cbc(&nettle_aes256,
+                 HL("603deb1015ca71be2b73aef0857d7781"
+                    "1f352c073b6108d72d9810a30914dff4"),
+                 HL("6bc1bee22e409f96e93d7e117393172a"
+                    "ae2d8a571e03ac9c9eb76fac45af8e51"
+                    "30c81c46a35ce411e5fbc1191a0a52ef"
+                    "f69f2445df4f9b17ad2b417be66c3710"),
+                 H("f58c4c04d6e5f1ba779eabfb5f7bfbd6"
+                   "9cfc4e967edb808d679f777bc6702c7d"
+                   "39f23369a9d9bacfa530e26304231461"
+                   "b2eb05e2c39be9fcda6c19078c6a9d1b"),
+                 H("000102030405060708090a0b0c0d0e0f"));
+
+  test_cbc_bulk();
+   
+  SUCCESS();
+}
+
+/*
+IV 
+  000102030405060708090a0b0c0d0e0f 
+Block #1 
+Plaintext      6bc1bee22e409f96e93d7e117393172a 
+Input Block     6bc0bce12a459991e134741a7f9e1925 
+Output Block  7649abac8119b246cee98e9b12e9197d 
+Ciphertext 7649abac8119b246cee98e9b12e9197d 
+Block #2 
+Plaintext      ae2d8a571e03ac9c9eb76fac45af8e51 
+Input Block     d86421fb9f1a1eda505ee1375746972c 
+Output Block  5086cb9b507219ee95db113a917678b2 
+Ciphertext 5086cb9b507219ee95db113a917678b2 
+Block #3 
+Plaintext      30c81c46a35ce411e5fbc1191a0a52ef 
+Input Block     604ed7ddf32efdff7020d0238b7c2a5d 
+Output Block  73bed6b8e3c1743b7116e69e22229516 
+Ciphertext 73bed6b8e3c1743b7116e69e22229516 
+Block #4 
+Plaintext      f69f2445df4f9b17ad2b417be66c3710 
+Input Block     8521f2fd3c8eef2cdc3da7e5c44ea206 
+Output Block  3ff1caa1681fac09120eca307586e1a7 
+Ciphertext 3ff1caa1681fac09120eca307586e1a7 
+ F.2.2 CBC-AES128.Decrypt 
+Key 
+  2b7e151628aed2a6abf7158809cf4f3c 
+IV 
+  000102030405060708090a0b0c0d0e0f 
+Block #1 
+Ciphertext 7649abac8119b246cee98e9b12e9197d 
+Input Block     7649abac8119b246cee98e9b12e9197d 
+Output Block  6bc0bce12a459991e134741a7f9e1925 
+Plaintext      6bc1bee22e409f96e93d7e117393172a 
+Block #2 
+Ciphertext 5086cb9b507219ee95db113a917678b2 
+Input Block     5086cb9b507219ee95db113a917678b2 
+Output Block  d86421fb9f1a1eda505ee1375746972c 
+Plaintext      ae2d8a571e03ac9c9eb76fac45af8e51 
+Block #3 
+Ciphertext 73bed6b8e3c1743b7116e69e22229516 
+Input Block     73bed6b8e3c1743b7116e69e22229516 
+Output Block  604ed7ddf32efdff7020d0238b7c2a5d 
+Plaintext      30c81c46a35ce411e5fbc1191a0a52ef 
+Block #4 
+Ciphertext 3ff1caa1681fac09120eca307586e1a7 
+Input Block     3ff1caa1681fac09120eca307586e1a7 
+
+
+Output Block  8521f2fd3c8eef2cdc3da7e5c44ea206 
+Plaintext      f69f2445df4f9b17ad2b417be66c3710 
+ F.2.3 CBC-AES192.Encrypt 
+Key 
+  8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b
+IV 
+  000102030405060708090a0b0c0d0e0f 
+Block #1 
+Plaintext      6bc1bee22e409f96e93d7e117393172a 
+Input Block     6bc0bce12a459991e134741a7f9e1925 
+Output Block  4f021db243bc633d7178183a9fa071e8 
+Ciphertext 4f021db243bc633d7178183a9fa071e8 
+Block #2 
+Plaintext      ae2d8a571e03ac9c9eb76fac45af8e51 
+Input Block     e12f97e55dbfcfa1efcf7796da0fffb9 
+Output Block  b4d9ada9ad7dedf4e5e738763f69145a 
+Ciphertext b4d9ada9ad7dedf4e5e738763f69145a 
+Block #3 
+Plaintext      30c81c46a35ce411e5fbc1191a0a52ef 
+Input Block     8411b1ef0e2109e5001cf96f256346b5 
+Output Block  571b242012fb7ae07fa9baac3df102e0 
+Ciphertext 571b242012fb7ae07fa9baac3df102e0 
+Block #4 
+Plaintext      f69f2445df4f9b17ad2b417be66c3710 
+Input Block     a1840065cdb4e1f7d282fbd7db9d35f0 
+Output Block  08b0e27988598881d920a9e64f5615cd 
+Ciphertext 08b0e27988598881d920a9e64f5615cd 
+ F.2.4 CBC-AES192.Decrypt 
+Key 
+  8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b
+IV 
+  000102030405060708090a0b0c0d0e0f 
+Block #1 
+Ciphertext 4f021db243bc633d7178183a9fa071e8 
+Input Block     4f021db243bc633d7178183a9fa071e8 
+Output Block  6bc0bce12a459991e134741a7f9e1925 
+Plaintext      6bc1bee22e409f96e93d7e117393172a 
+Block #2 
+Ciphertext b4d9ada9ad7dedf4e5e738763f69145a 
+Input Block     b4d9ada9ad7dedf4e5e738763f69145a 
+Output Block  e12f97e55dbfcfa1efcf7796da0fffb9 
+Plaintext      ae2d8a571e03ac9c9eb76fac45af8e51 
+Block #3 
+Ciphertext 571b242012fb7ae07fa9baac3df102e0 
+Input Block     571b242012fb7ae07fa9baac3df102e0 
+Output Block  8411b1ef0e2109e5001cf96f256346b5 
+Plaintext      30c81c46a35ce411e5fbc1191a0a52ef 
+Block #4 
+Ciphertext 08b0e27988598881d920a9e64f5615cd 
+Input Block     08b0e27988598881d920a9e64f5615cd 
+Output Block  a1840065cdb4e1f7d282fbd7db9d35f0 
+Plaintext      f69f2445df4f9b17ad2b417be66c3710 
+ F.2.5 CBC-AES256.Encrypt 
+Key 
+  603deb1015ca71be2b73aef0857d7781 
+1f352c073b6108d72d9810a30914dff4 
+  IV 
+  000102030405060708090a0b0c0d0e0f 
+Block #1 
+Plaintext      6bc1bee22e409f96e93d7e117393172a 
+Input Block     6bc0bce12a459991e134741a7f9e1925 
+Output Block  f58c4c04d6e5f1ba779eabfb5f7bfbd6 
+Ciphertext f58c4c04d6e5f1ba779eabfb5f7bfbd6 
+Block #2 
+Plaintext      ae2d8a571e03ac9c9eb76fac45af8e51 
+Input Block     5ba1c653c8e65d26e929c4571ad47587 
+Output Block  9cfc4e967edb808d679f777bc6702c7d 
+Ciphertext 9cfc4e967edb808d679f777bc6702c7d
+Block #3 
+Plaintext      30c81c46a35ce411e5fbc1191a0a52ef 
+Input Block     ac3452d0dd87649c8264b662dc7a7e92 
+Output Block  39f23369a9d9bacfa530e26304231461 
+Ciphertext 39f23369a9d9bacfa530e26304231461 
+Block #4 
+Plaintext      f69f2445df4f9b17ad2b417be66c3710 
+Input Block     cf6d172c769621d8081ba318e24f2371 
+Output Block  b2eb05e2c39be9fcda6c19078c6a9d1b 
+Ciphertext b2eb05e2c39be9fcda6c19078c6a9d1b
+ F.2.6 CBC-AES256.Decrypt 
+Key 
+  603deb1015ca71be2b73aef0857d7781 
+   1f352c073b6108d72d9810a30914dff4 
+IV 
+  000102030405060708090a0b0c0d0e0f 
+Block #1 
+Ciphertext f58c4c04d6e5f1ba779eabfb5f7bfbd6 
+Input Block     f58c4c04d6e5f1ba779eabfb5f7bfbd6 
+Output Block  6bc0bce12a459991e134741a7f9e1925 
+Plaintext      6bc1bee22e409f96e93d7e117393172a 
+Block #2 
+Ciphertext 9cfc4e967edb808d679f777bc6702c7d 
+Input Block     9cfc4e967edb808d679f777bc6702c7d 
+Output Block  5ba1c653c8e65d26e929c4571ad47587 
+Plaintext      ae2d8a571e03ac9c9eb76fac45af8e51 
+Block #3 
+Ciphertext 39f23369a9d9bacfa530e26304231461 
+Input Block     39f23369a9d9bacfa530e26304231461 
+Output Block  ac3452d0dd87649c8264b662dc7a7e92 
+Plaintext      30c81c46a35ce411e5fbc1191a0a52ef 
+Block #4 
+Ciphertext b2eb05e2c39be9fcda6c19078c6a9d1b 
+Input Block     b2eb05e2c39be9fcda6c19078c6a9d1b 
+Output Block  cf6d172c769621d8081ba318e24f2371 
+Plaintext      f69f2445df4f9b17ad2b417be66c3710 
+*/
diff --git a/testsuite/ctr-test.c b/testsuite/ctr-test.c
new file mode 100644 (file)
index 0000000..15c74d5
--- /dev/null
@@ -0,0 +1,204 @@
+#include "testutils.h"
+#include "aes.h"
+#include "ctr.h"
+
+int
+test_main(void)
+{
+  /* From NIST spec 800-38a on AES modes,
+   *
+   * http://csrc.nist.gov/CryptoToolkit/modes/800-38_Series_Publications/SP800-38A.pdf
+   *
+   * F.5  CTR Example Vectors
+   */
+
+  /* F.5.1  CTR-AES128.Encrypt */
+  test_cipher_ctr(&nettle_aes128,
+                 HL("2b7e151628aed2a6abf7158809cf4f3c"),
+                 HL("6bc1bee22e409f96e93d7e117393172a"
+                    "ae2d8a571e03ac9c9eb76fac45af8e51"
+                    "30c81c46a35ce411e5fbc1191a0a52ef"
+                    "f69f2445df4f9b17ad2b417be66c3710"),
+                 H("874d6191b620e3261bef6864990db6ce"
+                   "9806f66b7970fdff8617187bb9fffdff"
+                   "5ae4df3edbd5d35e5b4f09020db03eab"
+                   "1e031dda2fbe03d1792170a0f3009cee"),
+                 H("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"));
+
+  /* F.5.3  CTR-AES192.Encrypt */
+  test_cipher_ctr(&nettle_aes192,
+                 HL("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
+                 HL("6bc1bee22e409f96e93d7e117393172a"
+                    "ae2d8a571e03ac9c9eb76fac45af8e51"
+                    "30c81c46a35ce411e5fbc1191a0a52ef"
+                    "f69f2445df4f9b17ad2b417be66c3710"),
+                 H("1abc932417521ca24f2b0459fe7e6e0b"
+                    "090339ec0aa6faefd5ccc2c6f4ce8e94"
+                    "1e36b26bd1ebc670d1bd1d665620abf7"
+                    "4f78a7f6d29809585a97daec58c6b050"),
+                 H("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"));
+
+  /* F.5.5  CTR-AES256.Encrypt */
+  test_cipher_ctr(&nettle_aes256,
+                 HL("603deb1015ca71be2b73aef0857d7781"
+                    "1f352c073b6108d72d9810a30914dff4"),
+                 HL("6bc1bee22e409f96e93d7e117393172a"
+                    "ae2d8a571e03ac9c9eb76fac45af8e51"
+                    "30c81c46a35ce411e5fbc1191a0a52ef"
+                    "f69f2445df4f9b17ad2b417be66c3710"),
+                 H("601ec313775789a5b7a7f504bbf3d228"
+                    "f443e3ca4d62b59aca84e990cacaf5c5"
+                    "2b0930daa23de94ce87017ba2d84988d"
+                    "dfc9c58db67aada613c2dd08457941a6"),
+                 H("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"));
+
+  SUCCESS();
+}
+
+/*
+  F.5.1  CTR-AES128.Encrypt
+  Key            2b7e151628aed2a6abf7158809cf4f3c
+  Init. Counter f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
+  Block #1
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
+  Output Block   ec8cdf7398607cb0f2d21675ea9ea1e4
+  Plaintext      6bc1bee22e409f96e93d7e117393172a
+  Ciphertext     874d6191b620e3261bef6864990db6ce
+  Block #2
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdff00
+  Output Block   362b7c3c6773516318a077d7fc5073ae
+  Plaintext      ae2d8a571e03ac9c9eb76fac45af8e51
+  Ciphertext     9806f66b7970fdff8617187bb9fffdff
+  Block #3
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdff01
+  Output Block   6a2cc3787889374fbeb4c81b17ba6c44
+  Plaintext      30c81c46a35ce411e5fbc1191a0a52ef
+  Ciphertext     5ae4df3edbd5d35e5b4f09020db03eab
+  Block #4
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdff02
+  Output Block   e89c399ff0f198c6d40a31db156cabfe
+  Plaintext      f69f2445df4f9b17ad2b417be66c3710
+  Ciphertext     1e031dda2fbe03d1792170a0f3009cee
+  
+  F.5.2  CTR-AES128.Decrypt
+  Key            2b7e151628aed2a6abf7158809cf4f3c
+  Init. Counter f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
+  Block #1
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
+  Output Block   ec8cdf7398607cb0f2d21675ea9ea1e4
+  Ciphertext     874d6191b620e3261bef6864990db6ce
+  Plaintext      6bc1bee22e409f96e93d7e117393172a
+  Block #2
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdff00
+  Output Block   362b7c3c6773516318a077d7fc5073ae
+  Ciphertext     9806f66b7970fdff8617187bb9fffdff
+  Plaintext      ae2d8a571e03ac9c9eb76fac45af8e51
+  Block #3
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdff01
+  Output Block   6a2cc3787889374fbeb4c81b17ba6c44
+  Ciphertext     5ae4df3edbd5d35e5b4f09020db03eab
+  Plaintext      30c81c46a35ce411e5fbc1191a0a52ef
+  Block #4
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdff02
+  Output Block   e89c399ff0f198c6d40a31db156cabfe
+  Ciphertext     1e031dda2fbe03d1792170a0f3009cee
+  Plaintext      f69f2445df4f9b17ad2b417be66c3710
+  
+  F.5.3  CTR-AES192.Encrypt
+  Key            8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b
+  Init. Counter f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
+  Block #1
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
+  Output Block   717d2dc639128334a6167a488ded7921
+  Plaintext      6bc1bee22e409f96e93d7e117393172a
+  Ciphertext     1abc932417521ca24f2b0459fe7e6e0b
+  Block #2
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdff00
+  Output Block   a72eb3bb14a556734b7bad6ab16100c5
+  Plaintext      ae2d8a571e03ac9c9eb76fac45af8e51
+  Ciphertext     090339ec0aa6faefd5ccc2c6f4ce8e94
+  Block #3
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdff01
+  Output Block   2efeae2d72b722613446dc7f4c2af918
+  Plaintext      30c81c46a35ce411e5fbc1191a0a52ef
+  Ciphertext     1e36b26bd1ebc670d1bd1d665620abf7
+  Block #4
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdff02
+  Output Block   b9e783b30dd7924ff7bc9b97beaa8740
+  Plaintext      f69f2445df4f9b17ad2b417be66c3710
+  Ciphertext     4f78a7f6d29809585a97daec58c6b050
+  
+  F.5.4  CTR-AES192.Decrypt
+  Key            8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b
+  Init. Counter f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
+  Block #1
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
+  Output Block   717d2dc639128334a6167a488ded7921
+  Ciphertext     1abc932417521ca24f2b0459fe7e6e0b
+  Plaintext      6bc1bee22e409f96e93d7e117393172a
+  Block #2
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdff00
+  Output Block   a72eb3bb14a556734b7bad6ab16100c5
+  Ciphertext     090339ec0aa6faefd5ccc2c6f4ce8e94
+  Plaintext      ae2d8a571e03ac9c9eb76fac45af8e51
+  Block #3
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdff01
+  Output Block   2efeae2d72b722613446dc7f4c2af918
+  Ciphertext     1e36b26bd1ebc670d1bd1d665620abf7
+  Plaintext      30c81c46a35ce411e5fbc1191a0a52ef
+  Block #4
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdff02
+  Output Block   b9e783b30dd7924ff7bc9b97beaa8740
+  Ciphertext     4f78a7f6d29809585a97daec58c6b050
+  Plaintext      f69f2445df4f9b17ad2b417be66c3710
+  
+  F.5.5  CTR-AES256.Encrypt
+  Key            603deb1015ca71be2b73aef0857d7781
+                 1f352c073b6108d72d9810a30914dff4
+  Init. Counter f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
+  Block #1
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
+  Output Block   0bdf7df1591716335e9a8b15c860c502
+  Plaintext      6bc1bee22e409f96e93d7e117393172a
+  Ciphertext     601ec313775789a5b7a7f504bbf3d228
+  Block #2
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdff00
+  Output Block   5a6e699d536119065433863c8f657b94
+  Plaintext      ae2d8a571e03ac9c9eb76fac45af8e51
+  Ciphertext     f443e3ca4d62b59aca84e990cacaf5c5
+  Block #3
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdff01
+  Output Block   1bc12c9c01610d5d0d8bd6a3378eca62
+  Plaintext      30c81c46a35ce411e5fbc1191a0a52ef
+  Ciphertext     2b0930daa23de94ce87017ba2d84988d
+  Block #4
+  Input Block    f0f1f2f3f4f5f6f7f8f9fafbfcfdff02
+  Output Block   2956e1c8693536b1bee99c73a31576b6
+  Plaintext      f69f2445df4f9b17ad2b417be66c3710
+  Ciphertext     dfc9c58db67aada613c2dd08457941a6
+  
+  F.5.6  CTR-AES256.Decrypt
+  Key            603deb1015ca71be2b73aef0857d7781
+                 1f352c073b6108d72d9810a30914dff4
+  Init. Counter f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
+  Block #1
+  Input Block  f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
+  Output Block 0bdf7df1591716335e9a8b15c860c502
+  Ciphertext   601ec313775789a5b7a7f504bbf3d228
+  Plaintext    6bc1bee22e409f96e93d7e117393172a
+  Block #2
+  Input Block  f0f1f2f3f4f5f6f7f8f9fafbfcfdff00
+  Output Block 5a6e699d536119065433863c8f657b94
+  Ciphertext   f443e3ca4d62b59aca84e990cacaf5c5
+  Plaintext    ae2d8a571e03ac9c9eb76fac45af8e51
+  Block #3
+  Input Block  f0f1f2f3f4f5f6f7f8f9fafbfcfdff01
+  Output Block 1bc12c9c01610d5d0d8bd6a3378eca62
+  Ciphertext   2b0930daa23de94ce87017ba2d84988d
+  Plaintext    30c81c46a35ce411e5fbc1191a0a52ef
+  Block #4
+  Input Block  f0f1f2f3f4f5f6f7f8f9fafbfcfdff02
+  Output Block 2956e1c8693536b1bee99c73a31576b6
+  Ciphertext   dfc9c58db67aada613c2dd08457941a6
+  Plaintext    f69f2445df4f9b17ad2b417be66c3710
+*/
diff --git a/testsuite/cxx-test.cxx b/testsuite/cxx-test.cxx
new file mode 100644 (file)
index 0000000..b5635fb
--- /dev/null
@@ -0,0 +1,108 @@
+/* For FILE, used by gmp.h */
+#include <cstdio>
+
+#include "testutils.h"
+#include "md5.h"
+
+/* Test C++ linkage */
+int
+test_main(void)
+{
+  struct md5_ctx md5;
+  uint8_t digest[MD5_DIGEST_SIZE];
+
+  md5_init (&md5);
+  md5_update (&md5, 14, reinterpret_cast<const uint8_t *> ("message digest"));
+  md5_digest (&md5, MD5_DIGEST_SIZE, digest);
+
+  if (!MEMEQH (MD5_DIGEST_SIZE, digest,
+              "F96B697D7CB7938D 525A2F31AAF161D0"))
+    FAIL();
+
+#if WITH_PUBLIC_KEY
+
+  struct rsa_public_key pub;
+  struct rsa_private_key key;
+
+  mpz_t expected;
+  
+  mpz_init(expected);
+  
+  rsa_private_key_init(&key);
+  rsa_public_key_init(&pub);
+
+  mpz_set_str(pub.n,
+             "69abd505285af665" "36ddc7c8f027e6f0" "ed435d6748b16088"
+             "4fd60842b3a8d7fb" "bd8a3c98f0cc50ae" "4f6a9f7dd73122cc"
+             "ec8afa3f77134406" "f53721973115fc2d" "8cfbba23b145f28d"
+             "84f81d3b6ae8ce1e" "2850580c026e809b" "cfbb52566ea3a3b3"
+             "df7edf52971872a7" "e35c1451b8636d22" "279a8fb299368238"
+             "e545fbb4cf", 16);
+  mpz_set_str(pub.e, "0db2ad57", 16);
+
+  if (!rsa_public_key_prepare(&pub))
+    FAIL();
+
+  mpz_set_str(key.p,
+             "0a66399919be4b4d" "e5a78c5ea5c85bf9" "aba8c013cb4a8732"
+             "14557a12bd67711e" "bb4073fd39ad9a86" "f4e80253ad809e5b"
+             "f2fad3bc37f6f013" "273c9552c9f489", 16);
+
+  mpz_set_str(key.q,
+             "0a294f069f118625" "f5eae2538db9338c" "776a298eae953329"
+             "9fd1eed4eba04e82" "b2593bc98ba8db27" "de034da7daaea795"
+             "2d55b07b5f9a5875" "d1ca5f6dcab897", 16);
+  
+  mpz_set_str(key.a,
+             "011b6c48eb592eee" "e85d1bb35cfb6e07" "344ea0b5e5f03a28"
+             "5b405396cbc78c5c" "868e961db160ba8d" "4b984250930cf79a"
+             "1bf8a9f28963de53" "128aa7d690eb87", 16);
+  
+  mpz_set_str(key.b,
+             "0409ecf3d2557c88" "214f1af5e1f17853" "d8b2d63782fa5628"
+             "60cf579b0833b7ff" "5c0529f2a97c6452" "2fa1a8878a9635ab"
+             "ce56debf431bdec2" "70b308fa5bf387", 16);
+  
+  mpz_set_str(key.c,
+             "04e103ee925cb5e6" "6653949fa5e1a462" "c9e65e1adcd60058"
+             "e2df9607cee95fa8" "daec7a389a7d9afc" "8dd21fef9d83805a"
+             "40d46f49676a2f6b" "2926f70c572c00", 16);
+
+  if (!rsa_private_key_prepare(&key))
+    FAIL();
+
+  if (pub.size != key.size)
+    FAIL();
+  
+  mpz_set_str(expected,
+             "53bf517009fa956e" "3daa6adc95e8663d" "3759002f488bbbad"
+             "e49f62792d85dbcc" "293f68e2b68ef89a" "c5bd42d98f845325"
+             "3e6c1b76fc337db5" "e0053f255c55faf3" "eb6cc568ad7f5013"
+             "5b269a64acb9eaa7" "b7f09d9bd90310e6" "4c58f6dbe673ada2"
+             "67c97a9d99e19f9d" "87960d9ce3f0d5ce" "84f401fe7e10fa24"
+             "28b9bffcf9", 16);
+
+  mpz_t signature;
+  mpz_init(signature);
+
+  /* Create signature */
+  md5_update (&md5, 39, reinterpret_cast<const uint8_t *>
+             ("The magic words are squeamish ossifrage"));
+  ASSERT (rsa_md5_sign (&key, &md5, signature));
+
+  /* Verify it */
+  md5_update (&md5, 39, reinterpret_cast<const uint8_t *>
+             ("The magic words are squeamish ossifrage"));
+  if (!rsa_md5_verify (&pub, &md5, signature))
+    FAIL();
+
+  /* Try bad data */
+  md5_update (&md5, 39, reinterpret_cast<const uint8_t *>
+             ("The magik words are squeamish ossifrage"));
+  if (rsa_md5_verify (&pub, &md5, signature))
+    FAIL();
+  
+#endif /* WITH_PUBLIC_KEY */
+
+  SUCCESS();
+}
diff --git a/testsuite/des-compat-test.c b/testsuite/des-compat-test.c
new file mode 100644 (file)
index 0000000..c820c4e
--- /dev/null
@@ -0,0 +1,874 @@
+/* crypto/des/destest.c */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 THE AUTHOR 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.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "des-compat.h"
+#include "testutils.h"
+
+/* tisk tisk - the test keys don't all have odd parity :-( */
+/* test data */
+#define NUM_TESTS 34
+static const_des_cblock key_data[NUM_TESTS] = {
+       {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+       {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+       {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+       {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+       {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+       {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+       {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+       {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10},
+       {0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57},
+       {0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E},
+       {0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86},
+       {0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E},
+       {0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6},
+       {0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE},
+       {0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6},
+       {0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE},
+       {0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16},
+       {0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F},
+       {0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46},
+       {0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E},
+       {0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76},
+       {0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07},
+       {0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F},
+       {0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7},
+       {0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF},
+       {0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6},
+       {0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF},
+       {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
+       {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
+       {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
+       {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+       {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+       {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+       {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}};
+
+static unsigned char plain_data[NUM_TESTS][8]={
+       {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+       {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+       {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
+       {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+       {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+       {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+       {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+       {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+       {0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42},
+       {0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA},
+       {0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72},
+       {0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A},
+       {0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2},
+       {0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A},
+       {0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2},
+       {0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A},
+       {0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02},
+       {0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A},
+       {0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32},
+       {0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA},
+       {0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62},
+       {0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2},
+       {0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA},
+       {0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92},
+       {0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A},
+       {0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2},
+       {0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A},
+       {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+       {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+       {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+       {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+       {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+       {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+       {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
+
+static unsigned char cipher_data[NUM_TESTS][8]={
+       {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
+       {0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58},
+       {0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B},
+       {0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33},
+       {0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D},
+       {0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD},
+       {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
+       {0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4},
+       {0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B},
+       {0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71},
+       {0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A},
+       {0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A},
+       {0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95},
+       {0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B},
+       {0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09},
+       {0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A},
+       {0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F},
+       {0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88},
+       {0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77},
+       {0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A},
+       {0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56},
+       {0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56},
+       {0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56},
+       {0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC},
+       {0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A},
+       {0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41},
+       {0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93},
+       {0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00},
+       {0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06},
+       {0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7},
+       {0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51},
+       {0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE},
+       {0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D},
+       {0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}};
+
+static unsigned char cipher_ecb2[NUM_TESTS-1][8]={
+       {0x92,0x95,0xB5,0x9B,0xB3,0x84,0x73,0x6E},
+       {0x19,0x9E,0x9D,0x6D,0xF3,0x9A,0xA8,0x16},
+       {0x2A,0x4B,0x4D,0x24,0x52,0x43,0x84,0x27},
+       {0x35,0x84,0x3C,0x01,0x9D,0x18,0xC5,0xB6},
+       {0x4A,0x5B,0x2F,0x42,0xAA,0x77,0x19,0x25},
+       {0xA0,0x6B,0xA9,0xB8,0xCA,0x5B,0x17,0x8A},
+       {0xAB,0x9D,0xB7,0xFB,0xED,0x95,0xF2,0x74},
+       {0x3D,0x25,0x6C,0x23,0xA7,0x25,0x2F,0xD6},
+       {0xB7,0x6F,0xAB,0x4F,0xBD,0xBD,0xB7,0x67},
+       {0x8F,0x68,0x27,0xD6,0x9C,0xF4,0x1A,0x10},
+       {0x82,0x57,0xA1,0xD6,0x50,0x5E,0x81,0x85},
+       {0xA2,0x0F,0x0A,0xCD,0x80,0x89,0x7D,0xFA},
+       {0xCD,0x2A,0x53,0x3A,0xDB,0x0D,0x7E,0xF3},
+       {0xD2,0xC2,0xBE,0x27,0xE8,0x1B,0x68,0xE3},
+       {0xE9,0x24,0xCF,0x4F,0x89,0x3C,0x5B,0x0A},
+       {0xA7,0x18,0xC3,0x9F,0xFA,0x9F,0xD7,0x69},
+       {0x77,0x2C,0x79,0xB1,0xD2,0x31,0x7E,0xB1},
+       {0x49,0xAB,0x92,0x7F,0xD0,0x22,0x00,0xB7},
+       {0xCE,0x1C,0x6C,0x7D,0x85,0xE3,0x4A,0x6F},
+       {0xBE,0x91,0xD6,0xE1,0x27,0xB2,0xE9,0x87},
+       {0x70,0x28,0xAE,0x8F,0xD1,0xF5,0x74,0x1A},
+       {0xAA,0x37,0x80,0xBB,0xF3,0x22,0x1D,0xDE},
+       {0xA6,0xC4,0xD2,0x5E,0x28,0x93,0xAC,0xB3},
+       {0x22,0x07,0x81,0x5A,0xE4,0xB7,0x1A,0xAD},
+       {0xDC,0xCE,0x05,0xE7,0x07,0xBD,0xF5,0x84},
+       {0x26,0x1D,0x39,0x2C,0xB3,0xBA,0xA5,0x85},
+       {0xB4,0xF7,0x0F,0x72,0xFB,0x04,0xF0,0xDC},
+       {0x95,0xBA,0xA9,0x4E,0x87,0x36,0xF2,0x89},
+       {0xD4,0x07,0x3A,0xF1,0x5A,0x17,0x82,0x0E},
+       {0xEF,0x6F,0xAF,0xA7,0x66,0x1A,0x7E,0x89},
+       {0xC1,0x97,0xF5,0x58,0x74,0x8A,0x20,0xE7},
+       {0x43,0x34,0xCF,0xDA,0x22,0xC4,0x86,0xC8},
+       {0x08,0xD7,0xB4,0xFB,0x62,0x9D,0x08,0x85}};
+
+static const_des_cblock cbc_key = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static const_des_cblock cbc2_key = {0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87};
+static const_des_cblock cbc3_key = {0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
+static const_des_cblock cbc_iv = {0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
+static const_des_cblock cbc_data[4] ={ "7654321 ", "Now is t", "he time ", "for " };
+
+static unsigned char cbc_ok[32]={
+       0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
+       0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb,
+       0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68,
+       0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
+
+#if 0
+static unsigned char xcbc_ok[32]={
+       0x86,0x74,0x81,0x0D,0x61,0xA4,0xA5,0x48,
+       0xB9,0x93,0x03,0xE1,0xB8,0xBB,0xBD,0xBD,
+       0x64,0x30,0x0B,0xB9,0x06,0x65,0x81,0x76,
+       0x04,0x1D,0x77,0x62,0x17,0xCA,0x2B,0xD2,
+       };
+#endif
+
+static unsigned char cbc3_ok[32]={
+       0x3F,0xE3,0x01,0xC9,0x62,0xAC,0x01,0xD0,
+       0x22,0x13,0x76,0x3C,0x1C,0xBD,0x4C,0xDC,
+       0x79,0x96,0x57,0xC0,0x64,0xEC,0xF5,0xD4,
+       0x1C,0x67,0x38,0x12,0xCF,0xDE,0x96,0x75};
+
+#if 0
+static unsigned char pcbc_ok[32]={
+       0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
+       0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15,
+       0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f,
+       0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88};
+#endif
+
+#if 0
+static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
+static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
+static unsigned char plain[24]=
+       {
+       0x4e,0x6f,0x77,0x20,0x69,0x73,
+       0x20,0x74,0x68,0x65,0x20,0x74,
+       0x69,0x6d,0x65,0x20,0x66,0x6f,
+       0x72,0x20,0x61,0x6c,0x6c,0x20
+       };
+static unsigned char cfb_cipher8[24]= {
+       0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8,
+       0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87 };
+static unsigned char cfb_cipher16[24]={
+       0xF3,0x09,0x87,0x87,0x7F,0x57, 0xF7,0x3C,0x36,0xB6,0xDB,0x70,
+       0xD8,0xD5,0x34,0x19,0xD3,0x86, 0xB2,0x23,0xB7,0xB2,0xAD,0x1B };
+static unsigned char cfb_cipher32[24]={
+       0xF3,0x09,0x62,0x49,0xA4,0xDF, 0xA4,0x9F,0x33,0xDC,0x7B,0xAD,
+       0x4C,0xC8,0x9F,0x64,0xE4,0x53, 0xE5,0xEC,0x67,0x20,0xDA,0xB6 };
+static unsigned char cfb_cipher48[24]={
+       0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x30,0xB5,0x15,0xEC,0xBB,0x85,
+       0x97,0x5A,0x13,0x8C,0x68,0x60, 0xE2,0x38,0x34,0x3C,0xDC,0x1F };
+static unsigned char cfb_cipher64[24]={
+       0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x6E,0x51,0xA6,0x9E,0x83,0x9B,
+       0x1A,0x92,0xF7,0x84,0x03,0x46, 0x71,0x33,0x89,0x8E,0xA6,0x22 };
+
+static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
+static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8];
+static unsigned char ofb_cipher[24]=
+       {
+       0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51,
+       0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f,
+       0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3
+       };
+#endif
+
+DES_LONG cbc_cksum_ret=0xB462FEF7L;
+unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
+
+#ifndef NOPROTO
+static char *pt(const unsigned char *p);
+static int cfb_test(int bits, unsigned char *cfb_cipher);
+static int cfb64_test(unsigned char *cfb_cipher);
+static int ede_cfb64_test(unsigned char *cfb_cipher);
+#else
+static char *pt();
+static int cfb_test();
+static int cfb64_test();
+static int ede_cfb64_test();
+#endif
+
+int
+test_main(void)
+       {
+       int i,j,err=0;
+       des_cblock in, out, outin, iv3;
+       des_key_schedule ks,ks2,ks3;
+       des_cblock cbc_in[5];
+       des_cblock cbc_out[5];
+       DES_LONG cs;
+       unsigned char qret[4][4],cret[8];
+       DES_LONG lqret[4];
+       int num;
+       char *str;
+
+       printf("Doing ecb\n");
+       for (i=0; i<NUM_TESTS; i++)
+               {
+               if ((j=des_key_sched(&key_data[i], ks)) != 0)
+                       {
+                       printf("Key error %2d:%d\n",i+1,j);
+                       err=1;
+                       }
+               memcpy(in,plain_data[i],8);
+               memset(out,0,8);
+               memset(outin,0,8);
+               des_ecb_encrypt(&in, &out, ks, DES_ENCRYPT);
+               des_ecb_encrypt(&out, &outin, ks, DES_DECRYPT);
+
+               if (memcmp(out,cipher_data[i],8) != 0)
+                       {
+                       printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
+                               i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]),
+                               pt(out));
+                       err=1;
+                       }
+               if (memcmp(in,outin,8) != 0)
+                       {
+                       printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
+                               i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
+                       err=1;
+                       }
+               }
+
+#ifndef LIBDES_LIT
+       printf("Doing ede ecb\n");
+       for (i=0; i<(NUM_TESTS-1); i++)
+               {
+               if ((j=des_key_sched(&key_data[i], ks)) != 0)
+                       {
+                       err=1;
+                       printf("Key error %2d:%d\n",i+1,j);
+                       }
+               if ((j=des_key_sched(&key_data[i+1],ks2)) != 0)
+                       {
+                       printf("Key error %2d:%d\n",i+2,j);
+                       err=1;
+                       }
+               if ((j=des_key_sched(&key_data[i+2],ks3)) != 0)
+                       {
+                       printf("Key error %2d:%d\n",i+3,j);
+                       err=1;
+                       }
+               memcpy(in,plain_data[i],8);
+               memset(out,0,8);
+               memset(outin,0,8);
+               des_ecb2_encrypt(&in, &out, ks, ks2,
+                       DES_ENCRYPT);
+               des_ecb2_encrypt(&out, &outin, ks, ks2,
+                       DES_DECRYPT);
+
+               if (memcmp(out,cipher_ecb2[i],8) != 0)
+                       {
+                       printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
+                               i+1,pt(key_data[i]),pt(in),pt(cipher_ecb2[i]),
+                               pt(out));
+                       err=1;
+                       }
+               if (memcmp(in,outin,8) != 0)
+                       {
+                       printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
+                               i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
+                       err=1;
+                       }
+               }
+#endif
+
+       printf("Doing cbc\n");
+       if ((j=des_key_sched(&cbc_key, ks)) != 0)
+               {
+               printf("Key error %d\n",j);
+               err=1;
+               }
+       memset(cbc_out,0,sizeof(cbc_data));
+       memset(cbc_in,0,sizeof(cbc_data));
+       memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+       des_ncbc_encrypt(cbc_data, cbc_out,
+               sizeof(cbc_data), ks,
+               &iv3, DES_ENCRYPT);
+       if (memcmp(cbc_out,cbc_ok,32) != 0)
+               printf("cbc_encrypt encrypt error\n");
+
+       memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+       des_ncbc_encrypt(cbc_out, cbc_in,
+               sizeof(cbc_data),ks,
+               &iv3,DES_DECRYPT);
+       if (memcmp(cbc_in,cbc_data,sizeof(cbc_data)) != 0)
+               {
+               printf("cbc_encrypt decrypt error\n");
+               err=1;
+               }
+
+#ifndef LIBDES_LIT
+#if 0
+       printf("Doing desx cbc\n");
+       if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
+               {
+               printf("Key error %d\n",j);
+               err=1;
+               }
+       memset(cbc_out,0,sizeof(cbc_data));
+       memset(cbc_in,0,sizeof(cbc_data));
+       memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+       des_xcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
+               sizeof(cbc_data), ks,
+               (C_Block *)iv3,
+               (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_ENCRYPT);
+       if (memcmp(cbc_out,xcbc_ok,32) != 0)
+               {
+               printf("des_xcbc_encrypt encrypt error\n");
+               }
+       memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+       des_xcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
+               sizeof(cbc_data), ks,
+               (C_Block *)iv3,
+               (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_DECRYPT);
+       if (memcmp(cbc_in,cbc_data,sizeof(cbc_data)) != 0)
+               {
+               printf("des_xcbc_encrypt decrypt error\n");
+               err=1;
+               }
+#endif
+#endif /* LIBDES_LIT */
+
+       printf("Doing ede cbc\n");
+       if ((j=des_key_sched(&cbc_key,ks)) != 0)
+               {
+               printf("Key error %d\n",j);
+               err=1;
+               }
+       if ((j=des_key_sched(&cbc2_key,ks2)) != 0)
+               {
+               printf("Key error %d\n",j);
+               err=1;
+               }
+       if ((j=des_key_sched(&cbc3_key,ks3)) != 0)
+               {
+               printf("Key error %d\n",j);
+               err=1;
+               }
+       memset(cbc_out,0,sizeof(cbc_data));
+       memset(cbc_in,0,sizeof(cbc_data));
+       i=sizeof(cbc_data);
+       /* i=((i+7)/8)*8; */
+       memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+
+       des_ede3_cbc_encrypt( cbc_data, cbc_out,
+               16L, ks, ks2, ks3, &iv3, DES_ENCRYPT);
+       des_ede3_cbc_encrypt( &cbc_data[2],
+               &cbc_out[2],
+               (long)i-16, ks, ks2, ks3, &iv3, DES_ENCRYPT);
+       if (memcmp(cbc_out,cbc3_ok, sizeof(cbc_data)) != 0)
+               {
+               printf("des_ede3_cbc_encrypt encrypt error\n");
+               err=1;
+               }
+
+       memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+       des_ede3_cbc_encrypt(cbc_out, cbc_in,
+               (long)i, ks, ks2, ks3, &iv3, DES_DECRYPT);
+       if (memcmp(cbc_in,cbc_data,sizeof(cbc_data)) != 0)
+               {
+               printf("des_ede3_cbc_encrypt decrypt error\n");
+               err=1;
+               }
+
+#ifndef LIBDES_LIT
+#if 0
+       printf("Doing pcbc\n");
+       if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
+               {
+               printf("Key error %d\n",j);
+               err=1;
+               }
+       memset(cbc_out,0,sizeof(cbc_data));
+       memset(cbc_in,0,sizeof(cbc_data));
+       des_pcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
+               sizeof(cbc_data),ks,(C_Block *)cbc_iv,DES_ENCRYPT);
+       if (memcmp(cbc_out,pcbc_ok,32) != 0)
+               {
+               printf("pcbc_encrypt encrypt error\n");
+               err=1;
+               }
+       des_pcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
+               sizeof(cbc_data),ks,(C_Block *)cbc_iv,DES_DECRYPT);
+       if (memcmp(cbc_in,cbc_data,sizeof(cbc_data)) != 0)
+               {
+               printf("pcbc_encrypt decrypt error\n");
+               err=1;
+               }
+
+       printf("Doing ");
+       printf("cfb8 ");
+       err+=cfb_test(8,cfb_cipher8);
+       printf("cfb16 ");
+       err+=cfb_test(16,cfb_cipher16);
+       printf("cfb32 ");
+       err+=cfb_test(32,cfb_cipher32);
+       printf("cfb48 ");
+       err+=cfb_test(48,cfb_cipher48);
+       printf("cfb64 ");
+       err+=cfb_test(64,cfb_cipher64);
+
+       printf("cfb64() ");
+       err+=cfb64_test(cfb_cipher64);
+
+       memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+       for (i=0; i<sizeof(plain); i++)
+               des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]),
+                       8,(long)1,ks,(C_Block *)cfb_tmp,DES_ENCRYPT);
+       if (memcmp(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0)
+               {
+               printf("cfb_encrypt small encrypt error\n");
+               err=1;
+               }
+
+       memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+       for (i=0; i<sizeof(plain); i++)
+               des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]),
+                       8,(long)1,ks,(C_Block *)cfb_tmp,DES_DECRYPT);
+       if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+               {
+               printf("cfb_encrypt small decrypt error\n");
+               err=1;
+               }
+
+       printf("ede_cfb64() ");
+       err+=ede_cfb64_test(cfb_cipher64);
+
+       printf("done\n");
+
+       printf("Doing ofb\n");
+       des_key_sched((C_Block *)ofb_key,ks);
+       memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+       des_ofb_encrypt(plain,ofb_buf1,64,(long)sizeof(plain)/8,ks,
+               (C_Block *)ofb_tmp);
+       if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
+               {
+               printf("ofb_encrypt encrypt error\n");
+porintf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
+ofb_buf1[8+0], ofb_buf1[8+1], ofb_buf1[8+2], ofb_buf1[8+3],
+ofb_buf1[8+4], ofb_buf1[8+5], ofb_buf1[8+6], ofb_buf1[8+7]);
+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
+ofb_buf1[8+0], ofb_cipher[8+1], ofb_cipher[8+2], ofb_cipher[8+3],
+ofb_buf1[8+4], ofb_cipher[8+5], ofb_cipher[8+6], ofb_cipher[8+7]);
+               err=1;
+               }
+       memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+       des_ofb_encrypt(ofb_buf1,ofb_buf2,64,(long)sizeof(ofb_buf1)/8,ks,
+               (C_Block *)ofb_tmp);
+       if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
+               {
+               printf("ofb_encrypt decrypt error\n");
+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
+ofb_buf2[8+0], ofb_buf2[8+1], ofb_buf2[8+2], ofb_buf2[8+3],
+ofb_buf2[8+4], ofb_buf2[8+5], ofb_buf2[8+6], ofb_buf2[8+7]);
+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
+plain[8+0], plain[8+1], plain[8+2], plain[8+3],
+plain[8+4], plain[8+5], plain[8+6], plain[8+7]);
+               err=1;
+               }
+
+       printf("Doing ofb64\n");
+       des_key_sched((C_Block *)ofb_key,ks);
+       memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+       memset(ofb_buf1,0,sizeof(ofb_buf1));
+       memset(ofb_buf2,0,sizeof(ofb_buf1));
+       num=0;
+       for (i=0; i<sizeof(plain); i++)
+               {
+               des_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,
+                       (C_Block *)ofb_tmp,&num);
+               }
+       if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
+               {
+               printf("ofb64_encrypt encrypt error\n");
+               err=1;
+               }
+       memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+       num=0;
+       des_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks,
+               (C_Block *)ofb_tmp,&num);
+       if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
+               {
+               printf("ofb64_encrypt decrypt error\n");
+               err=1;
+               }
+
+       printf("Doing ede_ofb64\n");
+       des_key_sched((C_Block *)ofb_key,ks);
+       memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+       memset(ofb_buf1,0,sizeof(ofb_buf1));
+       memset(ofb_buf2,0,sizeof(ofb_buf1));
+       num=0;
+       for (i=0; i<sizeof(plain); i++)
+               {
+               des_ede3_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,ks,ks,
+                       (C_Block *)ofb_tmp,&num);
+               }
+       if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
+               {
+               printf("ede_ofb64_encrypt encrypt error\n");
+               err=1;
+               }
+       memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+       num=0;
+       des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks,
+               ks,ks,(C_Block *)ofb_tmp,&num);
+       if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
+               {
+               printf("ede_ofb64_encrypt decrypt error\n");
+               err=1;
+               }
+#endif
+        
+       printf("Doing cbc_cksum\n");
+       des_key_sched(&cbc_key,ks);
+       cs=des_cbc_cksum(cbc_data[0], &cret,
+               sizeof(cbc_data), ks, &cbc_iv);
+       if (cs != cbc_cksum_ret)
+               {
+               printf("bad return value (%08lX), should be %08lX\n",
+                       (unsigned long)cs,(unsigned long)cbc_cksum_ret);
+               err=1;
+               }
+       if (memcmp(cret,cbc_cksum_data,8) != 0)
+               {
+               printf("bad cbc_cksum block returned\n");
+               err=1;
+               }
+
+#if 0
+       printf("Doing quad_cksum\n");
+       cs=quad_cksum((C_Block *)cbc_data,(C_Block *)qret,
+               sizeof(cbc_data),2,(C_Block *)cbc_iv);
+       for (i=0; i<4; i++)
+               {
+               lqret[i]=0;
+               memcpy(&(lqret[i]),&(qret[i][0]),4);
+               }
+       { /* Big-endian fix */
+       static DES_LONG l=1;
+       static unsigned char *c=(unsigned char *)&l;
+       DES_LONG ll;
+
+       if (!c[0])
+               {
+               ll=lqret[0]^lqret[3];
+               lqret[0]^=ll;
+               lqret[3]^=ll;
+               ll=lqret[1]^lqret[2];
+               lqret[1]^=ll;
+               lqret[2]^=ll;
+               }
+       }
+       if (cs != 0x70d7a63aL)
+               {
+               printf("quad_cksum error, ret %08lx should be 70d7a63a\n",
+                       (unsigned long)cs);
+               err=1;
+               }
+       if (lqret[0] != 0x327eba8dL)
+               {
+               printf("quad_cksum error, out[0] %08lx is not %08lx\n",
+                       (unsigned long)lqret[0],0x327eba8dL);
+               err=1;
+               }
+       if (lqret[1] != 0x201a49ccL)
+               {
+               printf("quad_cksum error, out[1] %08lx is not %08lx\n",
+                       (unsigned long)lqret[1],0x201a49ccL);
+               err=1;
+               }
+       if (lqret[2] != 0x70d7a63aL)
+               {
+               printf("quad_cksum error, out[2] %08lx is not %08lx\n",
+                       (unsigned long)lqret[2],0x70d7a63aL);
+               err=1;
+               }
+       if (lqret[3] != 0x501c2c26L)
+               {
+               printf("quad_cksum error, out[3] %08lx is not %08lx\n",
+                       (unsigned long)lqret[3],0x501c2c26L);
+               err=1;
+               }
+#endif
+#endif /* LIBDES_LIT */
+#if 0
+       printf("input word alignment test");
+       for (i=0; i<4; i++)
+               {
+               printf(" %d",i);
+               des_ncbc_encrypt( (des_cblock *) &(cbc_out[i]), (des_cblock *) cbc_in,
+                       sizeof(cbc_data), ks, &cbc_iv,
+                       DES_ENCRYPT);
+               }
+       printf("\noutput word alignment test");
+       for (i=0; i<4; i++)
+               {
+               printf(" %d",i);
+               des_ncbc_encrypt( (des_cblock *) cbc_out, (des_cblock *) &(cbc_in[i]),
+                       sizeof(cbc_data), ks, &cbc_iv,
+                       DES_ENCRYPT);
+               }
+       printf("\n");
+
+       printf("fast crypt test ");
+       str=crypt("testing","ef");
+       if (strcmp("efGnQx2725bI2",str) != 0)
+               {
+               printf("fast crypt error, %s should be efGnQx2725bI2\n",str);
+               err=1;
+               }
+       str=crypt("bca76;23","yA");
+       if (strcmp("yA1Rp/1hZXIJk",str) != 0)
+               {
+               printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str);
+               err=1;
+               }
+       printf("\n");
+#endif
+       exit(err);
+       return(0);
+       }
+
+static char *pt(p)
+const unsigned char *p;
+       {
+       static char bufs[10][20];
+       static int bnum=0;
+       char *ret;
+       int i;
+       static char *f="0123456789ABCDEF";
+
+       ret= &(bufs[bnum++][0]);
+       bnum%=10;
+       for (i=0; i<8; i++)
+               {
+               ret[i*2]=f[(p[i]>>4)&0xf];
+               ret[i*2+1]=f[p[i]&0xf];
+               }
+       ret[16]='\0';
+       return(ret);
+       }
+
+#ifndef LIBDES_LIT
+#if 0
+static int cfb_test(bits, cfb_cipher)
+int bits;
+unsigned char *cfb_cipher;
+       {
+       des_key_schedule ks;
+       int i,err=0;
+
+       des_key_sched((C_Block *)cfb_key,ks);
+       memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+       des_cfb_encrypt(plain,cfb_buf1,bits,(long)sizeof(plain),ks,
+               (C_Block *)cfb_tmp,DES_ENCRYPT);
+       if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
+               {
+               err=1;
+               printf("cfb_encrypt encrypt error\n");
+               for (i=0; i<24; i+=8)
+                       printf("%s\n",pt(&(cfb_buf1[i])));
+               }
+       memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+       des_cfb_encrypt(cfb_buf1,cfb_buf2,bits,(long)sizeof(plain),ks,
+               (C_Block *)cfb_tmp,DES_DECRYPT);
+       if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+               {
+               err=1;
+               printf("cfb_encrypt decrypt error\n");
+               for (i=0; i<24; i+=8)
+                       printf("%s\n",pt(&(cfb_buf1[i])));
+               }
+       return(err);
+       }
+
+static int cfb64_test(cfb_cipher)
+unsigned char *cfb_cipher;
+       {
+       des_key_schedule ks;
+       int err=0,i,n;
+
+       des_key_sched((C_Block *)cfb_key,ks);
+       memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+       n=0;
+       des_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,
+               (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
+       des_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
+               (long)sizeof(plain)-12,ks,
+               (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
+       if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
+               {
+               err=1;
+               printf("cfb_encrypt encrypt error\n");
+               for (i=0; i<24; i+=8)
+                       printf("%s\n",pt(&(cfb_buf1[i])));
+               }
+       memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+       n=0;
+       des_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,
+               (C_Block *)cfb_tmp,&n,DES_DECRYPT);
+       des_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
+               (long)sizeof(plain)-17,ks,
+               (C_Block *)cfb_tmp,&n,DES_DECRYPT);
+       if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+               {
+               err=1;
+               printf("cfb_encrypt decrypt error\n");
+               for (i=0; i<24; i+=8)
+                       printf("%s\n",pt(&(cfb_buf2[i])));
+               }
+       return(err);
+       }
+
+static int ede_cfb64_test(cfb_cipher)
+unsigned char *cfb_cipher;
+       {
+       des_key_schedule ks;
+       int err=0,i,n;
+
+       des_key_sched((C_Block *)cfb_key,ks);
+       memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+       n=0;
+       des_ede3_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,ks,ks,
+               (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
+       des_ede3_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
+               (long)sizeof(plain)-12,ks,ks,ks,
+               (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
+       if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
+               {
+               err=1;
+               printf("ede_cfb_encrypt encrypt error\n");
+               for (i=0; i<24; i+=8)
+                       printf("%s\n",pt(&(cfb_buf1[i])));
+               }
+       memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+       n=0;
+       des_ede3_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,ks,ks,
+               (C_Block *)cfb_tmp,&n,DES_DECRYPT);
+       des_ede3_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
+               (long)sizeof(plain)-17,ks,ks,ks,
+               (C_Block *)cfb_tmp,&n,DES_DECRYPT);
+       if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+               {
+               err=1;
+               printf("ede_cfb_encrypt decrypt error\n");
+               for (i=0; i<24; i+=8)
+                       printf("%s\n",pt(&(cfb_buf2[i])));
+               }
+       return(err);
+       }
+#endif
+#endif /* LIBDES_LIT */
+
diff --git a/testsuite/des-test.c b/testsuite/des-test.c
new file mode 100644 (file)
index 0000000..244e5aa
--- /dev/null
@@ -0,0 +1,122 @@
+#include "testutils.h"
+#include "nettle-internal.h"
+#include "des.h"
+
+static void
+test_des(const uint8_t *key, int expected_parity,
+        unsigned length,
+        const uint8_t *cleartext,
+        const uint8_t *ciphertext)
+{
+  struct des_ctx ctx;
+  uint8_t *data = xalloc(length);
+
+  if (des_check_parity(8, key) != expected_parity)
+    FAIL();
+
+  if (!des_set_key(&ctx, key))
+    FAIL();
+
+  des_encrypt(&ctx, length, data, cleartext);
+
+  if (!MEMEQ(length, data, ciphertext))
+    {
+      fprintf(stderr, "Encrypt failed:\nInput:");
+      print_hex(length, cleartext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      print_hex(length, ciphertext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+
+  des_decrypt(&ctx, length, data, data);
+
+  if (!MEMEQ(length, data, cleartext))
+    {
+      fprintf(stderr, "Decrypt failed:\nInput:");
+      print_hex(length, ciphertext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      print_hex(length, cleartext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+
+  free(data);
+}
+
+static void
+test_weak(const uint8_t *key)
+{
+  struct des_ctx ctx;
+
+  if (des_set_key(&ctx, key))
+    FAIL();
+}
+
+int
+test_main(void)
+{
+  /* From Applied Cryptography */
+  test_des(H("01234567 89ABCDEF"), 1,
+          HL("01234567 89ABCDE7"),
+          H("C9574425 6A5ED31D"));
+
+  test_des(H("01 01 01 01 01 01 01 80"), 1,
+          HL("00 00 00 00 00 00 00 00"),
+          H("9C C6 2D F4 3B 6E ED 74"));
+
+  test_des(H("80 01 01 01 01 01 01 01"), 1,
+          HL("00 00 00 00 00 00 00 40"),
+          H("A3 80 E0 2A 6B E5 46 96"));
+
+  test_des(H("08 19 2A 3B 4C 5D 6E 7F"), 1,
+          HL("00 00 00 00 00 00 00 00"),
+          H("25 DD AC 3E 96 17 64 67"));
+
+  test_des(H("01 23 45 67 89 AB CD EF"), 1,
+          DES_BLOCK_SIZE, "Now is t",
+          H("3F A4 0E 8A 98 4D 48 15"));
+
+  /* Same key, but with one bad parity bit, */
+  test_des(H("01 23 45 66 89 AB CD EF"), 0,
+          DES_BLOCK_SIZE, "Now is t",
+          H("3F A4 0E 8A 98 4D 48 15"));
+
+  /* Parity check */
+  if (des_check_parity(HL("01 01 01 01 01 01 01 00")))
+    FAIL();
+
+  /* The four weak keys */
+  test_weak(H("01 01 01 01 01 01 01 01"));  
+  test_weak(H("FE FE FE FE FE FE FE FE"));
+  test_weak(H("1F 1F 1F 1F 0E 0E 0E 0E"));
+  test_weak(H("E0 E0 E0 E0 F1 F1 F1 F1"));
+
+  /* Same weak key, but different parity. */
+  test_weak(H("E0 E0 E0 E0 F0 F1 F1 F1"));
+
+  /* The six pairs of semiweak keys */
+  test_weak(H("01 FE 01 FE 01 FE 01 FE"));
+  test_weak(H("FE 01 FE 01 FE 01 FE 01"));
+
+  test_weak(H("1F E0 1F E0 0E F1 0E F1"));
+  test_weak(H("E0 1F E0 1F F1 0E F1 0E"));
+
+  test_weak(H("01 E0 01 E0 01 F1 01 F1"));
+  test_weak(H("E0 01 E0 01 F1 01 F1 01"));
+
+  test_weak(H("1F FE 1F FE 0E FE 0E FE"));
+  test_weak(H("FE 1F FE 1F FE 0E FE 0E"));
+
+  test_weak(H("01 1F 01 1F 01 0E 01 0E"));
+  test_weak(H("1F 01 1F 01 0E 01 0E 01"));
+
+  test_weak(H("E0 FE E0 FE F1 FE F1 FE"));
+  test_weak(H("FE E0 FE E0 FE F1 FE F1"));
+
+  SUCCESS();
+}
diff --git a/testsuite/des3-test.c b/testsuite/des3-test.c
new file mode 100644 (file)
index 0000000..678a235
--- /dev/null
@@ -0,0 +1,21 @@
+#include "testutils.h"
+#include "nettle-internal.h"
+#include "des.h"
+
+int
+test_main(void)
+{
+  /* Intermediate values:
+   *   After first DES encryption:  "cd ea 2a 20 c2 e0 9e 48"
+   *   After second DES decryption: "69 52 6e 95 8b ea 49 bd"
+   */
+
+  test_cipher(&nettle_des3,
+             HL("3e 0b 10 b0 5d 49 c2 54"
+                "6b 46 e0 75 8a 91 61 85"
+                "cb 04 07 d3 20 16 cb a2"),
+             DES_BLOCK_SIZE, "Now is t",
+             H("0a 5d b5 2d 85 74 d1 c9"));
+
+  SUCCESS();
+}
diff --git a/testsuite/dsa-keygen-test.c b/testsuite/dsa-keygen-test.c
new file mode 100644 (file)
index 0000000..12dc309
--- /dev/null
@@ -0,0 +1,46 @@
+#include "testutils.h"
+
+#include "knuth-lfib.h"
+
+static void
+progress(void *ctx UNUSED, int c)
+{
+  fputc(c, stderr);
+}
+
+int
+test_main(void)
+{
+  struct dsa_public_key pub;
+  struct dsa_private_key key;
+  
+  struct knuth_lfib_ctx lfib;
+  
+  dsa_private_key_init(&key);
+  dsa_public_key_init(&pub);
+
+  knuth_lfib_init(&lfib, 13);
+
+  if (!dsa_generate_keypair(&pub, &key,
+                           &lfib, (nettle_random_func *) knuth_lfib_random,
+                           NULL, verbose ? progress : NULL,
+                           1024, 160))
+    FAIL();
+
+  test_dsa_key(&pub, &key, 160);
+  test_dsa160(&pub, &key, NULL);
+
+  if (!dsa_generate_keypair(&pub, &key,
+                           &lfib, (nettle_random_func *) knuth_lfib_random,
+                           NULL, verbose ? progress : NULL,
+                           2048, 256))
+    FAIL();
+
+  test_dsa_key(&pub, &key, 256);
+  test_dsa256(&pub, &key, NULL);
+  
+  dsa_public_key_clear(&pub);
+  dsa_private_key_clear(&key);
+  
+  SUCCESS();
+}
diff --git a/testsuite/dsa-test.c b/testsuite/dsa-test.c
new file mode 100644 (file)
index 0000000..3698d1b
--- /dev/null
@@ -0,0 +1,105 @@
+#include "testutils.h"
+
+int
+test_main(void)
+{
+  struct dsa_public_key pub;
+  struct dsa_private_key key;
+  struct dsa_signature expected;
+  
+  dsa_public_key_init(&pub);
+  dsa_private_key_init(&key);
+  dsa_signature_init(&expected);
+
+  mpz_set_str(pub.p,
+             "83d9a7c2ce2a9179f43cdb3bffe7de0f0eef26dd5dfae44d"
+             "531bc0de45634d2c07cb929b0dbe10da580070e6abfbb841"
+             "5c44bff570b8ad779df653aad97dc7bdeb815d7e88103e61"
+             "606ed3d8a295fbfd340d2d49e220833ebace5511e22c4f02"
+             "97ed351e9948fa848e9c8fadb7b47bcc47def4255b5e1d5e"
+             "10215b3b55a0b85f", 16);
+  mpz_set_str(pub.q,
+             "8266e0deaf46020ba48d410ca580f3a978629b5d", 16);
+  mpz_set_str(pub.g,
+             "30d34bb9f376bec947154afe4076bc7d359c9d32f5471ddb"
+             "be8d6a941c47fa9dc4f32573151dbb4aa59eb989b74ac36b"
+             "b6310a5e8b580501655d91f393daa193ae1303049b87febb"
+             "093dc0404b53b4c5da2463300f9c5b156d788c4ace8ecbb9"
+             "dd00c18d99537f255ac025d074d894a607cbe3023a1276ef"
+             "556916a33f7de543", 16);
+  mpz_set_str(pub.y,
+             "64402048b27f39f404a546a84909c9c0e9e2dd153a849946"
+             "1062892598d30af27ae3cefc2b700fb6d077390a83bdcad7"
+             "8a1299487c9623bb62af0c85a3df9ef1ee2c0d66658e1fd3"
+             "283b5407f6cd30ee7e6154fad41a6a8b0f5c86c5accc1127"
+             "bf7c9a5d6badcb012180cb62a55c5e17d6d3528cdbe002cc"
+             "ee131c1b86867f7a", 16);
+  mpz_set_str(key.x,
+             "56c6efaf878d06eef21dc070fab71da6ec1e30a6", 16);
+
+  test_dsa_key(&pub, &key, 160);
+
+  mpz_set_str(expected.r, "373999e9ee0a84a9983e528ee266938091e4c55c", 16);
+  mpz_set_str(expected.s, "8017d54592bde7353f6558b3090d12ed8367e2ba", 16);
+
+  test_dsa160(&pub, &key, &expected);
+
+  mpz_set_str(pub.p,
+             "fda45d8f1df8f2b84fb3cf9ae69f93b087d98bea282f643e"
+             "23472c5b57605952010e4c846d711f2783e8ad4e1447698e"
+             "2e328fdb1d411ccb0f3caef5b8fc0b9dcecfadf022ecc7de"
+             "5c153c8f10fe88d63abf7d296ad485dfd6eead595fc1c36b"
+             "8bd42e8668b55b2bb0f1a6aecbe678df504880de2481a5e4"
+             "97d1b7d92ee48ffeb083a1833094a0418ec0d914409c720c"
+             "87ea63c164ec448c471b574a8f88073ebeb44dc6d6b98260"
+             "46126f03022ff04dcb6a2381a09b0a227d3c57cfbfd48e4a"
+             "19cbb0a35242c9e234ebe105ae26cab01ede40aa2869fad8"
+             "6bff57a19ec87b8de294ca03269c268c10813f18169beac5"
+             "ac97c0e748ccb244282c50c670e1bccb", 16);
+  mpz_set_str(pub.q,
+             "bd612630da4d930779a32546dc413efd299111b443c7355d"
+             "65d991163cc3cd9d", 16);
+  mpz_set_str(pub.g,
+             "050c56e14adb03e47d3902852f5b21c96c28a2aa89619c8b"
+             "78a98aa5083700994f99184588d2cefaf2a3ea213dd2d084"
+             "0e682a52357d5fefaef44520622f021855744d638e792f21"
+             "89543f9770aa1960da4d7b325a37a2922b035c8da3d71543"
+             "5d7a6ddefc62e84fe76fecbbf9667c6a1781a84aa434548b"
+             "bdc315f2fb0a420d65c1f72911845b148e994660138052a1"
+             "fce1c6f933be155b2af8c0177277cd3b75d9477ddbcb77bc"
+             "f5cccea915a2f3750ba41f337edd44f768cb3d24b17e299d"
+             "5cebe5e78cbaf5ad41e815edfc71df3131bd5359c653a224"
+             "bd3ac6a27bad7efff11b24fad0109ee26e4df76fc99e150d"
+             "666a9294bab8a03f113d228bfad349f4", 16);
+  mpz_set_str(pub.y,
+             "da7f9abb0b554afaa926c9cffa897239bfdbc58ed9981748"
+             "edb1e38f42dea0560a407a48b509a5cb460bf31dee9057a0"
+             "b41d468698fa82ff03c47e8f3f6564c74d6f1daa5f84ad25"
+             "b937317f861fa68c19e20d6b855e85cd94d5af95b968416e"
+             "6d43711f24d5497f018b7627d2bed25dc793ddb897fdcc34"
+             "5d183e43a80205483dea7a12185be3b185a7d84d3385b962"
+             "4485882722d177ccd8f49c5b519fb96b9b59fcfc63422f25"
+             "88fb8ff00bce46acb7c80d105c31414ecf5be0a0dad975bd"
+             "dcd83d6f063f9bce562fdd5b68e18fc2159dbb2457adc7a7"
+             "ee5bc0796eff370908f866a41b9a8873f89e1904925141f8"
+             "e574df25bd869f43a184a804e8ce5fcc", 16);
+  mpz_set_str(key.x,
+             "39f84f88569da55c6bee7e18175b539ea9b7ee24fabd85a7"
+             "1fa8c93b7181545b", 16);
+
+  test_dsa_key(&pub, &key, 256); 
+
+  mpz_set_str(expected.r,
+             "af30ed0383ea9eaca2fe6244adb86b5ffa80b62cd1687571"
+             "eb75c2a4fff413fb", 16);
+  mpz_set_str(expected.s,
+             "2761c5340430a9b003cd8ba72b1c2cd68644bfa23ae4c40f"
+             "9250dee3ef0e7c35", 16);
+
+  test_dsa256(&pub, &key, NULL);
+
+  dsa_public_key_clear(&pub);
+  dsa_private_key_clear(&key);
+  dsa_signature_clear(&expected);
+  SUCCESS();
+}
diff --git a/testsuite/gcm-test.c b/testsuite/gcm-test.c
new file mode 100644 (file)
index 0000000..a1cf964
--- /dev/null
@@ -0,0 +1,279 @@
+#include "testutils.h"
+#include "aes.h"
+#include "nettle-internal.h"
+
+int
+test_main(void)
+{
+  /* 
+   * GCM-AES Test Vectors from
+   * http://www.cryptobarn.com/papers/gcm-spec.pdf
+   */
+
+  /* Test case 1 */
+  test_aead(&nettle_gcm_aes128,
+           /* key */HL("00000000000000000000000000000000"),
+           /* auth data */ HL(""),
+           /* plaintext */HL(""),
+           /* ciphertext*/H(""),
+           /* IV */HL("000000000000000000000000"),
+           /* tag */H("58e2fccefa7e3061367f1d57a4e7455a"));
+
+  /* Test case 2 */
+  test_aead(&nettle_gcm_aes128,
+           HL("00000000000000000000000000000000"),
+           HL(""),
+           HL("00000000000000000000000000000000"),
+           H("0388dace60b6a392f328c2b971b2fe78"),
+           HL("000000000000000000000000"),
+           H("ab6e47d42cec13bdf53a67b21257bddf"));
+
+  /* Test case 3 */
+  test_aead(&nettle_gcm_aes128,
+           HL("feffe9928665731c6d6a8f9467308308"),
+           HL(""),
+           HL("d9313225f88406e5a55909c5aff5269a"
+              "86a7a9531534f7da2e4c303d8a318a72"
+              "1c3c0c95956809532fcf0e2449a6b525"
+              "b16aedf5aa0de657ba637b391aafd255"),
+           H("42831ec2217774244b7221b784d0d49c"
+             "e3aa212f2c02a4e035c17e2329aca12e"
+             "21d514b25466931c7d8f6a5aac84aa05"
+             "1ba30b396a0aac973d58e091473f5985"),
+           HL("cafebabefacedbaddecaf888"),
+           H("4d5c2af327cd64a62cf35abd2ba6fab4"));
+
+  /* Test case 4 */
+  test_aead(&nettle_gcm_aes128,
+           HL("feffe9928665731c6d6a8f9467308308"),
+           HL("feedfacedeadbeeffeedfacedeadbeef"
+              "abaddad2"),
+           HL("d9313225f88406e5a55909c5aff5269a"
+              "86a7a9531534f7da2e4c303d8a318a72"
+              "1c3c0c95956809532fcf0e2449a6b525"
+              "b16aedf5aa0de657ba637b39"),
+           H("42831ec2217774244b7221b784d0d49c"
+             "e3aa212f2c02a4e035c17e2329aca12e"
+             "21d514b25466931c7d8f6a5aac84aa05"
+             "1ba30b396a0aac973d58e091"),
+           HL("cafebabefacedbaddecaf888"),
+           H("5bc94fbc3221a5db94fae95ae7121a47"));
+
+  /* Test case 5 */
+  test_aead(&nettle_gcm_aes128,
+           HL("feffe9928665731c6d6a8f9467308308"),
+           HL("feedfacedeadbeeffeedfacedeadbeef"
+              "abaddad2"),
+           HL("d9313225f88406e5a55909c5aff5269a"
+              "86a7a9531534f7da2e4c303d8a318a72"
+              "1c3c0c95956809532fcf0e2449a6b525"
+              "b16aedf5aa0de657ba637b39"),
+           H("61353b4c2806934a777ff51fa22a4755"
+             "699b2a714fcdc6f83766e5f97b6c7423"
+             "73806900e49f24b22b097544d4896b42"
+             "4989b5e1ebac0f07c23f4598"),
+           HL("cafebabefacedbad"),
+           H("3612d2e79e3b0785561be14aaca2fccb"));
+
+  /* Test case 6 */
+  test_aead(&nettle_gcm_aes128,
+           HL("feffe9928665731c6d6a8f9467308308"),
+           HL("feedfacedeadbeeffeedfacedeadbeef"
+              "abaddad2"),
+           HL("d9313225f88406e5a55909c5aff5269a"
+              "86a7a9531534f7da2e4c303d8a318a72"
+              "1c3c0c95956809532fcf0e2449a6b525"
+              "b16aedf5aa0de657ba637b39"),
+           H("8ce24998625615b603a033aca13fb894"
+             "be9112a5c3a211a8ba262a3cca7e2ca7"
+             "01e4a9a4fba43c90ccdcb281d48c7c6f"
+             "d62875d2aca417034c34aee5"),
+           HL("9313225df88406e555909c5aff5269aa"
+              "6a7a9538534f7da1e4c303d2a318a728"
+              "c3c0c95156809539fcf0e2429a6b5254"
+              "16aedbf5a0de6a57a637b39b"),
+           H("619cc5aefffe0bfa462af43c1699d050"));
+  
+  /* Test case 7 */
+  test_aead(&nettle_gcm_aes128,
+           HL("00000000000000000000000000000000"
+              "0000000000000000"),
+           HL(""),
+           HL(""),
+           H(""),
+           HL("000000000000000000000000"),
+           H("cd33b28ac773f74ba00ed1f312572435"));
+
+  /* Test case 8 */
+  test_aead(&nettle_gcm_aes128,
+           HL("00000000000000000000000000000000"
+              "0000000000000000"),
+           HL(""),
+           HL("00000000000000000000000000000000"),
+           H("98e7247c07f0fe411c267e4384b0f600"),
+           HL("000000000000000000000000"),
+           H("2ff58d80033927ab8ef4d4587514f0fb"));
+
+  /* Test case 9 */
+  test_aead(&nettle_gcm_aes128,
+           HL("feffe9928665731c6d6a8f9467308308"
+              "feffe9928665731c"),
+           HL(""),
+           HL("d9313225f88406e5a55909c5aff5269a"
+              "86a7a9531534f7da2e4c303d8a318a72"
+              "1c3c0c95956809532fcf0e2449a6b525"
+              "b16aedf5aa0de657ba637b391aafd255"),
+           H("3980ca0b3c00e841eb06fac4872a2757"
+             "859e1ceaa6efd984628593b40ca1e19c"
+             "7d773d00c144c525ac619d18c84a3f47"
+             "18e2448b2fe324d9ccda2710acade256"),
+           HL("cafebabefacedbaddecaf888"),
+           H("9924a7c8587336bfb118024db8674a14"));
+
+  /* Test case 10 */
+  test_aead(&nettle_gcm_aes128,
+           HL("feffe9928665731c6d6a8f9467308308"
+              "feffe9928665731c"),
+           HL("feedfacedeadbeeffeedfacedeadbeef"
+              "abaddad2"),
+           HL("d9313225f88406e5a55909c5aff5269a"
+              "86a7a9531534f7da2e4c303d8a318a72"
+              "1c3c0c95956809532fcf0e2449a6b525"
+              "b16aedf5aa0de657ba637b39"),
+           H("3980ca0b3c00e841eb06fac4872a2757"
+             "859e1ceaa6efd984628593b40ca1e19c"
+             "7d773d00c144c525ac619d18c84a3f47"
+             "18e2448b2fe324d9ccda2710"),
+           HL("cafebabefacedbaddecaf888"),
+           H("2519498e80f1478f37ba55bd6d27618c"));
+
+  /* Test case 11 */
+  test_aead(&nettle_gcm_aes128,
+           HL("feffe9928665731c6d6a8f9467308308"
+              "feffe9928665731c"),
+           HL("feedfacedeadbeeffeedfacedeadbeef"
+              "abaddad2"),
+           HL("d9313225f88406e5a55909c5aff5269a"
+              "86a7a9531534f7da2e4c303d8a318a72"
+              "1c3c0c95956809532fcf0e2449a6b525"
+              "b16aedf5aa0de657ba637b39"),
+           H("0f10f599ae14a154ed24b36e25324db8"
+             "c566632ef2bbb34f8347280fc4507057"
+             "fddc29df9a471f75c66541d4d4dad1c9"
+             "e93a19a58e8b473fa0f062f7"),
+           HL("cafebabefacedbad"),
+           H("65dcc57fcf623a24094fcca40d3533f8"));
+
+  /* Test case 12 */
+  test_aead(&nettle_gcm_aes128,
+           HL("feffe9928665731c6d6a8f9467308308"
+              "feffe9928665731c"),
+           HL("feedfacedeadbeeffeedfacedeadbeef"
+              "abaddad2"),
+           HL("d9313225f88406e5a55909c5aff5269a"
+              "86a7a9531534f7da2e4c303d8a318a72"
+              "1c3c0c95956809532fcf0e2449a6b525"
+              "b16aedf5aa0de657ba637b39"),
+           H("d27e88681ce3243c4830165a8fdcf9ff"
+             "1de9a1d8e6b447ef6ef7b79828666e45"
+             "81e79012af34ddd9e2f037589b292db3"
+             "e67c036745fa22e7e9b7373b"),
+           HL("9313225df88406e555909c5aff5269aa"
+              "6a7a9538534f7da1e4c303d2a318a728"
+              "c3c0c95156809539fcf0e2429a6b5254"
+              "16aedbf5a0de6a57a637b39b"),
+           H("dcf566ff291c25bbb8568fc3d376a6d9"));
+
+  /* Test case 13 */
+  test_aead(&nettle_gcm_aes128,
+           HL("00000000000000000000000000000000"
+              "00000000000000000000000000000000"),
+           HL(""),
+           HL(""),
+           H(""),
+           HL("000000000000000000000000"),
+           H("530f8afbc74536b9a963b4f1c4cb738b"));
+
+  /* Test case 14 */
+  test_aead(&nettle_gcm_aes128,
+           HL("00000000000000000000000000000000"
+              "00000000000000000000000000000000"),
+           HL(""),
+           HL("00000000000000000000000000000000"),
+           H("cea7403d4d606b6e074ec5d3baf39d18"),
+           HL("000000000000000000000000"),
+           H("d0d1c8a799996bf0265b98b5d48ab919"));
+
+  /* Test case 15 */
+  test_aead(&nettle_gcm_aes128,
+           HL("feffe9928665731c6d6a8f9467308308"
+              "feffe9928665731c6d6a8f9467308308"),
+           HL(""),
+           HL("d9313225f88406e5a55909c5aff5269a"
+              "86a7a9531534f7da2e4c303d8a318a72"
+              "1c3c0c95956809532fcf0e2449a6b525"
+              "b16aedf5aa0de657ba637b391aafd255"),
+           H("522dc1f099567d07f47f37a32a84427d"
+             "643a8cdcbfe5c0c97598a2bd2555d1aa"
+             "8cb08e48590dbb3da7b08b1056828838"
+             "c5f61e6393ba7a0abcc9f662898015ad"),
+           HL("cafebabefacedbaddecaf888"),
+           H("b094dac5d93471bdec1a502270e3cc6c"));
+
+  /* Test case 16 */
+  test_aead(&nettle_gcm_aes128,
+           HL("feffe9928665731c6d6a8f9467308308"
+              "feffe9928665731c6d6a8f9467308308"),
+           HL("feedfacedeadbeeffeedfacedeadbeef"
+              "abaddad2"),
+           HL("d9313225f88406e5a55909c5aff5269a"
+              "86a7a9531534f7da2e4c303d8a318a72"
+              "1c3c0c95956809532fcf0e2449a6b525"
+              "b16aedf5aa0de657ba637b39"),
+           H("522dc1f099567d07f47f37a32a84427d"
+             "643a8cdcbfe5c0c97598a2bd2555d1aa"
+             "8cb08e48590dbb3da7b08b1056828838"
+             "c5f61e6393ba7a0abcc9f662"),
+           HL("cafebabefacedbaddecaf888"),
+           H("76fc6ece0f4e1768cddf8853bb2d551b"));
+
+  /* Test case 17 */
+  test_aead(&nettle_gcm_aes128,
+           HL("feffe9928665731c6d6a8f9467308308"
+              "feffe9928665731c6d6a8f9467308308"),
+           HL("feedfacedeadbeeffeedfacedeadbeef"
+              "abaddad2"),
+           HL("d9313225f88406e5a55909c5aff5269a"
+              "86a7a9531534f7da2e4c303d8a318a72"
+              "1c3c0c95956809532fcf0e2449a6b525"
+              "b16aedf5aa0de657ba637b39"),
+           H("c3762df1ca787d32ae47c13bf19844cb"
+             "af1ae14d0b976afac52ff7d79bba9de0"
+             "feb582d33934a4f0954cc2363bc73f78"
+             "62ac430e64abe499f47c9b1f"),
+           HL("cafebabefacedbad"),
+           H("3a337dbf46a792c45e454913fe2ea8f2"));
+
+  /* Test case 18 */
+  test_aead(&nettle_gcm_aes128,
+           HL("feffe9928665731c6d6a8f9467308308"
+              "feffe9928665731c6d6a8f9467308308"),
+           HL("feedfacedeadbeeffeedfacedeadbeef"
+              "abaddad2"),
+           HL("d9313225f88406e5a55909c5aff5269a"
+              "86a7a9531534f7da2e4c303d8a318a72"
+              "1c3c0c95956809532fcf0e2449a6b525"
+              "b16aedf5aa0de657ba637b39"),
+           H("5a8def2f0c9e53f1f75d7853659e2a20"
+             "eeb2b22aafde6419a058ab4f6f746bf4"
+             "0fc0c3b780f244452da3ebf1c5d82cde"
+             "a2418997200ef82e44ae7e3f"),
+           HL("9313225df88406e555909c5aff5269aa"
+              "6a7a9538534f7da1e4c303d2a318a728"
+              "c3c0c95156809539fcf0e2429a6b5254"
+              "16aedbf5a0de6a57a637b39b"),
+           H("a44a8266ee1c8eb0c8b5d4cf5ae9f19a"));
+
+  SUCCESS();
+}
+
diff --git a/testsuite/gold-bug.txt b/testsuite/gold-bug.txt
new file mode 100644 (file)
index 0000000..be3a2a0
--- /dev/null
@@ -0,0 +1,1598 @@
+Edgar Allan Poe
+
+The Gold-Bug
+
+
+What ho! what ho! this fellow is dancing mad!
+He hath been bitten by the Tarantula.
+                                  --All in the Wrong.
+
+
+Many years ago, I contracted an intimacy with a Mr. William
+Legrand.  He was of an ancient Huguenot family, and had once been
+wealthy: but a series of misfortunes had reduced him to want.  To
+avoid the mortification consequent upon his disasters, he left New
+Orleans, the city of his forefathers, and took up his residence at
+Sullivan's Island, near Charleston, South Carolina.
+
+This island is a very singular one.  It consists of little else
+than the sea sand, and is about three miles long.  Its breadth at
+no point exceeds a quarter of a mile.  It is separated from the
+mainland by a scarcely perceptible creek, oozing its way through a
+wilderness of reeds and slime, a favorite resort of the marsh hen.
+The vegetation, as might be supposed, is scant, or at least
+dwarfish.  No trees of any magnitude are to be seen.  Near the
+western extremity, where Fort Moultrie stands, and where are some
+miserable frame buildings, tenanted, during summer, by the
+fugitives from Charleston dust and fever, may be found, indeed, the
+bristly palmetto; but the whole island, with the exception of this
+western point, and a line of hard, white beach on the seacoast, is
+covered with a dense undergrowth of the sweet myrtle so much prized
+by the horticulturists of England.  The shrub here often attains
+the height of fifteen or twenty feet, and forms an almost
+impenetrable coppice, burdening the air with its fragrance.
+
+In the inmost recesses of this coppice, not far from the eastern or
+more remote end of the island, Legrand had built himself a small
+hut, which he occupied when I first, by mere accident, made his
+acquaintance.  This soon ripened into friendship--for there was
+much in the recluse to excite interest and esteem.  I found him
+well educated, with unusual powers of mind, but infected with
+misanthropy, and subject to perverse moods of alternate enthusiasm
+and melancholy.  He had with him many books, but rarely employed
+them.  His chief amusements were gunning and fishing, or sauntering
+along the beach and through the myrtles, in quest of shells or
+entomological specimens--his collection of the latter might have
+been envied by a Swammerdamm.  In these excursions he was usually
+accompanied by an old negro, called Jupiter, who had been
+manumitted before the reverses of the family, but who could be
+induced, neither by threats nor by promises, to abandon what he
+considered his right of attendance upon the footsteps of his young
+"Massa Will."  It is not improbable that the relatives of Legrand,
+conceiving him to be somewhat unsettled in intellect, had contrived
+to instill this obstinacy into Jupiter, with a view to the
+supervision and guardianship of the wanderer.
+
+The winters in the latitude of Sullivan's Island are seldom very
+severe, and in the fall of the year it is a rare event indeed when
+a fire is considered necessary.  About the middle of October, 18--,
+there occurred, however, a day of remarkable chilliness.  Just
+before sunset I scrambled my way through the evergreens to the hut
+of my friend, whom I had not visited for several weeks--my
+residence being, at that time, in Charleston, a distance of nine
+miles from the island, while the facilities of passage and
+repassage were very far behind those of the present day.  Upon
+reaching the hut I rapped, as was my custom, and getting no reply,
+sought for the key where I knew it was secreted, unlocked the door,
+and went in.  A fine fire was blazing upon the hearth.  It was a
+novelty, and by no means an ungrateful one.  I threw off an
+overcoat, took an armchair by the crackling logs, and awaited
+patiently the arrival of my hosts.
+
+Soon after dark they arrived, and gave me a most cordial welcome.
+Jupiter, grinning from ear to ear, bustled about to prepare some
+marsh hens for supper.  Legrand was in one of his fits--how else
+shall I term them?--of enthusiasm.  He had found an unknown
+bivalve, forming a new genus, and, more than this, he had hunted
+down and secured, with Jupiter's assistance, a scarabaeus which he
+believed to be totally new, but in respect to which he wished to
+have my opinion on the morrow.
+
+"And why not to-night?" I asked, rubbing my hands over the blaze,
+and wishing the whole tribe of scarabaei at the devil.
+
+"Ah, if I had only known you were here!" said Legrand, "but it's so
+long since I saw you; and how could I foresee that you would pay me
+a visit this very night of all others?  As I was coming home I met
+Lieutenant G----, from the fort, and, very foolishly, I lent him
+the bug; so it will be impossible for you to see it until the
+morning.  Stay here to-night, and I will send Jup down for it at
+sunrise.  It is the loveliest thing in creation!"
+
+"What?--sunrise?"
+
+"Nonsense! no!--the bug.  It is of a brilliant gold color--about
+the size of a large hickory nut--with two jet black spots near one
+extremity of the back, and another, somewhat longer, at the other.
+The antennae are--"
+
+"Dey ain't NO tin in him, Massa Will, I keep a tellin' on you,"
+here interrupted Jupiter; "de bug is a goole-bug, solid, ebery bit
+of him, inside and all, sep him wing--neber feel half so hebby a
+bug in my life."
+
+"Well, suppose it is, Jup," replied Legrand, somewhat more
+earnestly, it seemed to me, than the case demanded; "is that any
+reason for your letting the birds burn?  The color"--here he turned
+to me--"is really almost enough to warrant Jupiter's idea.  You
+never saw a more brilliant metallic luster than the scales emit--
+but of this you cannot judge till to-morrow.  In the meantime I can
+give you some idea of the shape."  Saying this, he seated himself
+at a small table, on which were a pen and ink, but no paper.  He
+looked for some in a drawer, but found none.
+
+"Never mind," he said at length, "this will answer;" and he drew
+from his waistcoat pocket a scrap of what I took to be very dirty
+foolscap, and made upon it a rough drawing with the pen.  While he
+did this, I retained my seat by the fire, for I was still chilly.
+When the design was complete, he handed it to me without rising.
+As I received it, a loud growl was heard, succeeded by a scratching
+at the door.  Jupiter opened it, and a large Newfoundland,
+belonging to Legrand, rushed in, leaped upon my shoulders, and
+loaded me with caresses; for I had shown him much attention during
+previous visits.  When his gambols were over, I looked at the
+paper, and, to speak the truth, found myself not a little puzzled
+at what my friend had depicted.
+
+"Well!" I said, after contemplating it for some minutes, "this IS a
+strange scarabaeus, I must confess; new to me; never saw anything
+like it before--unless it was a skull, or a death's head, which it
+more nearly resembles than anything else that has come under MY
+observation."
+
+"A death's head!" echoed Legrand.  "Oh--yes--well, it has something
+of that appearance upon paper, no doubt.  The two upper black spots
+look like eyes, eh? and the longer one at the bottom like a mouth--
+and then the shape of the whole is oval."
+
+"Perhaps so," said I; "but, Legrand, I fear you are no artist.  I
+must wait until I see the beetle itself, if I am to form any idea
+of its personal appearance."
+
+"Well, I don't know," said he, a little nettled, "I draw tolerably--
+SHOULD do it at least--have had good masters, and flatter myself
+that I am not quite a blockhead."
+
+"But, my dear fellow, you are joking then," said I, "this is a very
+passable SKULL--indeed, I may say that it is a very EXCELLENT
+skull, according to the vulgar notions about such specimens of
+physiology--and your scarabaeus must be the queerest scarabaeus in
+the world if it resembles it.  Why, we may get up a very thrilling
+bit of superstition upon this hint.  I presume you will call the
+bug Scarabaeus caput hominis, or something of that kind--there are
+many similar titles in the Natural Histories.  But where are the
+antennae you spoke of?"
+
+"The antennae!" said Legrand, who seemed to be getting
+unaccountably warm upon the subject; "I am sure you must see the
+antennae.  I made them as distinct as they are in the original
+insect, and I presume that is sufficient."
+
+"Well, well," I said, "perhaps you have--still I don't see them;"
+and I handed him the paper without additional remark, not wishing
+to ruffle his temper; but I was much surprised at the turn affairs
+had taken; his ill humor puzzled me--and, as for the drawing of the
+beetle, there were positively NO antennae visible, and the whole
+DID bear a very close resemblance to the ordinary cuts of a death's
+head.
+
+He received the paper very peevishly, and was about to crumple it,
+apparently to throw it in the fire, when a casual glance at the
+design seemed suddenly to rivet his attention.  In an instant his
+face grew violently red--in another excessively pale.  For some
+minutes he continued to scrutinize the drawing minutely where he
+sat.  At length he arose, took a candle from the table, and
+proceeded to seat himself upon a sea chest in the farthest corner
+of the room.  Here again he made an anxious examination of the
+paper, turning it in all directions.  He said nothing, however, and
+his conduct greatly astonished me; yet I thought it prudent not to
+exacerbate the growing moodiness of his temper by any comment.
+Presently he took from his coat pocket a wallet, placed the paper
+carefully in it, and deposited both in a writing desk, which he
+locked.  He now grew more composed in his demeanor; but his
+original air of enthusiasm had quite disappeared.  Yet he seemed
+not so much sulky as abstracted.  As the evening wore away he
+became more and more absorbed in reverie, from which no sallies of
+mine could arouse him.  It had been my intention to pass the night
+at the hut, as I had frequently done before, but, seeing my host in
+this mood, I deemed it proper to take leave.  He did not press me
+to remain, but, as I departed, he shook my hand with even more than
+his usual cordiality.
+
+It was about a month after this (and during the interval I had seen
+nothing of Legrand) when I received a visit, at Charleston, from
+his man, Jupiter.  I had never seen the good old negro look so
+dispirited, and I feared that some serious disaster had befallen my
+friend.
+
+"Well, Jup," said I, "what is the matter now?--how is your master?"
+
+"Why, to speak the troof, massa, him not so berry well as mought
+be."
+
+"Not well!  I am truly sorry to hear it.  What does he complain
+of?"
+
+"Dar! dot's it!--him neber 'plain of notin'--but him berry sick for
+all dat."
+
+"VERY sick, Jupiter!--why didn't you say so at once?  Is he
+confined to bed?"
+
+"No, dat he aint!--he aint 'fin'd nowhar--dat's just whar de shoe
+pinch--my mind is got to be berry hebby 'bout poor Massa Will."
+
+"Jupiter, I should like to understand what it is you are talking
+about.  You say your master is sick.  Hasn't he told you what ails
+him?"
+
+"Why, massa, 'taint worf while for to git mad about de matter--
+Massa Will say noffin at all aint de matter wid him--but den what
+make him go about looking dis here way, wid he head down and he
+soldiers up, and as white as a goose?  And den he keep a syphon all
+de time--"
+
+"Keeps a what, Jupiter?"
+
+"Keeps a syphon wid de figgurs on de slate--de queerest figgurs I
+ebber did see.  Ise gittin' to be skeered, I tell you.  Hab for to
+keep mighty tight eye 'pon him 'noovers.  Todder day he gib me slip
+'fore de sun up and was gone de whole ob de blessed day.  I had a
+big stick ready cut for to gib him deuced good beating when he did
+come--but Ise sich a fool dat I hadn't de heart arter all--he
+looked so berry poorly."
+
+"Eh?--what?--ah yes!--upon the whole I think you had better not be
+too severe with the poor fellow--don't flog him, Jupiter--he can't
+very well stand it--but can you form no idea of what has occasioned
+this illness, or rather this change of conduct?  Has anything
+unpleasant happened since I saw you?"
+
+"No, massa, dey aint bin noffin onpleasant SINCE den--'twas 'FORE
+den I'm feared--'twas de berry day you was dare."
+
+"How? what do you mean."
+
+"Why, massa, I mean de bug--dare now."
+
+"The what?"
+
+"De bug--I'm berry sartin dat Massa Will bin bit somewhere 'bout de
+head by dat goole-bug."
+
+"And what cause have you, Jupiter, for such a supposition?"
+
+"Claws enuff, massa, and mouff, too.  I nebber did see sich a
+deuced bug--he kick and he bite eberyting what cum near him.  Massa
+Will cotch him fuss, but had for to let him go 'gin mighty quick, I
+tell you--den was de time he must ha' got de bite.  I didn't like
+de look ob de bug mouff, myself, nohow, so I wouldn't take hold oh
+him wid my finger, but I cotch him wid a piece oh paper dat I
+found.  I rap him up in de paper and stuff a piece of it in he
+mouff--dat was de way."
+
+"And you think, then, that your master was really bitten by the
+beetle, and that the bite made him sick?"
+
+"I don't think noffin about it--I nose it.  What make him dream
+'bout de goole so much, if 'taint cause he bit by the goole-bug?
+Ise heered 'bout dem goole-bugs 'fore dis."
+
+"But how do you know he dreams about gold?"
+
+"How I know?  why, 'cause he talk about it in he sleep--dat's how I
+nose."
+
+"Well, Jup, perhaps you are right; but to what fortunate
+circumstance am I to attribute the honor of a visit from you to-
+day?"
+
+"What de matter, massa?"
+
+"Did you bring any message from Mr. Legrand?"
+
+"No, massa, I bring dis here pissel;" and here Jupiter handed me a
+note which ran thus:
+
+
+"MY DEAR ----
+
+"Why have I not seen you for so long a time?  I hope you have not
+been so foolish as to take offense at any little brusquerie of
+mine; but no, that is improbable.
+
+"Since I saw you I have had great cause for anxiety.  I have
+something to tell you, yet scarcely know how to tell it, or whether
+I should tell it at all.
+
+"I have not been quite well for some days past, and poor old Jup
+annoys me, almost beyond endurance, by his well-meant attentions.
+Would you believe it?--he had prepared a huge stick, the other day,
+with which to chastise me for giving him the slip, and spending the
+day, solus, among the hills on the mainland.  I verily believe that
+my ill looks alone saved me a flogging.
+
+"I have made no addition to my cabinet since we met.  "If you can,
+in any way, make it convenient, come over with Jupiter.  DO come.
+I wish to see you TO-NIGHT, upon business of importance.  I assure
+you that it is of the HIGHEST importance.
+
+"Ever yours,
+
+"WILLIAM LEGRAND."
+
+
+There was something in the tone of this note which gave me great
+uneasiness.  Its whole style differed materially from that of
+Legrand.  What could he be dreaming of?  What new crotchet
+possessed his excitable brain?  What "business of the highest
+importance" could HE possibly have to transact?  Jupiter's account
+of him boded no good.  I dreaded lest the continued pressure of
+misfortune had, at length, fairly unsettled the reason of my
+friend.  Without a moment's hesitation, therefore, I prepared to
+accompany the negro.
+
+Upon reaching the wharf, I noticed a scythe and three spades, all
+apparently new, lying in the bottom of the boat in which we were to
+embark.
+
+"What is the meaning of all this, Jup?" I inquired.
+
+"Him syfe, massa, and spade."
+
+"Very true; but what are they doing here?"
+
+"Him de syfe and de spade what Massa Will sis 'pon my buying for
+him in de town, and de debbil's own lot of money I had to gib for
+em."
+
+"But what, in the name of all that is mysterious, is your 'Massa
+Will' going to do with scythes and spades?"
+
+"Dat's more dan I know, and debbil take me if I don't b'lieve 'tis
+more dan he know too.  But it's all cum ob de bug."
+
+Finding that no satisfaction was to be obtained of Jupiter, whose
+whole intellect seemed to be absorbed by "de bug," I now stepped
+into the boat, and made sail.  With a fair and strong breeze we
+soon ran into the little cove to the northward of Fort Moultrie,
+and a walk of some two miles brought us to the hut.  It was about
+three in the afternoon when we arrived.  Legrand had been awaiting
+us in eager expectation.  He grasped my hand with a nervous
+empressement which alarmed me and strengthened the suspicions
+already entertained.  His countenance was pale even to ghastliness,
+and his deep-set eyes glared with unnatural luster.  After some
+inquiries respecting his health, I asked him, not knowing what
+better to say, if he had yet obtained the scarabaeus from
+Lieutenant G----.
+
+"Oh, yes," he replied, coloring violently, "I got it from him the
+next morning.  Nothing should tempt me to part with that
+scarabaeus.  Do you know that Jupiter is quite right about it?"
+
+"In what way?" I asked, with a sad foreboding at heart.
+
+"In supposing it to be a bug of REAL GOLD."  He said this with an
+air of profound seriousness, and I felt inexpressibly shocked.
+
+"This bug is to make my fortune," he continued, with a triumphant
+smile; "to reinstate me in my family possessions.  Is it any
+wonder, then, that I prize it?  Since Fortune has thought fit to
+bestow it upon me, I have only to use it properly, and I shall
+arrive at the gold of which it is the index.  Jupiter, bring me
+that scarabaeus!"
+
+"What! de bug, massa?  I'd rudder not go fer trubble dat bug; you
+mus' git him for your own self."  Hereupon Legrand arose, with a
+grave and stately air, and brought me the beetle from a glass case
+in which it was enclosed.  It was a beautiful scarabaeus, and, at
+that time, unknown to naturalists--of course a great prize in a
+scientific point of view.  There were two round black spots near
+one extremity of the back, and a long one near the other.  The
+scales were exceedingly hard and glossy, with all the appearance of
+burnished gold.  The weight of the insect was very remarkable, and,
+taking all things into consideration, I could hardly blame Jupiter
+for his opinion respecting it; but what to make of Legrand's
+concordance with that opinion, I could not, for the life of me,
+tell.
+
+"I sent for you," said he, in a grandiloquent tone, when I had
+completed my examination of the beetle, "I sent for you that I
+might have your counsel and assistance in furthering the views of
+Fate and of the bug--"
+
+"My dear Legrand," I cried, interrupting him, "you are certainly
+unwell, and had better use some little precautions.  You shall go
+to bed, and I will remain with you a few days, until you get over
+this.  You are feverish and--"
+
+"Feel my pulse," said he.
+
+I felt it, and, to say the truth, found not the slightest
+indication of fever.
+
+"But you may be ill and yet have no fever.  Allow me this once to
+prescribe for you.  In the first place go to bed.  In the next--"
+
+"You are mistaken," he interposed, "I am as well as I can expect to
+be under the excitement which I suffer.  If you really wish me
+well, you will relieve this excitement."
+
+"And how is this to be done?"
+
+"Very easily.  Jupiter and myself are going upon an expedition into
+the hills, upon the mainland, and, in this expedition, we shall
+need the aid of some person in whom we can confide.  You are the
+only one we can trust.  Whether we succeed or fail, the excitement
+which you now perceive in me will be equally allayed."
+
+"I am anxious to oblige you in any way," I replied; "but do you
+mean to say that this infernal beetle has any connection with your
+expedition into the hills?"
+
+"It has."
+
+"Then, Legrand, I can become a party to no such absurd proceeding."
+
+"I am sorry--very sorry--for we shall have to try it by ourselves."
+
+"Try it by yourselves!  The man is surely mad!--but stay!--how long
+do you propose to be absent?"
+
+"Probably all night.  We shall start immediately, and be back, at
+all events, by sunrise."
+
+"And will you promise me, upon your honor, that when this freak of
+yours is over, and the bug business (good God!) settled to your
+satisfaction, you will then return home and follow my advice
+implicitly, as that of your physician?"
+
+"Yes; I promise; and now let us be off, for we have no time to
+lose."
+
+With a heavy heart I accompanied my friend.  We started about four
+o'clock--Legrand, Jupiter, the dog, and myself.  Jupiter had with
+him the scythe and spades--the whole of which he insisted upon
+carrying--more through fear, it seemed to me, of trusting either of
+the implements within reach of his master, than from any excess of
+industry or complaisance.  His demeanor was dogged in the extreme,
+and "dat deuced bug" were the sole words which escaped his lips
+during the journey.  For my own part, I had charge of a couple of
+dark lanterns, while Legrand contented himself with the scarabaeus,
+which he carried attached to the end of a bit of whipcord; twirling
+it to and fro, with the air of a conjurer, as he went.  When I
+observed this last, plain evidence of my friend's aberration of
+mind, I could scarcely refrain from tears.  I thought it best,
+however, to humor his fancy, at least for the present, or until I
+could adopt some more energetic measures with a chance of success.
+In the meantime I endeavored, but all in vain, to sound him in
+regard to the object of the expedition.  Having succeeded in
+inducing me to accompany him, he seemed unwilling to hold
+conversation upon any topic of minor importance, and to all my
+questions vouchsafed no other reply than "we shall see!"
+
+We crossed the creek at the head of the island by means of a skiff,
+and, ascending the high grounds on the shore of the mainland,
+proceeded in a northwesterly direction, through a tract of country
+excessively wild and desolate, where no trace of a human footstep
+was to be seen.  Legrand led the way with decision; pausing only
+for an instant, here and there, to consult what appeared to be
+certain landmarks of his own contrivance upon a former occasion.
+
+In this manner we journeyed for about two hours, and the sun was
+just setting when we entered a region infinitely more dreary than
+any yet seen.  It was a species of table-land, near the summit of
+an almost inaccessible hill, densely wooded from base to pinnacle,
+and interspersed with huge crags that appeared to lie loosely upon
+the soil, and in many cases were prevented from precipitating
+themselves into the valleys below, merely by the support of the
+trees against which they reclined.  Deep ravines, in various
+directions, gave an air of still sterner solemnity to the scene.
+
+The natural platform to which we had clambered was thickly
+overgrown with brambles, through which we soon discovered that it
+would have been impossible to force our way but for the scythe; and
+Jupiter, by direction of his master, proceeded to clear for us a
+path to the foot of an enormously tall tulip tree, which stood,
+with some eight or ten oaks, upon the level, and far surpassed them
+all, and all other trees which I had then ever seen, in the beauty
+of its foliage and form, in the wide spread of its branches, and in
+the general majesty of its appearance.  When we reached this tree,
+Legrand turned to Jupiter, and asked him if he thought he could
+climb it.  The old man seemed a little staggered by the question,
+and for some moments made no reply.  At length he approached the
+huge trunk, walked slowly around it, and examined it with minute
+attention.  When he had completed his scrutiny, he merely said:
+
+"Yes, massa, Jup climb any tree he ebber see in he life."
+
+"Then up with you as soon as possible, for it will soon be too dark
+to see what we are about."
+
+"How far mus' go up, massa?" inquired Jupiter.
+
+"Get up the main trunk first, and then I will tell you which way to
+go--and here--stop! take this beetle with you."
+
+"De bug, Massa Will!--de goole-bug!" cried the negro, drawing back
+in dismay--"what for mus' tote de bug way up de tree?--d--n if I
+do!"
+
+"If you are afraid, Jup, a great big negro like you, to take hold
+of a harmless little dead beetle, why you can carry it up by this
+string--but, if you do not take it up with you in some way, I shall
+be under the necessity of breaking your head with this shovel."
+
+"What de matter now, massa?" said Jup, evidently shamed into
+compliance; "always want for to raise fuss wid old nigger.  Was
+only funnin anyhow.  ME feered de bug! what I keer for de bug?"
+Here he took cautiously hold of the extreme end of the string, and,
+maintaining the insect as far from his person as circumstances
+would permit, prepared to ascend the tree.
+
+In youth, the tulip tree, or Liriodendron tulipiferum, the most
+magnificent of American foresters, has a trunk peculiarly smooth,
+and often rises to a great height without lateral branches; but, in
+its riper age, the bark becomes gnarled and uneven, while many
+short limbs make their appearance on the stem.  Thus the difficulty
+of ascension, in the present case, lay more in semblance than in
+reality.  Embracing the huge cylinder, as closely as possible, with
+his arms and knees, seizing with his hands some projections, and
+resting his naked toes upon others, Jupiter, after one or two
+narrow escapes from falling, at length wriggled himself into the
+first great fork, and seemed to consider the whole business as
+virtually accomplished.  The RISK of the achievement was, in fact,
+now over, although the climber was some sixty or seventy feet from
+the ground.
+
+"Which way mus' go now, Massa Will?" he asked.
+
+"Keep up the largest branch--the one on this side," said Legrand.
+The negro obeyed him promptly, and apparently with but little
+trouble; ascending higher and higher, until no glimpse of his squat
+figure could be obtained through the dense foliage which enveloped
+it.  Presently his voice was heard in a sort of halloo.
+
+"How much fudder is got to go?"
+
+"How high up are you?" asked Legrand.
+
+"Ebber so fur," replied the negro; "can see de sky fru de top oh de
+tree."
+
+"Never mind the sky, but attend to what I say.  Look down the trunk
+and count the limbs below you on this side.  How many limbs have
+you passed?"
+
+"One, two, tree, four, fibe--I done pass fibe big limb, massa, 'pon
+dis side."
+
+"Then go one limb higher."
+
+In a few minutes the voice was heard again, announcing that the
+seventh limb was attained.
+
+"Now, Jup," cried Legrand, evidently much excited, "I want you to
+work your way out upon that limb as far as you can.  If you see
+anything strange let me know."
+
+By this time what little doubt I might have entertained of my poor
+friend's insanity was put finally at rest.  I had no alternative
+but to conclude him stricken with lunacy, and I became seriously
+anxious about getting him home.  While I was pondering upon what
+was best to be done, Jupiter's voice was again heard.
+
+"Mos feered for to ventur pon dis limb berry far--'tis dead limb
+putty much all de way."
+
+"Did you say it was a DEAD limb, Jupiter?" cried Legrand in a
+quavering voice.
+
+"Yes, massa, him dead as de door-nail--done up for sartin--done
+departed dis here life."
+
+"What in the name of heaven shall I do?" asked Legrand, seemingly
+in the greatest distress.
+
+"Do!" said I, glad of an opportunity to interpose a word, "why come
+home and go to bed.  Come now!--that's a fine fellow.  It's getting
+late, and, besides, you remember your promise."
+
+"Jupiter," cried he, without heeding me in the least, "do you hear
+me?"
+
+"Yes, Massa Will, hear you ebber so plain."
+
+"Try the wood well, then, with your knife, and see if you think it
+VERY rotten."
+
+"Him rotten, massa, sure nuff," replied the negro in a few moments,
+"but not so berry rotten as mought be.  Mought venture out leetle
+way pon de limb by myself, dat's true."
+
+"By yourself!--what do you mean?"
+
+"Why, I mean de bug.  'Tis BERRY hebby bug.  Spose I drop him down
+fuss, an den de limb won't break wid just de weight of one nigger."
+
+"You infernal scoundrel!" cried Legrand, apparently much relieved,
+"what do you mean by telling me such nonsense as that?  As sure as
+you drop that beetle I'll break your neck.  Look here, Jupiter, do
+you hear me?"
+
+"Yes, massa, needn't hollo at poor nigger dat style."
+
+"Well! now listen!--if you will venture out on the limb as far as
+you think safe, and not let go the beetle, I'll make you a present
+of a silver dollar as soon as you get down."
+
+"I'm gwine, Massa Will--deed I is," replied the negro very
+promptly--"mos out to the eend now."
+
+"OUT TO THE END!" here fairly screamed Legrand; "do you say you are
+out to the end of that limb?"
+
+"Soon be to de eend, massa--o-o-o-o-oh!  Lor-gol-a-marcy! what IS
+dis here pon de tree?"
+
+"Well!" cried Legrand, highly delighted, "what is it?"
+
+"Why 'taint noffin but a skull--somebody bin lef him head up de
+tree, and de crows done gobble ebery bit ob de meat off."
+
+"A skull, you say!--very well,--how is it fastened to the limb?--
+what holds it on?"
+
+"Sure nuff, massa; mus look.  Why dis berry curious sarcumstance,
+pon my word--dare's a great big nail in de skull, what fastens ob
+it on to de tree."
+
+"Well now, Jupiter, do exactly as I tell you--do you hear?"
+
+"Yes, massa."
+
+"Pay attention, then--find the left eye of the skull."
+
+"Hum! hoo! dat's good! why dey ain't no eye lef at all."
+
+"Curse your stupidity! do you know your right hand from your left?"
+
+"Yes, I knows dat--knows all about dat--'tis my lef hand what I
+chops de wood wid."
+
+"To be sure! you are left-handed; and your left eye is on the same
+side as your left hand.  Now, I suppose, you can find the left eye
+of the skull, or the place where the left eye has been.  Have you
+found it?"
+
+Here was a long pause.  At length the negro asked:
+
+"Is de lef eye of de skull pon de same side as de lef hand of de
+skull too?--cause de skull aint got not a bit oh a hand at all--
+nebber mind!  I got de lef eye now--here de lef eye! what mus do
+wid it?"
+
+Let the beetle drop through it, as far as the string will reach--
+but be careful and not let go your hold of the string."
+
+"All dat done, Massa Will; mighty easy ting for to put de bug fru
+de hole--look out for him dare below!"
+
+During this colloquy no portion of Jupiter's person could be seen;
+but the beetle, which he had suffered to descend, was now visible
+at the end of the string, and glistened, like a globe of burnished
+gold, in the last rays of the setting sun, some of which still
+faintly illumined the eminence upon which we stood.  The scarabaeus
+hung quite clear of any branches, and, if allowed to fall, would
+have fallen at our feet.  Legrand immediately took the scythe, and
+cleared with it a circular space, three or four yards in diameter,
+just beneath the insect, and, having accomplished this, ordered
+Jupiter to let go the string and come down from the tree.
+
+Driving a peg, with great nicety, into the ground, at the precise
+spot where the beetle fell, my friend now produced from his pocket
+a tape measure.  Fastening one end of this at that point of the
+trunk of the tree which was nearest the peg, he unrolled it till it
+reached the peg and thence further unrolled it, in the direction
+already established by the two points of the tree and the peg, for
+the distance of fifty feet--Jupiter clearing away the brambles with
+the scythe.  At the spot thus attained a second peg was driven, and
+about this, as a center, a rude circle, about four feet in
+diameter, described.  Taking now a spade himself, and giving one to
+Jupiter and one to me, Legrand begged us to set about digging as
+quickly as possible.
+
+To speak the truth, I had no especial relish for such amusement at
+any time, and, at that particular moment, would willingly have
+declined it; for the night was coming on, and I felt much fatigued
+with the exercise already taken; but I saw no mode of escape, and
+was fearful of disturbing my poor friend's equanimity by a refusal.
+Could I have depended, indeed, upon Jupiter's aid, I would have had
+no hesitation in attempting to get the lunatic home by force; but I
+was too well assured of the old negro's disposition, to hope that
+he would assist me, under any circumstances, in a personal contest
+with his master.  I made no doubt that the latter had been infected
+with some of the innumerable Southern superstitions about money
+buried, and that his fantasy had received confirmation by the
+finding of the scarabaeus, or, perhaps, by Jupiter's obstinacy in
+maintaining it to be "a bug of real gold."  A mind disposed to
+lunacy would readily be led away by such suggestions--especially if
+chiming in with favorite preconceived ideas--and then I called to
+mind the poor fellow's speech about the beetle's being "the index
+of his fortune."  Upon the whole, I was sadly vexed and puzzled,
+but, at length, I concluded to make a virtue of necessity--to dig
+with a good will, and thus the sooner to convince the visionary, by
+ocular demonstration, of the fallacy of the opinion he entertained.
+
+The lanterns having been lit, we all fell to work with a zeal
+worthy a more rational cause; and, as the glare fell upon our
+persons and implements, I could not help thinking how picturesque a
+group we composed, and how strange and suspicious our labors must
+have appeared to any interloper who, by chance, might have stumbled
+upon our whereabouts.
+
+We dug very steadily for two hours.  Little was said; and our chief
+embarrassment lay in the yelpings of the dog, who took exceeding
+interest in our proceedings.  He, at length, became so obstreperous
+that we grew fearful of his giving the alarm to some stragglers in
+the vicinity,--or, rather, this was the apprehension of Legrand;--
+for myself, I should have rejoiced at any interruption which might
+have enabled me to get the wanderer home.  The noise was, at
+length, very effectually silenced by Jupiter, who, getting out of
+the hole with a dogged air of deliberation, tied the brute's mouth
+up with one of his suspenders, and then returned, with a grave
+chuckle, to his task.
+
+When the time mentioned had expired, we had reached a depth of five
+feet, and yet no signs of any treasure became manifest.  A general
+pause ensued, and I began to hope that the farce was at an end.
+Legrand, however, although evidently much disconcerted, wiped his
+brow thoughtfully and recommenced.  We had excavated the entire
+circle of four feet diameter, and now we slightly enlarged the
+limit, and went to the farther depth of two feet.  Still nothing
+appeared.  The gold-seeker, whom I sincerely pitied, at length
+clambered from the pit, with the bitterest disappointment imprinted
+upon every feature, and proceeded, slowly and reluctantly, to put
+on his coat, which he had thrown off at the beginning of his labor.
+In the meantime I made no remark.  Jupiter, at a signal from his
+master, began to gather up his tools.  This done, and the dog
+having been unmuzzled, we turned in profound silence toward home.
+
+We had taken, perhaps, a dozen steps in this direction, when, with
+a loud oath, Legrand strode up to Jupiter, and seized him by the
+collar.  The astonished negro opened his eyes and mouth to the
+fullest extent, let fall the spades, and fell upon his knees.
+
+"You scoundrel!" said Legrand, hissing out the syllables from
+between his clenched teeth--"you infernal black villain!--speak, I
+tell you!--answer me this instant, without prevarication!--which--
+which is your left eye?"
+
+"Oh, my golly, Massa Will! aint dis here my lef eye for sartain?"
+roared the terrified Jupiter, placing his hand upon his RIGHT organ
+of vision, and holding it there with a desperate pertinacity, as if
+in immediate, dread of his master's attempt at a gouge.
+
+"I thought so!--I knew it! hurrah!" vociferated Legrand, letting
+the negro go and executing a series of curvets and caracols, much
+to the astonishment of his valet, who, arising from his knees,
+looked, mutely, from his master to myself, and then from myself to
+his master.
+
+"Come! we must go back," said the latter, "the game's not up yet;"
+and he again led the way to the tulip tree.
+
+"Jupiter," said he, when we reached its foot, "come here! was the
+skull nailed to the limb with the face outward, or with the face to
+the limb?"
+
+"De face was out, massa, so dat de crows could get at de eyes good,
+widout any trouble."
+
+"Well, then, was it this eye or that through which you dropped the
+beetle?" here Legrand touched each of Jupiter's eyes.
+
+"'Twas dis eye, massa--de lef eye--jis as you tell me," and here it
+was his right eye that the negro indicated.
+
+"That will do--we must try it again."
+
+Here my friend, about whose madness I now saw, or fancied that I
+saw, certain indications of method, removed the peg which marked
+the spot where the beetle fell, to a spot about three inches to the
+westward of its former position.  Taking, now, the tape measure
+from the nearest point of the trunk to the peg, as before, and
+continuing the extension in a straight line to the distance of
+fifty feet, a spot was indicated, removed, by several yards, from
+the point at which we had been digging.
+
+Around the new position a circle, somewhat larger than in the
+former instance, was now described, and we again set to work with
+the spade.  I was dreadfully weary, but, scarcely understanding
+what had occasioned the change in my thoughts, I felt no longer any
+great aversion from the labor imposed.  I had become most
+unaccountably interested--nay, even excited.  Perhaps there was
+something, amid all the extravagant demeanor of Legrand--some air
+of forethought, or of deliberation, which impressed me.  I dug
+eagerly, and now and then caught myself actually looking, with
+something that very much resembled expectation, for the fancied
+treasure, the vision of which had demented my unfortunate
+companion.  At a period when such vagaries of thought most fully
+possessed me, and when we had been at work perhaps an hour and a
+half, we were again interrupted by the violent howlings of the dog.
+His uneasiness, in the first instance, had been, evidently, but the
+result of playfulness or caprice, but he now assumed a bitter and
+serious tone.  Upon Jupiter's again attempting to muzzle him, he
+made furious resistance, and, leaping into the hole, tore up the
+mold frantically with his claws.  In a few seconds he had uncovered
+a mass of human bones, forming two complete skeletons, intermingled
+with several buttons of metal, and what appeared to be the dust of
+decayed woolen.  One or two strokes of a spade upturned the blade
+of a large Spanish knife, and, as we dug farther, three or four
+loose pieces of gold and silver coin came to light.
+
+At sight of these the joy of Jupiter could scarcely be restrained,
+but the countenance of his master wore an air of extreme
+disappointment.  He urged us, however, to continue our exertions,
+and the words were hardly uttered when I stumbled and fell forward,
+having caught the toe of my boot in a large ring of iron that lay
+half buried in the loose earth.
+
+We now worked in earnest, and never did I pass ten minutes of more
+intense excitement.  During this interval we had fairly unearthed
+an oblong chest of wood, which, from its perfect preservation and
+wonderful hardness, had plainly been subjected to some mineralizing
+process--perhaps that of the bichloride of mercury.  This box was
+three feet and a half long, three feet broad, and two and a half
+feet deep.  It was firmly secured by bands of wrought iron,
+riveted, and forming a kind of open trelliswork over the whole.  On
+each side of the chest, near the top, were three rings of iron--six
+in all--by means of which a firm hold could be obtained by six
+persons.  Our utmost united endeavors served only to disturb the
+coffer very slightly in its bed.  We at once saw the impossibility
+of removing so great a weight.  Luckily, the sole fastenings of the
+lid consisted of two sliding bolts.  These we drew back--trembling
+and panting with anxiety.  In an instant, a treasure of
+incalculable value lay gleaming before us.  As the rays of the
+lanterns fell within the pit, there flashed upward a glow and a
+glare, from a confused heap of gold and of jewels, that absolutely
+dazzled our eyes.
+
+I shall not pretend to describe the feelings with which I gazed.
+Amazement was, of course, predominant.  Legrand appeared exhausted
+with excitement, and spoke very few words.  Jupiter's countenance
+wore, for some minutes, as deadly a pallor as it is possible, in
+the nature of things, for any negro's visage to assume.  He seemed
+stupefied--thunderstricken.  Presently he fell upon his knees in
+the pit, and burying his naked arms up to the elbows in gold, let
+them there remain, as if enjoying the luxury of a bath.  At length,
+with a deep sigh, he exclaimed, as if in a soliloquy:
+
+"And dis all cum of de goole-bug! de putty goole-bug! de poor
+little goole-bug, what I boosed in that sabage kind oh style!
+Ain't you shamed oh yourself, nigger?--answer me dat!"
+
+It became necessary, at last, that I should arouse both master and
+valet to the expediency of removing the treasure.  It was growing
+late, and it behooved us to make exertion, that we might get
+everything housed before daylight.  It was difficult to say what
+should he done, and much time was spent in deliberation--so
+confused were the ideas of all.  We, finally, lightened the box by
+removing two thirds of its contents, when we were enabled, with
+some trouble, to raise it from the hole.  The articles taken out
+were deposited among the brambles, and the dog left to guard them,
+with strict orders from Jupiter neither, upon any pretense, to stir
+from the spot, nor to open his mouth until our return.  We then
+hurriedly made for home with the chest; reaching the hut in safety,
+but after excessive toil, at one o'clock in the morning.  Worn out
+as we were, it was not in human nature to do more immediately.  We
+rested until two, and had supper; starting for the hills
+immediately afterwards, armed with three stout sacks, which, by
+good luck, were upon the premises.  A little before four we arrived
+at the pit, divided the remainder of the booty, as equally as might
+be, among us, and, leaving the holes unfilled, again set out for
+the hut, at which, for the second time, we deposited our golden
+burdens, just as the first faint streaks of the dawn gleamed from
+over the treetops in the east.
+
+We were now thoroughly broken down; but the intense excitement of
+the time denied us repose.  After an unquiet slumber of some three
+or four hours' duration, we arose, as if by preconcert, to make
+examination of our treasure.
+
+The chest had been full to the brim, and we spent the whole day,
+and the greater part of the next night, in a scrutiny of its
+contents.  There had been nothing like order or arrangement.
+Everything had been heaped in promiscuously.  Having assorted all
+with care, we found ourselves possessed of even vaster wealth than
+we had at first supposed.  In coin there was rather more than four
+hundred and fifty thousand dollars--estimating the value of the
+pieces, as accurately as we could, by the tables of the period.
+There was not a particle of silver.  All was gold of antique date
+and of great variety--French, Spanish, and German money, with a few
+English guineas, and some counters, of which we had never seen
+specimens before.  There were several very large and heavy coins,
+so worn that we could make nothing of their inscriptions.  There
+was no American money.  The value of the jewels we found more
+difficulty in estimating.  There were diamonds--some of them
+exceedingly large and fine--a hundred and ten in all, and not one
+of them small; eighteen rubies of remarkable brilliancy;--three
+hundred and ten emeralds, all very beautiful; and twenty-one
+sapphires, with an opal.  These stones had all been broken from
+their settings and thrown loose in the chest.  The settings
+themselves, which we picked out from among the other gold, appeared
+to have been beaten up with hammers, as if to prevent
+identification.  Besides all this, there was a vast quantity of
+solid gold ornaments; nearly two hundred massive finger and ears
+rings; rich chains--thirty of these, if I remember; eighty-three
+very large and heavy crucifixes; five gold censers of great value;
+a prodigious golden punch bowl, ornamented with richly chased vine
+leaves and Bacchanalian figures; with two sword handles exquisitely
+embossed, and many other smaller articles which I cannot recollect.
+The weight of these valuables exceeded three hundred and fifty
+pounds avoirdupois; and in this estimate I have not included one
+hundred and ninety-seven superb gold watches; three of the number
+being worth each five hundred dollars, if one.  Many of them were
+very old, and as timekeepers valueless; the works having suffered,
+more or less, from corrosion--but all were richly jeweled and in
+cases of great worth.  We estimated the entire contents of the
+chest, that night, at a million and a half of dollars; and upon the
+subsequent disposal of the trinkets and jewels (a few being
+retained for our own use), it was found that we had greatly
+undervalued the treasure.
+
+When, at length, we had concluded our examination, and the intense
+excitement of the time had, in some measure, subsided, Legrand, who
+saw that I was dying with impatience for a solution of this most
+extraordinary riddle, entered into a full detail of all the
+circumstances connected with it.
+
+"You remember," said he, "the night when I handed you the rough
+sketch I had made of the scarabaeus.  You recollect, also, that I
+became quite vexed at you for insisting that my drawing resembled a
+death's head.  When you first made this assertion I thought you
+were jesting; but afterwards I called to mind the peculiar spots on
+the back of the insect, and admitted to myself that your remark had
+some little foundation in fact.  Still, the sneer at my graphic
+powers irritated me--for I am considered a good artist--and,
+therefore, when you handed me the scrap of parchment, I was about
+to crumple it up and throw it angrily into the fire."
+
+"The scrap of paper, you mean," said I.
+
+"No; it had much of the appearance of paper, and at first I
+supposed it to be such, but when I came to draw upon it, I
+discovered it at once to be a piece of very thin parchment.  It was
+quite dirty, you remember.  Well, as I was in the very act of
+crumpling it up, my glance fell upon the sketch at which you had
+been looking, and you may imagine my astonishment when I perceived,
+in fact, the figure of a death's head just where, it seemed to me,
+I had made the drawing of the beetle.  For a moment I was too much
+amazed to think with accuracy.  I knew that my design was very
+different in detail from this--although there was a certain
+similarity in general outline.  Presently I took a candle, and
+seating myself at the other end of the room, proceeded to
+scrutinize the parchment more closely.  Upon turning it over, I saw
+my own sketch upon the reverse, just as I had made it.  My first
+idea, now, was mere surprise at the really remarkable similarity of
+outline--at the singular coincidence involved in the fact that,
+unknown to me, there should have been a skull upon the other side
+of the parchment, immediately beneath my figure of the scarabaeus,
+and that this skull, not only in outline, but in size, should so
+closely resemble my drawing.  I say the singularity of this
+coincidence absolutely stupefied me for a time.  This is the usual
+effect of such coincidences.  The mind struggles to establish a
+connection--a sequence of cause and effect--and, being unable to do
+so, suffers a species of temporary paralysis.  But, when I
+recovered from this stupor, there dawned upon me gradually a
+conviction which startled me even far more than the coincidence.  I
+began distinctly, positively, to remember that there had been NO
+drawing upon the parchment, when I made my sketch of the
+scarabaeus.  I became perfectly certain of this; for I recollected
+turning up first one side and then the other, in search of the
+cleanest spot.  Had the skull been then there, of course I could
+not have failed to notice it.  Here was indeed a mystery which I
+felt it impossible to explain; but, even at that early moment,
+there seemed to glimmer, faintly, within the most remote and secret
+chambers of my intellect, a glow-wormlike conception of that truth
+which last night's adventure brought to so magnificent a
+demonstration.  I arose at once, and putting the parchment securely
+away, dismissed all further reflection until I should be alone.
+
+"When you had gone, and when Jupiter was fast asleep, I betook
+myself to a more methodical investigation of the affair.  In the
+first place I considered the manner in which the parchment had come
+into my possession.  The spot where we discovered the scarabaeus
+was on the coast of the mainland, about a mile eastward of the
+island, and but a short distance above high-water mark.  Upon my
+taking hold of it, it gave me a sharp bite, which caused me to let
+it drop.  Jupiter, with his accustomed caution, before seizing the
+insect, which had flown toward him, looked about him for a leaf, or
+something of that nature, by which to take hold of it.  It was at
+this moment that his eyes, and mine also, fell upon the scrap of
+parchment, which I then supposed to be paper.  It was lying half
+buried in the sand, a corner sticking up.  Near the spot where we
+found it, I observed the remnants of the hull of what appeared to
+have been a ship's longboat.  The wreck seemed to have been there
+for a very great while, for the resemblance to boat timbers could
+scarcely be traced.
+
+"Well, Jupiter picked up the parchment, wrapped the beetle in it,
+and gave it to me.  Soon afterwards we turned to go home, and on
+the way met Lieutenant G----.  I showed him the insect, and he
+begged me to let him take it to the fort.  Upon my consenting, he
+thrust it forthwith into his waistcoat pocket, without the
+parchment in which it had been wrapped, and which I had continued
+to hold in my hand during his inspection.  Perhaps he dreaded my
+changing my mind, and thought it best to make sure of the prize at
+once--you know how enthusiastic he is on all subjects connected
+with Natural History.  At the same time, without being conscious of
+it, I must have deposited the parchment in my own pocket.
+
+"You remember that when I went to the table, for the purpose of
+making a sketch of the beetle, I found no paper where it was
+usually kept.  I looked in the drawer, and found none there.  I
+searched my pockets, hoping to find an old letter, when my hand
+fell upon the parchment.  I thus detail the precise mode in which
+it came into my possession, for the circumstances impressed me with
+peculiar force.
+
+"No doubt you will think me fanciful--but I had already established
+a kind of CONNECTION.  I had put together two links of a great
+chain.  There was a boat lying upon a seacoast, and not far from
+the boat was a parchment--NOT A PAPER--with a skull depicted upon
+it.  You will, of course, ask 'where is the connection?'  I reply
+that the skull, or death's head, is the well-known emblem of the
+pirate.  The flag of the death's head is hoisted in all
+engagements.
+
+"I have said that the scrap was parchment, and not paper.
+Parchment is durable--almost imperishable.  Matters of little
+moment are rarely consigned to parchment; since, for the mere
+ordinary purposes of drawing or writing, it is not nearly so well
+adapted as paper.  This reflection suggested some meaning--some
+relevancy--in the death's head.  I did not fail to observe, also,
+the FORM of the parchment.  Although one of its corners had been,
+by some accident, destroyed, it could be seen that the original
+form was oblong.  It was just such a slip, indeed, as might have
+been chosen for a memorandum--for a record of something to be long
+remembered, and carefully preserved."
+
+"But," I interposed, "you say that the skull was NOT upon the
+parchment when you made the drawing of the beetle.  How then do you
+trace any connection between the boat and the skull--since this
+latter, according to your own admission, must have been designed
+(God only knows how or by whom) at some period subsequent to your
+sketching the scarabaeus?"
+
+"Ah, hereupon turns the whole mystery; although the secret, at this
+point, I had comparatively little difficulty in solving.  My steps
+were sure, and could afford but a single result.  I reasoned, for
+example, thus: When I drew the scarabaeus, there was no skull
+apparent upon the parchment.  When I had completed the drawing I
+gave it to you, and observed you narrowly until you returned it.
+YOU, therefore, did not design the skull, and no one else was
+present to do it.  Then it was not done by human agency.  And
+nevertheless it was done.
+
+"At this stage of my reflections I endeavored to remember, and DID
+remember, with entire distinctness, every incident which occurred
+about the period in question.  The weather was chilly (oh, rare and
+happy accident!), and a fire was blazing upon the hearth.  I was
+heated with exercise and sat near the table.  You, however, had
+drawn a chair close to the chimney.  Just as I placed the parchment
+in your hand, and as you were in the act of inspecting it, Wolf,
+the Newfoundland, entered, and leaped upon your shoulders.  With
+your left hand you caressed him and kept him off, while your right,
+holding the parchment, was permitted to fall listlessly between
+your knees, and in close proximity to the fire.  At one moment I
+thought the blaze had caught it, and was about to caution you, but,
+before I could speak, you had withdrawn it, and were engaged in its
+examination.  When I considered all these particulars, I doubted
+not for a moment that HEAT had been the agent in bringing to light,
+upon the parchment, the skull which I saw designed upon it.  You
+are well aware that chemical preparations exist, and have existed
+time out of mind, by means of which it is possible to write upon
+either paper or vellum, so that the characters shall become visible
+only when subjected to the action of fire.  Zaffre, digested in
+aqua regia, and diluted with four times its weight of water, is
+sometimes employed; a green tint results.  The regulus of cobalt,
+dissolved in spirit of niter, gives a red.  These colors disappear
+at longer or shorter intervals after the material written upon
+cools, but again become apparent upon the reapplication of heat.
+
+"I now scrutinized the death's head with care.  Its outer edges--
+the edges of the drawing nearest the edge of the vellum--were far
+more DISTINCT than the others.  It was clear that the action of the
+caloric had been imperfect or unequal.  I immediately kindled a
+fire, and subjected every portion of the parchment to a glowing
+heat.  At first, the only effect was the strengthening of the faint
+lines in the skull; but, upon persevering in the experiment, there
+became visible, at the corner of the slip, diagonally opposite to
+the spot in which the death's head was delineated, the figure of
+what I at first supposed to be a goat.  A closer scrutiny, however,
+satisfied me that it was intended for a kid."
+
+"Ha! ha!" said I, "to be sure I have no right to laugh at you--a
+million and a half of money is too serious a matter for mirth--but
+you are not about to establish a third link in your chain--you will
+not find any especial connection between your pirates and a goat--
+pirates, you know, have nothing to do with goats; they appertain to
+the farming interest."
+
+"But I have just said that the figure was NOT that of a goat."
+
+"Well, a kid then--pretty much the same thing."
+
+"Pretty much, but not altogether," said Legrand.  "You may have
+heard of one CAPTAIN Kidd.  I at once looked upon the figure of the
+animal as a kind of punning or hieroglyphical signature.  I say
+signature; because its position upon the vellum suggested this
+idea.  The death's head at the corner diagonally opposite, had, in
+the same manner, the air of a stamp, or seal.  But I was sorely put
+out by the absence of all else--of the body to my imagined
+instrument--of the text for my context."
+
+"I presume you expected to find a letter between the stamp and the
+signature."
+
+"Something of that kind.  The fact is, I felt irresistibly
+impressed with a presentiment of some vast good fortune impending.
+I can scarcely say why.  Perhaps, after all, it was rather a desire
+than an actual belief;--but do you know that Jupiter's silly words,
+about the bug being of solid gold, had a remarkable effect upon my
+fancy?  And then the series of accidents and coincidents--these
+were so VERY extraordinary.  Do you observe how mere an accident it
+was that these events should have occurred upon the SOLE day of all
+the year in which it has been, or may be sufficiently cool for
+fire, and that without the fire, or without the intervention of the
+dog at the precise moment in which he appeared, I should never have
+become aware of the death's head, and so never the possessor of the
+treasure?"
+
+"But proceed--I am all impatience."
+
+"Well; you have heard, of course, the many stories current--the
+thousand vague rumors afloat about money buried, somewhere upon the
+Atlantic coast, by Kidd and his associates.  These rumors must have
+had some foundation in fact.  And that the rumors have existed so
+long and so continuous, could have resulted, it appeared to me,
+only from the circumstance of the buried treasures still REMAINING
+entombed.  Had Kidd concealed his plunder for a time, and
+afterwards reclaimed it, the rumors would scarcely have reached us
+in their present unvarying form.  You will observe that the stories
+told are all about money-seekers, not about money-finders.  Had the
+pirate recovered his money, there the affair would have dropped.
+It seemed to me that some accident--say the loss of a memorandum
+indicating its locality--had deprived him of the means of
+recovering it, and that this accident had become known to his
+followers, who otherwise might never have heard that the treasure
+had been concealed at all, and who, busying themselves in vain,
+because unguided, attempts to regain it, had given first birth, and
+then universal currency, to the reports which are now so common.
+Have you ever heard of any important treasure being unearthed along
+the coast?"
+
+"Never."
+
+"But that Kidd's accumulations were immense, is well known.  I took
+it for granted, therefore, that the earth still held them; and you
+will scarcely be surprised when I tell you that I felt a hope,
+nearly amounting to certainty, that the parchment so strangely
+found involved a lost record of the place of deposit."
+
+"But how did you proceed?"
+
+"I held the vellum again to the fire, after increasing the heat,
+but nothing appeared.  I now thought it possible that the coating
+of dirt might have something to do with the failure: so I carefully
+rinsed the parchment by pouring warm water over it, and, having
+done this, I placed it in a tin pan, with the skull downward, and
+put the pan upon a furnace of lighted charcoal.  In a few minutes,
+the pan having become thoroughly heated, I removed the slip, and,
+to my inexpressible joy, found it spotted, in several places, with
+what appeared to be figures arranged in lines.  Again I placed it
+in the pan, and suffered it to remain another minute.  Upon taking
+it off, the whole was just as you see it now."
+
+Here Legrand, having reheated the parchment, submitted it to my
+inspection.  The following characters were rudely traced, in a red
+tint, between the death's head and the goat:
+
+
+"53++!305))6*;4826)4+)4+).;806*;48!8]60))85;1+8*:+(;:+*8!83(88)5*!;
+46(;88*96*?;8)*+(;485);5*!2:*+(;4956*2(5*-4)8]8*;4069285);)6!8)4++;
+1(+9;48081;8:8+1;48!85;4)485!528806*81(+9;48;(88;4(+?34;48)4+;161;:
+188;+?;"
+
+
+"But," said I, returning him the slip, "I am as much in the dark as
+ever.  Were all the jewels of Golconda awaiting me upon my solution
+of this enigma, I am quite sure that I should be unable to earn
+them."
+
+"And yet," said Legrand, "the solution is by no means so difficult
+as you might be led to imagine from the first hasty inspection of
+the characters.  These characters, as anyone might readily guess,
+form a cipher--that is to say, they convey a meaning; but then from
+what is known of Kidd, I could not suppose him capable of
+constructing any of the more abstruse cryptographs.  I made up my
+mind, at once, that this was of a simple species--such, however, as
+would appear, to the crude intellect of the sailor, absolutely
+insoluble without the key."
+
+"And you really solved it?"
+
+"Readily; I have solved others of an abstruseness ten thousand
+times greater.  Circumstances, and a certain bias of mind, have led
+me to take interest in such riddles, and it may well be doubted
+whether human ingenuity can construct an enigma of the kind which
+human ingenuity may not, by proper application, resolve.  In fact,
+having once established connected and legible characters, I
+scarcely gave a thought to the mere difficulty of developing their
+import.
+
+"In the present case--indeed in all cases of secret writing--the
+first question regards the LANGUAGE of the cipher; for the
+principles of solution, so far, especially, as the more simple
+ciphers are concerned, depend upon, and are varied by, the genius
+of the particular idiom.  In general, there is no alternative but
+experiment (directed by probabilities) of every tongue known to him
+who attempts the solution, until the true one be attained.  But,
+with the cipher now before us, all difficulty was removed by the
+signature.  The pun upon the word 'Kidd' is appreciable in no other
+language than the English.  But for this consideration I should
+have begun my attempts with the Spanish and French, as the tongues
+in which a secret of this kind would most naturally have been
+written by a pirate of the Spanish main.  As it was, I assumed the
+cryptograph to be English.
+
+"You observe there are no divisions between the words.  Had there
+been divisions the task would have been comparatively easy.  In
+such cases I should have commenced with a collation and analysis of
+the shorter words, and, had a word of a single letter occurred, as
+is most likely, (a or I, for example,) I should have considered the
+solution as assured.  But, there being no division, my first step
+was to ascertain the predominant letters, as well as the least
+frequent.  Counting all, I constructed a table thus:
+
+
+Of the character 8 there are 33.
+                 ;     "     26.
+                 4     "     19.
+                +)     "     16.
+                 *     "     13.
+                 5     "     12.
+                 6     "     11.
+                !1     "      8.
+                 0     "      6.
+                92     "      5.
+                :3     "      4.
+                 ?     "      3.
+                 ]     "      2.
+                -.     "      1.
+
+
+"Now, in English, the letter which most frequently occurs is e.
+Afterwards, the succession runs thus: a o i d h n r s t u y c f g l
+m w b k p q x z.  E predominates so remarkably, that an individual
+sentence of any length is rarely seen, in which it is not the
+prevailing character.
+
+"Here, then, we have, in the very beginning, the groundwork for
+something more than a mere guess.  The general use which may be
+made of the table is obvious--but, in this particular cipher, we
+shall only very partially require its aid.  As our predominant
+character is 8, we will commence by assuming it as the e of the
+natural alphabet.  To verify the supposition, let us observe if the
+8 be seen often in couples--for e is doubled with great frequency
+in English--in such words, for example, as 'meet,' 'fleet,'
+'speed,' 'seen,' 'been,' 'agree,' etc.  In the present instance we
+see it doubled no less than five times, although the cryptograph is
+brief.
+
+"Let us assume 8, then, as e.  Now, of all WORDS in the language,
+'the' is most usual; let us see, therefore, whether there are not
+repetitions of any three characters, in the same order of
+collocation, the last of them being 8.  If we discover repetitions
+of such letters, so arranged, they will most probably represent the
+word 'the.'  Upon inspection, we find no less than seven such
+arrangements, the characters being ;48.  We may, therefore, assume
+that ; represents t, 4 represents h, and 8 represents e--the last
+being now well confirmed.  Thus a great step has been taken.
+
+"But, having established a single word, we are enabled to establish
+a vastly important point; that is to say, several commencements and
+terminations of other words.  Let us refer, for example, to the
+last instance but one, in which the combination ;48 occurs--not far
+from the end of the cipher.  We know that the ; immediately ensuing
+is the commencement of a word, and, of the six characters
+succeeding this 'the,' we are cognizant of no less than five.  Let
+us set these characters down, thus, by the letters we know them to
+represent, leaving a space for the unknown--
+
+
+t eeth.
+
+
+"Here we are enabled, at once, to discard the 'th,' as forming no
+portion of the word commencing with the first t; since, by
+experiment of the entire alphabet for a letter adapted to the
+vacancy, we perceive that no word can be formed of which this th
+can be a part.  We are thus narrowed into
+
+
+t ee,
+
+
+and, going through the alphabet, if necessary, as before, we arrive
+at the word 'tree,' as the sole possible reading.  We thus gain
+another letter, r, represented by (, with the words 'the tree' in
+juxtaposition.
+
+"Looking beyond these words, for a short distance, we again see the
+combination ;48, and employ it by way of TERMINATION to what
+immediately precedes.  We have thus this arrangement:
+
+
+the tree ;4(4+?34 the,
+
+
+or, substituting the natural letters, where known, it reads thus:
+
+
+the tree thr+?3h the.
+
+
+"Now, if, in place of the unknown characters, we leave blank
+spaces, or substitute dots, we read thus:
+
+
+the tree thr...h the,
+
+
+when the word 'through' makes itself evident at once.  But this
+discovery gives us three new letters, o, u, and g, represented by
++, ?, and 3.
+
+"Looking now, narrowly, through the cipher for combinations of
+known characters, we find, not very far from the beginning, this
+arrangement,
+
+
+83(88, or egree,
+
+
+which plainly, is the conclusion of the word 'degree,' and gives us
+another letter, d, represented by !.
+
+"Four letters beyond the word 'degree,' we perceive the combination
+
+
+;46(;88.
+
+
+"Translating the known characters, and representing the unknown by
+dots, as before, we read thus:
+
+
+th.rtee,
+
+
+an arrangement immediately suggestive of the word thirteen,' and
+again furnishing us with two new characters, i and n, represented
+by 6 and *.
+
+"Referring, now, to the beginning of the cryptograph, we find the
+combination,
+
+
+53++!.
+
+
+"Translating as before, we obtain
+
+
+.good,
+
+
+which assures us that the first letter is A, and that the first two
+words are 'A good.'
+
+"It is now time that we arrange our key, as far as discovered, in a
+tabular form, to avoid confusion.  It will stand thus:
+
+
+5 represents a
+!     "      d
+8     "      e
+3     "      g
+4     "      h
+6     "      i
+*     "      n
++     "      o
+(     "      r
+;     "      t
+?     "      u
+
+
+"We have, therefore, no less than eleven of the most important
+letters represented, and it will be unnecessary to proceed with the
+details of the solution.  I have said enough to convince you that
+ciphers of this nature are readily soluble, and to give you some
+insight into the rationale of their development.  But be assured
+that the specimen before us appertains to the very simplest species
+of cryptograph.  It now only remains to give you the full
+translation of the characters upon the parchment, as unriddled.
+Here it is:
+
+
+"'A good glass in the bishop's hostel in the devil's seat forty-one
+degrees and thirteen minutes northeast and by north main branch
+seventh limb east side shoot from the left eye of the death's head
+a bee-line from the tree through the shot fifty feet out.'"
+
+
+"But," said I, "the enigma seems still in as bad a condition as
+ever.  How is it possible to extort a meaning from all this jargon
+about 'devil's seats,' 'death's heads,' and 'bishop's hostels'?"
+
+"I confess," replied Legrand, "that the matter still wears a
+serious aspect, when regarded with a casual glance.  My first
+endeavor was to divide the sentence into the natural division
+intended by the cryptographist."
+
+"You mean, to punctuate it?"
+
+"Something of that kind."
+
+"But how was it possible to effect this?"
+
+"I reflected that it had been a POINT with the writer to run his
+words together without division, so as to increase the difficulty
+of solution.  Now, a not overacute man, in pursuing such an object,
+would be nearly certain to overdo the matter.  When, in the course
+of his composition, he arrived at a break in his subject which
+would naturally require a pause, or a point, he would be
+exceedingly apt to run his characters, at this place, more than
+usually close together.  If you will observe the MS., in the
+present instance, you will easily detect five such cases of unusual
+crowding.  Acting upon this hint I made the division thus:
+
+
+"'A good glass in the bishop's hostel in the devil's seat--forty-
+one degrees and thirteen minutes--northeast and by north--main
+branch seventh limb east side--shoot from the left eye of the
+death's head--a bee-line from the tree through the shot fifty feet
+out.'"
+
+
+"Even this division," said I, "leaves me still in the dark."
+
+"It left me also in the dark," replied Legrand, "for a few days;
+during which I made diligent inquiry in the neighborhood of
+Sullivan's Island, for any building which went by name of the
+'Bishop's Hotel'; for, of course, I dropped the obsolete word
+'hostel.'  Gaining no information on the subject, I was on the
+point of extending my sphere of search, and proceeding in a more
+systematic manner, when, one morning, it entered into my head,
+quite suddenly, that this 'Bishop's Hostel' might have some
+reference to an old family, of the name of Bessop, which, time out
+of mind, had held possession of an ancient manor house, about four
+miles to the northward of the island.  I accordingly went over to
+the plantation, and reinstituted my inquiries among the older
+negroes of the place.  At length one of the most aged of the women
+said that she had heard of such a place as Bessop's Castle, and
+thought that she could guide me to it, but that it was not a
+castle, nor a tavern, but a high rock.
+
+"I offered to pay her well for her trouble, and, after some demur,
+she consented to accompany me to the spot.  We found it without
+much difficulty, when, dismissing her, I proceeded to examine the
+place.  The 'castle' consisted of an irregular assemblage of cliffs
+and rocks--one of the latter being quite remarkable for its height
+as well as for its insulated and artificial appearance.  I
+clambered to its apex, and then felt much at a loss as to what
+should be next done.
+
+"While I was busied in reflection, my eyes fell upon a narrow ledge
+in the eastern face of the rock, perhaps a yard below the summit
+upon which I stood.  This ledge projected about eighteen inches,
+and was not more than a foot wide, while a niche in the cliff just
+above it gave it a rude resemblance to one of the hollow-backed
+chairs used by our ancestors.  I made no doubt that here was the
+'devil's seat' alluded to in the MS., and now I seemed to grasp the
+full secret of the riddle.
+
+"The 'good glass,' I knew, could have reference to nothing but a
+telescope; for the word 'glass' is rarely employed in any other
+sense by seamen.  Now here, I at once saw, was a telescope to be
+used, and a definite point of view, ADMITTING NO VARIATION, from
+which to use it.  Nor did I hesitate to believe that the phrases,
+'forty-one degrees and thirteen minutes,' and 'northeast and by
+north,' were intended as directions for the leveling of the glass.
+Greatly excited by these discoveries, I hurried home, procured a
+telescope, and returned to the rock.
+
+"I let myself down to the ledge, and found that it was impossible
+to retain a seat upon it except in one particular position.  This
+fact confirmed my preconceived idea.  I proceeded to use the glass.
+Of course, the 'forty-one degrees and thirteen minutes' could
+allude to nothing but elevation above the visible horizon, since
+the horizontal direction was clearly indicated by the words,
+'northeast and by north.'  This latter direction I at once
+established by means of a pocket compass; then, pointing the glass
+as nearly at an angle of forty-one degrees of elevation as I could
+do it by guess, I moved it cautiously up or down, until my
+attention was arrested by a circular rift or opening in the foliage
+of a large tree that overtopped its fellows in the distance.  In
+the center of this rift I perceived a white spot, but could not, at
+first, distinguish what it was.  Adjusting the focus of the
+telescope, I again looked, and now made it out to be a human skull.
+
+"Upon this discovery I was so sanguine as to consider the enigma
+solved; for the phrase 'main branch, seventh limb, east side,'
+could refer only to the position of the skull upon the tree, while
+'shoot from the left eye of the death's head' admitted, also, of
+but one interpretation, in regard to a search for buried treasure.
+I perceived that the design was to drop a bullet from the left eye
+of the skull, and that a bee-line, or, in other words, a straight
+line, drawn from the nearest point of the trunk 'through the shot'
+(or the spot where the bullet fell), and thence extended to a
+distance of fifty feet, would indicate a definite point--and
+beneath this point I thought it at least POSSIBLE that a deposit of
+value lay concealed."
+
+"All this," I said, "is exceedingly clear, and, although ingenious,
+still simple and explicit.  When you left the Bishop's Hotel, what
+then?"
+
+"Why, having carefully taken the bearings of the tree, I turned
+homeward.  The instant that I left 'the devil's seat,' however, the
+circular rift vanished; nor could I get a glimpse of it afterwards,
+turn as I would.  What seems to me the chief ingenuity in this
+whole business, is the fact (for repeated experiment has convinced
+me it IS a fact) that the circular opening in question is visible
+from no other attainable point of view than that afforded by the
+narrow ledge upon the face of the rock.
+
+"In this expedition to the 'Bishop's Hotel' I had been attended by
+Jupiter, who had, no doubt, observed, for some weeks past, the
+abstraction of my demeanor, and took especial care not to leave me
+alone.  But, on the next day, getting up very early, I contrived to
+give him the slip, and went into the hills in search of the tree.
+After much toil I found it.  When I came home at night my valet
+proposed to give me a flogging.  With the rest of the adventure I
+believe you are as well acquainted as myself."
+
+"I suppose," said I, "you missed the spot, in the first attempt at
+digging, through Jupiter's stupidity in letting the bug fall
+through the right instead of through the left eye of the skull."
+
+"Precisely.  This mistake made a difference of about two inches and
+a half in the 'shot'--that is to say, in the position of the peg
+nearest the tree; and had the treasure been BENEATH the 'shot,' the
+error would have been of little moment; but 'the shot,' together
+with the nearest point of the tree, were merely two points for the
+establishment of a line of direction; of course the error, however
+trivial in the beginning, increased as we proceeded with the line,
+and by the time we had gone fifty feet threw us quite off the
+scent.  But for my deep-seated impressions that treasure was here
+somewhere actually buried, we might have had all our labor in
+vain."
+
+"But your grandiloquence, and your conduct in swinging the beetle--
+how excessively odd!  I was sure you were mad.  And why did you
+insist upon letting fall the bug, instead of a bullet, from the
+skull?"
+
+"Why, to be frank, I felt somewhat annoyed by your evident
+suspicions touching my sanity, and so resolved to punish you
+quietly, in my own way, by a little bit of sober mystification.
+For this reason I swung the beetle, and for this reason I let it
+fall from the tree.  An observation of yours about its great weight
+suggested the latter idea."
+
+"Yes, I perceive; and now there is only one point which puzzles me.
+What are we to make of the skeletons found in the hole?"
+
+"That is a question I am no more able to answer than yourself.
+There seems, however, only one plausible way of accounting for
+them--and yet it is dreadful to believe in such atrocity as my
+suggestion would imply.  It is clear that Kidd--if Kidd indeed
+secreted this treasure, which I doubt not--it is clear that he must
+have had assistance in the labor.  But this labor concluded, he may
+have thought it expedient to remove all participants in his secret.
+Perhaps a couple of blows with a mattock were sufficient, while his
+coadjutors were busy in the pit; perhaps it required a dozen--who
+shall tell?"
diff --git a/testsuite/hmac-test.c b/testsuite/hmac-test.c
new file mode 100644 (file)
index 0000000..0f14934
--- /dev/null
@@ -0,0 +1,905 @@
+#include "testutils.h"
+#include "hmac.h"
+
+/* KEY and MSG are supposed to expand to length, data */ 
+#define HMAC_TEST(alg, length, key, msg, mac) do {             \
+  hmac_##alg##_set_key(&alg, key);                             \
+  hmac_##alg##_update(&alg, msg);                              \
+  digest[length] = 17;                                         \
+  hmac_##alg##_digest(&alg, length, digest);                   \
+  ASSERT(MEMEQ (length, digest, mac));                         \
+  ASSERT(digest[length] == 17);                                        \
+} while (0)
+
+int
+test_main(void)
+{
+  struct hmac_md5_ctx md5;
+  struct hmac_sha1_ctx sha1;
+  struct hmac_ripemd160_ctx ripemd160;
+  struct hmac_sha224_ctx sha224;
+  struct hmac_sha256_ctx sha256;
+  struct hmac_sha384_ctx sha384;
+  struct hmac_sha512_ctx sha512;
+
+  /* sha512's digests are longest */
+  uint8_t digest[SHA512_DIGEST_SIZE+1];
+
+  memset(digest, 0, sizeof(digest));
+
+  /* Test vectors for md5, from RFC-2202 */
+
+  /* md5 - 1 */
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           HL("0b0b0b0b0b0b0b0b 0b0b0b0b0b0b0b0b"),
+           LDATA("Hi There"),
+           H("9294727a3638bb1c 13f48ef8158bfc9d"));
+
+
+  /* md5 - 2 */
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           LDATA("Jefe"),
+           LDATA("what do ya want for nothing?"),
+           H("750c783e6ab0b503 eaa86e310a5db738"));        
+
+  /* md5 - 3 */
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"),
+           HL("dddddddddddddddd dddddddddddddddd"
+              "dddddddddddddddd dddddddddddddddd"
+              "dddddddddddddddd dddddddddddddddd"
+              "dddd"),
+           H("56be34521d144c88 dbb8c733f0e8b3f6"));
+  
+  /* md5 - 4 */
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           HL("0102030405060708 090a0b0c0d0e0f10" 
+              "1112131415161718 19"),
+           HL("cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd"
+              "cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd"
+              "cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd"
+              "cdcd"),
+           H("697eaf0aca3a3aea 3a75164746ffaa79"));
+
+  /* md5 - 5 */
+  HMAC_TEST(md5, 12,
+           HL("0c0c0c0c0c0c0c0c 0c0c0c0c0c0c0c0c"),
+           LDATA("Test With Truncation"),
+           H("56461ef2342edc00 f9bab995"));
+
+  /* md5 - 6 */
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"),
+           LDATA("Test Using Larger Than Block-Size Key - Hash Key First"),
+           H("6b1ab7fe4bd7bf8f 0b62e6ce61b9d0cd"));
+
+  /* md5 - 7 */
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"),
+           LDATA("Test Using Larger Than Block-Size Key and Larger "
+                 "Than One Block-Size Data"),
+           H("6f630fad67cda0ee 1fb1f562db3aa53e"));
+
+  /* Additional test vectors, from Daniel Kahn Gillmor */
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA(""),
+           H("e84db42a188813f30a15e611d64c7869"));
+  
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("a"),
+           H("123662062e67c2aab371cc49db0df134"));
+  
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("38"),
+           H("0a46cc10a49d4b7025c040c597bf5d76"));
+  
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("abc"),
+           H("d1f4d89f0e8b2b6ed0623c99ec298310"));
+  
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("message digest"),
+           H("1627207b9bed5009a4f6e9ca8d2ca01e"));
+  
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("abcdefghijklmnopqrstuvwxyz"),
+           H("922aae6ab3b3a29202e21ce5f916ae9a"));
+
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
+           H("ede9cb83679ba82d88fbeae865b3f8fc"));
+
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("12345678901234567890123456789012345678901234567890123456789012345678901234567890"),
+           H("939dd45512ee3a594b6654f6b8de27f7"));
+
+  /* Test vectors for ripemd160, from
+     http://homes.esat.kuleuven.be/~bosselae/ripemd160.html */
+  HMAC_TEST(ripemd160, RIPEMD160_DIGEST_SIZE,
+           HL("00112233445566778899aabbccddeeff01234567"),
+           LDATA(""),
+           H("cf387677bfda8483e63b57e06c3b5ecd8b7fc055"));
+
+  HMAC_TEST(ripemd160, RIPEMD160_DIGEST_SIZE,
+           HL("00112233445566778899aabbccddeeff01234567"),
+           LDATA("a"),
+           H("0d351d71b78e36dbb7391c810a0d2b6240ddbafc"));
+
+  HMAC_TEST(ripemd160, RIPEMD160_DIGEST_SIZE,
+           HL("00112233445566778899aabbccddeeff01234567"),
+           LDATA("abc"),
+           H("f7ef288cb1bbcc6160d76507e0a3bbf712fb67d6"));
+
+  HMAC_TEST(ripemd160, RIPEMD160_DIGEST_SIZE,
+           HL("00112233445566778899aabbccddeeff01234567"),
+           LDATA("message digest"),
+           H("f83662cc8d339c227e600fcd636c57d2571b1c34"));
+
+  HMAC_TEST(ripemd160, RIPEMD160_DIGEST_SIZE,
+           HL("00112233445566778899aabbccddeeff01234567"),
+           LDATA("abcdefghijklmnopqrstuvwxyz"),
+           H("843d1c4eb880ac8ac0c9c95696507957d0155ddb"));
+
+  HMAC_TEST(ripemd160, RIPEMD160_DIGEST_SIZE,
+           HL("00112233445566778899aabbccddeeff01234567"),
+           LDATA("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"),
+           H("60f5ef198a2dd5745545c1f0c47aa3fb5776f881"));
+
+  HMAC_TEST(ripemd160, RIPEMD160_DIGEST_SIZE,
+           HL("00112233445566778899aabbccddeeff01234567"),
+           LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
+           H("e49c136a9e5627e0681b808a3b97e6a6e661ae79"));
+
+  /* Other key */
+  HMAC_TEST(ripemd160, RIPEMD160_DIGEST_SIZE,
+           HL("0123456789abcdeffedcba987654321000112233"),
+           LDATA(""),
+           H("fe69a66c7423eea9c8fa2eff8d9dafb4f17a62f5"));
+
+  HMAC_TEST(ripemd160, RIPEMD160_DIGEST_SIZE,
+           HL("0123456789abcdeffedcba987654321000112233"),
+           LDATA("a"),
+           H("85743e899bc82dbfa36faaa7a25b7cfd372432cd"));
+
+  HMAC_TEST(ripemd160, RIPEMD160_DIGEST_SIZE,
+           HL("0123456789abcdeffedcba987654321000112233"),
+           LDATA("abc"),
+           H("6e4afd501fa6b4a1823ca3b10bd9aa0ba97ba182"));
+
+  HMAC_TEST(ripemd160, RIPEMD160_DIGEST_SIZE,
+           HL("0123456789abcdeffedcba987654321000112233"),
+           LDATA("message digest"),
+           H("2e066e624badb76a184c8f90fba053330e650e92"));
+
+  HMAC_TEST(ripemd160, RIPEMD160_DIGEST_SIZE,
+           HL("0123456789abcdeffedcba987654321000112233"),
+           LDATA("abcdefghijklmnopqrstuvwxyz"),
+           H("07e942aa4e3cd7c04dedc1d46e2e8cc4c741b3d9"));
+
+  HMAC_TEST(ripemd160, RIPEMD160_DIGEST_SIZE,
+           HL("0123456789abcdeffedcba987654321000112233"),
+           LDATA("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"),
+           H("b6582318ddcfb67a53a67d676b8ad869aded629a"));
+
+  HMAC_TEST(ripemd160, RIPEMD160_DIGEST_SIZE,
+           HL("0123456789abcdeffedcba987654321000112233"),
+           LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
+           H("f1be3ee877703140d34f97ea1ab3a07c141333e2"));
+
+  /* Test vectors for sha1, from RFC-2202 */
+
+  /* sha1 - 1 */
+  HMAC_TEST(sha1, SHA1_DIGEST_SIZE,
+           HL("0b0b0b0b0b0b0b0b 0b0b0b0b0b0b0b0b 0b0b0b0b"),
+           LDATA("Hi There"),
+           H("b617318655057264 e28bc0b6fb378c8e f146be00"));
+
+  /* sha1 - 2 */
+  HMAC_TEST(sha1, SHA1_DIGEST_SIZE,
+           LDATA("Jefe"),
+           LDATA("what do ya want for nothing?"),
+           H("effcdf6ae5eb2fa2 d27416d5f184df9c 259a7c79"));
+
+  /* sha1 - 3 */
+  HMAC_TEST(sha1, SHA1_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaa"),
+           HL("dddddddddddddddd dddddddddddddddd"
+              "dddddddddddddddd dddddddddddddddd"
+              "dddddddddddddddd dddddddddddddddd"
+              "dddd"),
+           H("125d7342b9ac11cd 91a39af48aa17b4f 63f175d3"));
+
+  /* sha1 - 4 */
+  HMAC_TEST(sha1, SHA1_DIGEST_SIZE,
+           HL("0102030405060708 090a0b0c0d0e0f10" 
+              "1112131415161718 19"),
+           HL("cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd"
+              "cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd"
+              "cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd"
+              "cdcd"),
+           H("4c9007f4026250c6 bc8414f9bf50c86c 2d7235da"));
+
+  /* sha1 - 5 */
+  HMAC_TEST(sha1, 12,
+           HL("0c0c0c0c0c0c0c0c 0c0c0c0c0c0c0c0c 0c0c0c0c"),
+           LDATA("Test With Truncation"),
+           H("4c1a03424b55e07f e7f27be1"));
+
+  /* sha1 - 6 */
+  HMAC_TEST(sha1, SHA1_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"),
+           LDATA("Test Using Larger Than Block-Size Key - Hash Key First"),
+           H("aa4ae5e15272d00e 95705637ce8a3b55 ed402112"));
+
+  /* sha1 - 7 */
+  HMAC_TEST(sha1, SHA1_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"),
+           LDATA("Test Using Larger Than Block-Size Key and Larger "
+                 "Than One Block-Size Data"),
+           H("e8e99d0f45237d78 6d6bbaa7965c7808 bbff1a91"));
+
+  /* Additional test vectors, from Daniel Kahn Gillmor */
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA(""),
+           H("e84db42a188813f30a15e611d64c7869"));
+  
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("a"),
+           H("123662062e67c2aab371cc49db0df134"));
+  
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("38"),
+           H("0a46cc10a49d4b7025c040c597bf5d76"));
+  
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("abc"),
+           H("d1f4d89f0e8b2b6ed0623c99ec298310"));
+  
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("message digest"),
+           H("1627207b9bed5009a4f6e9ca8d2ca01e"));
+  
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("abcdefghijklmnopqrstuvwxyz"),
+           H("922aae6ab3b3a29202e21ce5f916ae9a"));
+
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
+           H("ede9cb83679ba82d88fbeae865b3f8fc"));
+
+  HMAC_TEST(md5, MD5_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("12345678901234567890123456789012345678901234567890123456789012345678901234567890"),
+           H("939dd45512ee3a594b6654f6b8de27f7"));
+
+  /* Test vectors for sha224, from RFC 4231 */
+  HMAC_TEST(sha224, SHA224_DIGEST_SIZE,
+           HL("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"
+              "0b0b0b0b"),
+           LDATA("Hi There"),
+           H("896fb1128abbdf196832107cd49df33f"
+             "47b4b1169912ba4f53684b22"));
+
+  HMAC_TEST(sha224, SHA224_DIGEST_SIZE,
+           LDATA("Jefe"),
+           LDATA("what do ya want for nothing?"),
+           H("a30e01098bc6dbbf45690f3a7e9e6d0f"
+             "8bbea2a39e6148008fd05e44"));
+
+  HMAC_TEST(sha224, SHA224_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaa"),
+           HL("dddddddddddddddddddddddddddddddd"
+              "dddddddddddddddddddddddddddddddd"
+              "dddddddddddddddddddddddddddddddd"
+              "dddd"),
+           H("7fb3cb3588c6c1f6ffa9694d7d6ad264"
+             "9365b0c1f65d69d1ec8333ea"));
+
+  HMAC_TEST(sha224, SHA224_DIGEST_SIZE,
+           HL("0102030405060708090a0b0c0d0e0f10"
+              "111213141516171819"),
+           HL("cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
+              "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
+              "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
+              "cdcd"),
+           H("6c11506874013cac6a2abc1bb382627c"
+             "ec6a90d86efc012de7afec5a"));
+
+  HMAC_TEST(sha224, 16,
+           HL("0c0c0c0c0c0c0c0c 0c0c0c0c0c0c0c0c 0c0c0c0c"),
+           LDATA("Test With Truncation"),
+           H("0e2aea68a90c8d37c988bcdb9fca6fa8"));
+
+  HMAC_TEST(sha224, SHA224_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaa"),
+           LDATA("Test Using Larger Than Block-Size Key - Hash Key First"),
+           H("95e9a0db962095adaebe9b2d6f0dbce2"
+             "d499f112f2d2b7273fa6870e"));
+
+  HMAC_TEST(sha224, SHA224_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaa"),
+           LDATA("This is a test using a larger than block-size ke"
+                 "y and a larger than block-size data. The key nee"
+                 "ds to be hashed before being used by the HMAC al"
+                 "gorithm."),
+           H("3a854166ac5d9f023f54d517d0b39dbd"
+             "946770db9c2b95c9f6f565d1"));
+
+  /* Additional test vectors, from Daniel Kahn Gillmor */
+  HMAC_TEST(sha224, SHA224_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA(""),
+           H("d12a49ae38177ffeaa548b2148bb5238"
+             "60849772d9391e675b103d89"));
+  
+  HMAC_TEST(sha224, SHA224_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("a"),
+           H("b04ff8522f904f553970bfa8ad3f0086"
+             "bce1e8580affd8a12c94e31a"));
+  
+  HMAC_TEST(sha224, SHA224_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("38"),
+           H("afcfb5511f710334f9350f57faec3c08"
+             "764b4bd126a6840f4347f116"));
+  
+  HMAC_TEST(sha224, SHA224_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("abc"),
+           H("9df9907af127900c909376893565c6cf"
+             "2d7db244fdc4277da1e0b679"));
+  
+  HMAC_TEST(sha224, SHA224_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("message digest"),
+           H("254ebf6b8ddd7a3271b3d9aca1699b0c"
+             "0bfb7df61e8a114922c88d27"));
+  
+  HMAC_TEST(sha224, SHA224_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("abcdefghijklmnopqrstuvwxyz"),
+           H("6ec5bffba5880c3234a6cf257816e4d5"
+             "35ab178a7f12929769e378fb"));
+
+  HMAC_TEST(sha224, SHA224_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
+           H("5f768179dbb29ca722875d0f461a2e2f"
+             "597d0210340a84df1a8e9c63"));
+
+  HMAC_TEST(sha224, SHA224_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("12345678901234567890123456789012345678901234567890123456789012345678901234567890"),
+           H("c7667b0d7e56b2b4f6fcc1d8da9e22da"
+             "a1556f44c47132a87303c6a2"));
+
+  /* Test vectors for sha256, from RFC 4231 */
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           HL("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"
+              "0b0b0b0b"),
+           LDATA("Hi There"),
+           H("b0344c61d8db38535ca8afceaf0bf12b"
+             "881dc200c9833da726e9376c2e32cff7"));
+
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           LDATA("Jefe"),
+           LDATA("what do ya want for nothing?"),
+           H("5bdcc146bf60754e6a042426089575c7"
+             "5a003f089d2739839dec58b964ec3843"));
+
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaa"),
+           HL("dddddddddddddddddddddddddddddddd"
+              "dddddddddddddddddddddddddddddddd"
+              "dddddddddddddddddddddddddddddddd"
+              "dddd"),
+           H("773ea91e36800e46854db8ebd09181a7"
+             "2959098b3ef8c122d9635514ced565fe"));
+
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           HL("0102030405060708090a0b0c0d0e0f10"
+              "111213141516171819"),
+           HL("cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
+              "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
+              "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
+              "cdcd"),
+           H("82558a389a443c0ea4cc819899f2083a"
+             "85f0faa3e578f8077a2e3ff46729665b"));
+
+  HMAC_TEST(sha256, 16,
+           HL("0c0c0c0c0c0c0c0c 0c0c0c0c0c0c0c0c 0c0c0c0c"),
+           LDATA("Test With Truncation"),
+           H("a3b6167473100ee06e0c796c2955552b"));
+
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaa"),
+           LDATA("Test Using Larger Than Block-Size Key - Hash Key First"),
+           H("60e431591ee0b67f0d8a26aacbf5b77f"
+             "8e0bc6213728c5140546040f0ee37f54"));
+
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaa"),
+           LDATA("This is a test using a larger than block-size ke"
+                 "y and a larger than block-size data. The key nee"
+                 "ds to be hashed before being used by the HMAC al"
+                 "gorithm."),
+           H("9b09ffa71b942fcb27635fbcd5b0e944"
+             "bfdc63644f0713938a7f51535c3a35e2"));
+
+  /* Additional test vectors for sha256, from
+     draft-ietf-ipsec-ciph-sha-256-01.txt */
+
+  /* Test Case #1: HMAC-SHA-256 with 3-byte input and 32-byte key */
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           HL("0102030405060708 090a0b0c0d0e0f10"
+              "1112131415161718 191a1b1c1d1e1f20"),
+           LDATA("abc"),
+           H("a21b1f5d4cf4f73a 4dd939750f7a066a"
+                "7f98cc131cb16a66 92759021cfab8181"));
+
+  /* Test Case #2: HMAC-SHA-256 with 56-byte input and 32-byte key */
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           HL("0102030405060708 090a0b0c0d0e0f10"
+              "1112131415161718 191a1b1c1d1e1f20"),
+           LDATA("abcdbcdecdefdefgefghfghighijhijk"
+                 "ijkljklmklmnlmnomnopnopq"),
+           H("104fdc1257328f08 184ba73131c53cae"
+                "e698e36119421149 ea8c712456697d30"));
+
+  /* Test Case #3: HMAC-SHA-256 with 112-byte (multi-block) input
+     and 32-byte key */
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           HL("0102030405060708 090a0b0c0d0e0f10"
+              "1112131415161718 191a1b1c1d1e1f20"),
+           LDATA("abcdbcdecdefdefgefghfghighijhijk"
+                 "ijkljklmklmnlmnomnopnopqabcdbcde"
+                 "cdefdefgefghfghighijhijkijkljklm"
+                 "klmnlmnomnopnopq"),
+           H("470305fc7e40fe34 d3eeb3e773d95aab"
+             "73acf0fd060447a5 eb4595bf33a9d1a3"));
+
+  /* Test Case #4:  HMAC-SHA-256 with 8-byte input and 32-byte key */
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           HL("0b0b0b0b0b0b0b0b 0b0b0b0b0b0b0b0b"
+              "0b0b0b0b0b0b0b0b 0b0b0b0b0b0b0b0b"),
+           LDATA("Hi There"),
+           H("198a607eb44bfbc6 9903a0f1cf2bbdc5"
+             "ba0aa3f3d9ae3c1c 7a3b1696a0b68cf7"));
+
+  /* Test Case #6: HMAC-SHA-256 with 50-byte input and 32-byte key */
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"),
+           HL("dddddddddddddddd dddddddddddddddd"
+              "dddddddddddddddd dddddddddddddddd"
+              "dddddddddddddddd dddddddddddddddd"
+              "dddd"),
+           H("cdcb1220d1ecccea 91e53aba3092f962"
+             "e549fe6ce9ed7fdc 43191fbde45c30b0"));
+
+  /* Test Case #7: HMAC-SHA-256 with 50-byte input and 37-byte key */
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           HL("0102030405060708 090a0b0c0d0e0f10"
+              "1112131415161718 191a1b1c1d1e1f20"
+              "2122232425"),
+           HL("cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd"
+              "cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd"
+              "cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd"
+              "cdcd"),
+           H("d4633c17f6fb8d74 4c66dee0f8f07455"
+             "6ec4af55ef079985 41468eb49bd2e917"));
+
+  /* Test Case #8: HMAC-SHA-256 with 20-byte input and 32-byte key */
+  HMAC_TEST(sha256, 16,
+           HL("0c0c0c0c0c0c0c0c 0c0c0c0c0c0c0c0c"
+              "0c0c0c0c0c0c0c0c 0c0c0c0c0c0c0c0c"),
+           LDATA("Test With Truncation"),
+           H("7546af01841fc09b 1ab9c3749a5f1c17"));
+
+  /* Test Case #9: HMAC-SHA-256 with 54-byte input and 80-byte key */
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"),
+           LDATA("Test Using Larger Than Block-Size Key - Hash Key First"),
+           H("6953025ed96f0c09 f80a96f78e6538db"
+             "e2e7b820e3dd970e 7ddd39091b32352f"));
+
+  /* Test Case #10: HMAC-SHA-256 with 73-byte (multi-block) input
+     and 80-byte key */
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"),
+           LDATA("Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data"),
+           H("6355ac22e890d0a3 c8481a5ca4825bc8"
+             "84d3e7a1ff98a2fc 2ac7d8e064c3b2e6"));
+
+  /* Additional test vectors, from Daniel Kahn Gillmor */
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA(""),
+           H("5c780648c90d121c50091c3a0c3afc1f"
+             "4ab847528005d99d9821ad3f341b651a"));
+  
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("a"),
+           H("6142364c0646b0cfe426866f21d613e0"
+             "55a136a7d9b45d85685e080a09cec463"));
+  
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("38"),
+           H("e49aa7839977e130ad87b63da9d4eb7b"
+             "263cd5a27c54a7604b6044eb35901171"));
+  
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("abc"),
+           H("e5ef49f545c7af933a9d18c7c562bc91"
+             "08583fd5cf00d9e0db351d6d8f8e41bc"));
+  
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("message digest"),
+           H("373b04877180fea27a41a8fb8f88201c"
+             "a6268411ee3c80b01a424483eb9156e1"));
+  
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("abcdefghijklmnopqrstuvwxyz"),
+           H("eb5945d56eefbdb41602946ea6448d53"
+             "86b08d7d801a87f439fab52f8bb9736e"));
+
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
+           H("3798f363c57afa6edaffe39016ca7bad"
+             "efd1e670afb0e3987194307dec3197db"));
+
+  HMAC_TEST(sha256, SHA256_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("12345678901234567890123456789012345678901234567890123456789012345678901234567890"),
+           H("c89a7039a62985ff813fe4509b918a43"
+             "6d7b1ffd8778e2c24dec464849fb6128"));
+
+  /* Test vectors for sha384, from RFC 4231 */
+  HMAC_TEST(sha384, SHA384_DIGEST_SIZE,
+           HL("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"
+              "0b0b0b0b"),
+           LDATA("Hi There"),
+           H("afd03944d84895626b0825f4ab46907f"
+             "15f9dadbe4101ec682aa034c7cebc59c"
+             "faea9ea9076ede7f4af152e8b2fa9cb6"));
+
+  HMAC_TEST(sha384, SHA384_DIGEST_SIZE,
+           LDATA("Jefe"),
+           LDATA("what do ya want for nothing?"),
+           H("af45d2e376484031617f78d2b58a6b1b"
+             "9c7ef464f5a01b47e42ec3736322445e"
+             "8e2240ca5e69e2c78b3239ecfab21649"));
+
+  HMAC_TEST(sha384, SHA384_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaa"),
+           HL("dddddddddddddddddddddddddddddddd"
+              "dddddddddddddddddddddddddddddddd"
+              "dddddddddddddddddddddddddddddddd"
+              "dddd"),
+           H("88062608d3e6ad8a0aa2ace014c8a86f"
+             "0aa635d947ac9febe83ef4e55966144b"
+             "2a5ab39dc13814b94e3ab6e101a34f27"));
+
+  HMAC_TEST(sha384, SHA384_DIGEST_SIZE,
+           HL("0102030405060708090a0b0c0d0e0f10"
+              "111213141516171819"),
+           HL("cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
+              "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
+              "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
+              "cdcd"),
+           H("3e8a69b7783c25851933ab6290af6ca7"
+             "7a9981480850009cc5577c6e1f573b4e"
+             "6801dd23c4a7d679ccf8a386c674cffb"));
+
+  HMAC_TEST(sha384, 16,
+           HL("0c0c0c0c0c0c0c0c 0c0c0c0c0c0c0c0c 0c0c0c0c"),
+           LDATA("Test With Truncation"),
+           H("3abf34c3503b2a23a46efc619baef897"));
+
+  HMAC_TEST(sha384, SHA384_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaa"),
+           LDATA("Test Using Larger Than Block-Size Key - Hash Key First"),
+           H("4ece084485813e9088d2c63a041bc5b4"
+             "4f9ef1012a2b588f3cd11f05033ac4c6"
+             "0c2ef6ab4030fe8296248df163f44952"));
+
+  HMAC_TEST(sha384, SHA384_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaa"),
+           LDATA("This is a test using a larger than block-size ke"
+                 "y and a larger than block-size data. The key nee"
+                 "ds to be hashed before being used by the HMAC al"
+                 "gorithm."),
+           H("6617178e941f020d351e2f254e8fd32c"
+             "602420feb0b8fb9adccebb82461e99c5"
+             "a678cc31e799176d3860e6110c46523e"));
+
+  /* Test vectors for sha512, from RFC 4231 */
+  HMAC_TEST(sha512, SHA512_DIGEST_SIZE,
+           HL("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"
+              "0b0b0b0b"),
+           LDATA("Hi There"),
+           H("87aa7cdea5ef619d4ff0b4241a1d6cb0"
+             "2379f4e2ce4ec2787ad0b30545e17cde"
+             "daa833b7d6b8a702038b274eaea3f4e4"
+             "be9d914eeb61f1702e696c203a126854"));
+
+  HMAC_TEST(sha512, SHA512_DIGEST_SIZE,
+           LDATA("Jefe"),
+           LDATA("what do ya want for nothing?"),
+           H("164b7a7bfcf819e2e395fbe73b56e0a3"
+             "87bd64222e831fd610270cd7ea250554"
+             "9758bf75c05a994a6d034f65f8f0e6fd"
+             "caeab1a34d4a6b4b636e070a38bce737"));
+
+  HMAC_TEST(sha512, SHA512_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaa"),
+           HL("dddddddddddddddddddddddddddddddd"
+              "dddddddddddddddddddddddddddddddd"
+              "dddddddddddddddddddddddddddddddd"
+              "dddd"),
+           H("fa73b0089d56a284efb0f0756c890be9"
+             "b1b5dbdd8ee81a3655f83e33b2279d39"
+             "bf3e848279a722c806b485a47e67c807"
+             "b946a337bee8942674278859e13292fb"));
+
+  HMAC_TEST(sha512, SHA512_DIGEST_SIZE,
+           HL("0102030405060708090a0b0c0d0e0f10"
+              "111213141516171819"),
+           HL("cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
+              "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
+              "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
+              "cdcd"),
+           H("b0ba465637458c6990e5a8c5f61d4af7"
+             "e576d97ff94b872de76f8050361ee3db"
+             "a91ca5c11aa25eb4d679275cc5788063"
+             "a5f19741120c4f2de2adebeb10a298dd"));
+
+  HMAC_TEST(sha512, 16,
+           HL("0c0c0c0c0c0c0c0c 0c0c0c0c0c0c0c0c 0c0c0c0c"),
+           LDATA("Test With Truncation"),
+           H("415fad6271580a531d4179bc891d87a6"));
+
+  HMAC_TEST(sha512, SHA512_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaa"),
+           LDATA("Test Using Larger Than Block-Size Key - Hash Key First"),
+           H("80b24263c7c1a3ebb71493c1dd7be8b4"
+             "9b46d1f41b4aeec1121b013783f8f352"
+             "6b56d037e05f2598bd0fd2215d6a1e52"
+             "95e64f73f63f0aec8b915a985d786598"));
+
+  HMAC_TEST(sha512, SHA512_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaa"),
+           LDATA("This is a test using a larger than block-size ke"
+                 "y and a larger than block-size data. The key nee"
+                 "ds to be hashed before being used by the HMAC al"
+                 "gorithm."),
+           H("e37b6a775dc87dbaa4dfa9f96e5e3ffd"
+             "debd71f8867289865df5a32d20cdc944"
+             "b6022cac3c4982b10d5eeb55c3e4de15"
+             "134676fb6de0446065c97440fa8c6a58"));
+
+  /* Additional test vectors, from Daniel Kahn Gillmor */
+  HMAC_TEST(sha512, SHA512_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA(""),
+           H("34316413c2d6940572d0bbbf099d529d"
+             "148b424533cf562bc1b365f530e21a31"
+             "799fc51cef78060cc6f448a8e5d780c2"
+             "6cdf20d4c3e6f27fe5ef576bbd05e855"));
+  
+  HMAC_TEST(sha512, SHA512_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("a"),
+           H("cf1948507378bc3ab58cb6ec87f4d456"
+             "b90d3298395c29873f1ded1e111b50fe"
+             "c336ed24684bf19716efc309212f37aa"
+             "715cfb9ecccf3af13691ded167b4b336"));
+  
+  HMAC_TEST(sha512, SHA512_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("38"),
+           H("b8201784216ce01b83cdd282616c6e89"
+             "644c6dfd1269ed8580bbc39b92add364"
+             "c2b2a2018cffb1915e8625e473b67d0f"
+             "e54a50e475dfa0e2b1a97bac1383792c"));
+  
+  HMAC_TEST(sha512, SHA512_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("abc"),
+           H("f097ee08b8c44e847a384f9fd645e35e"
+             "4816baa9791ba39d3dc611210500b044"
+             "873ee296bf1047dc06daa201a5767192"
+             "5b73b4ea59c60114881c8287d0699c83"));
+  
+  HMAC_TEST(sha512, SHA512_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("message digest"),
+           H("921a441a884b83c76a8526da8e60d60d"
+             "17ded4eee5c29375e0d93717669a4c3e"
+             "eba7473e95f7c1a2a85afc24a0adbc4d"
+             "6c2bdd6ca6cab8b18d19f82d4a6c51bc"));
+  
+  HMAC_TEST(sha512, SHA512_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("abcdefghijklmnopqrstuvwxyz"),
+           H("640054c96f35815095617d0a8c956066"
+             "1a6ff46bfb39110333b2c52c8866abfb"
+             "59d9152c9b0948c1ed65c3fd72a8fb82"
+             "190acc8830770afe5b0c5b6414c75a77"));
+
+  HMAC_TEST(sha512, SHA512_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
+           H("835a4f5b3750b4c1fccfa88da2f746a4"
+             "900160c9f18964309bb736c13b59491b"
+             "8e32d37b724cc5aebb0f554c6338a3b5"
+             "94c4ba26862b2dadb59b7ede1d08d53e"));
+
+  HMAC_TEST(sha512, SHA512_DIGEST_SIZE,
+           LDATA("monkey monkey monkey monkey"),
+           LDATA("12345678901234567890123456789012345678901234567890123456789012345678901234567890"),
+           H("fdf83dc879e3476c8e8aceff2bf6fece"
+             "2e4f39c7e1a167845465bb549dfa5ffe"
+             "997e6c7cf3720eae51ed2b00ad2a8225"
+             "375092290edfa9d48ec7e4bc8e276088"));
+
+  /* Additional test vectors, from
+     draft-kelly-ipsec-ciph-sha2-01.txt */
+
+  /* Test case AUTH512-1: */
+  HMAC_TEST(sha512, SHA512_DIGEST_SIZE,
+           HL("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"
+              "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"
+              "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"
+              "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"),
+           LDATA("Hi There"),
+           H("637edc6e01dce7e6742a99451aae82df"
+             "23da3e92439e590e43e761b33e910fb8"
+             "ac2878ebd5803f6f0b61dbce5e251ff8"
+             "789a4722c1be65aea45fd464e89f8f5b"));
+
+  /* Test case AUTH512-2: */
+  HMAC_TEST(sha512, SHA512_DIGEST_SIZE,
+           LDATA("JefeJefeJefeJefe"
+                 "JefeJefeJefeJefe"
+                 "JefeJefeJefeJefe"
+                 "JefeJefeJefeJefe"),      
+           LDATA("what do ya want for nothing?"),
+           H("cb370917ae8a7ce28cfd1d8f4705d614"
+             "1c173b2a9362c15df235dfb251b15454"
+             "6aa334ae9fb9afc2184932d8695e397b"
+             "fa0ffb93466cfcceaae38c833b7dba38"));
+
+  /* Test case AUTH512-3: */
+  HMAC_TEST(sha512, SHA512_DIGEST_SIZE,
+           HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
+           HL("dddddddddddddddddddddddddddddddd"
+              "dddddddddddddddddddddddddddddddd"
+              "dddddddddddddddddddddddddddddddd"
+              "dddd"),
+           H("2ee7acd783624ca9398710f3ee05ae41"
+             "b9f9b0510c87e49e586cc9bf961733d8"
+             "623c7b55cebefccf02d5581acc1c9d5f"
+             "b1ff68a1de45509fbe4da9a433922655"));
+
+  /* Test case AUTH512-3 from same document seems broken. */
+  
+  SUCCESS();
+}
diff --git a/testsuite/knuth-lfib-test.c b/testsuite/knuth-lfib-test.c
new file mode 100644 (file)
index 0000000..218894f
--- /dev/null
@@ -0,0 +1,22 @@
+#include "testutils.h"
+#include "knuth-lfib.h"
+
+int
+test_main(void)
+{
+  struct knuth_lfib_ctx ctx;
+
+  uint32_t a[2009];
+  uint32_t x;
+  unsigned m;
+  
+  knuth_lfib_init(&ctx, 310952);
+  for (m = 0; m<2009; m++)
+    knuth_lfib_get_array(&ctx, 1009, a);
+
+  x = knuth_lfib_get(&ctx);
+  if (x != 461390032)
+    FAIL();
+
+  SUCCESS();
+}
diff --git a/testsuite/md2-test.c b/testsuite/md2-test.c
new file mode 100644 (file)
index 0000000..8ab45c1
--- /dev/null
@@ -0,0 +1,27 @@
+#include "testutils.h"
+#include "md2.h"
+
+int
+test_main(void)
+{
+  /* Testcases from RFC 1319 */
+  test_hash(&nettle_md2, 0, "",
+           H("8350e5a3e24c153df2275c9f80692773"));
+  test_hash(&nettle_md2, LDATA("a"),
+           H("32ec01ec4a6dac72c0ab96fb34c0b5d1"));
+  test_hash(&nettle_md2, LDATA("abc"),
+           H("da853b0d3f88d99b30283a69e6ded6bb"));
+  test_hash(&nettle_md2, LDATA("message digest"),
+           H("ab4f496bfb2a530b219ff33031fe06b0"));
+  test_hash(&nettle_md2, LDATA("abcdefghijklmnopqrstuvwxyz"),
+           H("4e8ddff3650292ab5a4108c3aa47940b"));
+  test_hash(&nettle_md2,
+           LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+                 "0123456789"),
+           H("da33def2a42df13975352846c30338cd"));
+  test_hash(&nettle_md2, LDATA("1234567890123456789012345678901234567890"
+                              "1234567890123456789012345678901234567890"),
+           H("d5976f79d83d3a0dc9806c3c66f3efd8"));
+
+  SUCCESS();
+}
diff --git a/testsuite/md4-test.c b/testsuite/md4-test.c
new file mode 100644 (file)
index 0000000..208456d
--- /dev/null
@@ -0,0 +1,38 @@
+#include "testutils.h"
+#include "md4.h"
+
+int
+test_main(void)
+{
+  /* Testcases from RFC 1320 */
+  test_hash(&nettle_md4, LDATA(""),
+           H("31d6cfe0d16ae931b73c59d7e0c089c0"));
+  test_hash(&nettle_md4, LDATA("a"),
+           H("bde52cb31de33e46245e05fbdbd6fb24"));
+  test_hash(&nettle_md4, LDATA("abc"),
+           H("a448017aaf21d8525fc10ae87aa6729d"));
+  test_hash(&nettle_md4, LDATA("message digest"),
+           H("d9130a8164549fe818874806e1c7014b"));
+  test_hash(&nettle_md4, LDATA("abcdefghijklmnopqrstuvwxyz"),
+           H("d79e1c308aa5bbcdeea8ed63df412da9"));
+  test_hash(&nettle_md4,
+           LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+                 "0123456789"),
+           H("043f8582f241db351ce627e153e7f0e4"));
+  test_hash(&nettle_md4,
+           LDATA("12345678901234567890123456789012345678901234567890"
+                 "123456789012345678901234567890"),
+           H("e33b4ddc9c38f2199c3e7b164fcc0536"));
+
+  /* Additional test vectors, from Daniel Kahn Gillmor */
+  test_hash(&nettle_md4, LDATA("38"),
+           H("ae9c7ebfb68ea795483d270f5934b71d"));
+  test_hash(&nettle_md4, LDATA("abc"),
+           H("a448017aaf21d8525fc10ae87aa6729d"));
+  test_hash(&nettle_md4, LDATA("message digest"),
+           H("d9130a8164549fe818874806e1c7014b"));
+  test_hash(&nettle_md4, LDATA("abcdefghijklmnopqrstuvwxyz"),
+           H("d79e1c308aa5bbcdeea8ed63df412da9"));
+
+  SUCCESS();
+}
diff --git a/testsuite/md5-compat-test.c b/testsuite/md5-compat-test.c
new file mode 100644 (file)
index 0000000..bffb623
--- /dev/null
@@ -0,0 +1,60 @@
+#include "testutils.h"
+#include "md5-compat.h"
+
+int
+test_main(void)
+{
+  MD5_CTX ctx;
+  unsigned char digest[MD5_DIGEST_SIZE];
+
+  MD5Init(&ctx);
+  MD5Final(digest, &ctx);
+  if (!MEMEQ(MD5_DIGEST_SIZE, digest, H("D41D8CD98F00B204 E9800998ECF8427E")))
+    FAIL();
+
+  MD5Init(&ctx);
+  MD5Update(&ctx, "a", 1);
+  MD5Final(digest, &ctx);
+
+  if (!MEMEQ(MD5_DIGEST_SIZE, digest, H("0CC175B9C0F1B6A8 31C399E269772661")))
+    FAIL();
+
+  MD5Init(&ctx);
+  MD5Update(&ctx, "abc", 3);
+  MD5Final(digest, &ctx);
+
+  if (!MEMEQ(MD5_DIGEST_SIZE, digest, H("900150983cd24fb0 D6963F7D28E17F72")))
+    FAIL();
+
+  MD5Init(&ctx);
+  MD5Update(&ctx, "message digest", 14);
+  MD5Final(digest, &ctx);
+
+  if (!MEMEQ(MD5_DIGEST_SIZE, digest, H("F96B697D7CB7938D 525A2F31AAF161D0")))
+    FAIL();
+
+  MD5Init(&ctx);
+  MD5Update(&ctx, "abcdefghijklmnopqrstuvwxyz", 26);
+  MD5Final(digest, &ctx);
+
+  if (!MEMEQ(MD5_DIGEST_SIZE, digest, H("C3FCD3D76192E400 7DFB496CCA67E13B")))
+    FAIL();
+
+  MD5Init(&ctx);
+  MD5Update(&ctx, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 62);
+  MD5Final(digest, &ctx);
+
+  if (!MEMEQ(MD5_DIGEST_SIZE, digest, H("D174AB98D277D9F5 A5611C2C9F419D9F")))
+    FAIL();
+
+  MD5Init(&ctx);
+  MD5Update(&ctx, "1234567890123456789012345678901234567890"
+           "1234567890123456789012345678901234567890",
+           80);
+  MD5Final(digest, &ctx);
+
+  if (!MEMEQ(MD5_DIGEST_SIZE, digest, H("57EDF4A22BE3C955 AC49DA2E2107B67A")))
+    FAIL();
+
+  SUCCESS();
+}
diff --git a/testsuite/md5-test.c b/testsuite/md5-test.c
new file mode 100644 (file)
index 0000000..995f304
--- /dev/null
@@ -0,0 +1,120 @@
+#include "testutils.h"
+#include "md5.h"
+
+int
+test_main(void)
+{
+  test_hash(&nettle_md5, 0, "",
+           H("D41D8CD98F00B204 E9800998ECF8427E"));
+
+  test_hash(&nettle_md5, 1, "a",
+           H("0CC175B9C0F1B6A8 31C399E269772661"));
+           
+  test_hash(&nettle_md5, 3, "abc",
+           H("900150983cd24fb0 D6963F7D28E17F72"));
+
+  test_hash(&nettle_md5, 14, "message digest",
+           H("F96B697D7CB7938D 525A2F31AAF161D0"));
+  
+  test_hash(&nettle_md5, 26, "abcdefghijklmnopqrstuvwxyz",
+           H("C3FCD3D76192E400 7DFB496CCA67E13B"));
+  
+  test_hash(&nettle_md5, 62,
+           "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+           "abcdefghijklmnopqrstuvwxyz"
+           "0123456789",
+           H("D174AB98D277D9F5 A5611C2C9F419D9F"));
+
+  test_hash(&nettle_md5, 80,
+           "1234567890123456789012345678901234567890"
+           "1234567890123456789012345678901234567890",
+           H("57EDF4A22BE3C955 AC49DA2E2107B67A"));
+
+  /* Additional test vector, from Daniel Kahn Gillmor */
+  test_hash(&nettle_md5, LDATA("38"),
+           H("a5771bce93e200c3 6f7cd9dfd0e5deaa"));
+
+  /* Collisions, reported by Xiaoyun Wang1, Dengguo Feng2, Xuejia
+     Lai3, Hongbo Yu1, http://eprint.iacr.org/2004/199. */
+
+#define M0 \
+  /*                                          vv */                            \
+  "d131dd02 c5e6eec4 693d9a06 98aff95c 2fcab5 87 12467eab 4004583e b8fb7f89"   \
+  "55ad3406 09f4b302 83e48883 25 71 415a 085125e8 f7cdc99f d91dbd f2 80373c5b" \
+  /*                             ^^                               ^^ */
+
+#define M1 \
+  /*                                          vv */                            \
+  "d131dd02 c5e6eec4 693d9a06 98aff95c 2fcab5 07 12467eab 4004583e b8fb7f89"   \
+  "55ad3406 09f4b302 83e48883 25 f1 415a 085125e8 f7cdc99f d91dbd 72 80373c5b" \
+  /*                             ^^                               ^^ */
+
+#define N0                                                                     \
+  /*                                          vv */                            \
+  "960b1dd1 dc417b9c e4d897f4 5a6555d5 35739a c7 f0ebfd0c 3029f166 d109b18f"   \
+  "75277f79 30d55ceb 22e8adba 79 cc 155c ed74cbdd 5fc5d36d b19b0a d8 35cca7e3" \
+  /*                             ^^                               ^^ */
+
+#define N1                                                                     \
+  /*                                          vv */                            \
+  "960b1dd1 dc417b9c e4d897f4 5a6555d5 35739a 47 f0ebfd0c 3029f166 d109b18f"   \
+  "75277f79 30d55ceb 22e8adba 79 4c 155c ed74cbdd 5fc5d36d b19b0a 58 35cca7e3" \
+  /*                             ^^                               ^^ */
+
+  /* Note: The checksum in the paper, 1f160396 efc71ff4 bcff659f
+     bf9d0fa3, is incorrect. */
+
+#define H0 "a4c0d35c 95a63a80 5915367d cfe6b751"
+
+#define N2                                                                     \
+  /*                                          vv */                            \
+  "d8823e31 56348f5b ae6dacd4 36c919c6 dd53e2 b4 87da03fd 02396306 d248cda0"   \
+  "e99f3342 0f577ee8 ce54b670 80 a8 0d1e c69821bc b6a88393 96f965 2b 6ff72a70" \
+  /*                             ^^                               ^^ */
+
+#define N3                                                                     \
+  /*                                          vv */                            \
+  "d8823e31 56348f5b ae6dacd4 36c919c6 dd53e2 34 87da03fd 02396306 d248cda0"   \
+  "e99f3342 0f577ee8 ce54b670 80 28 0d1e c69821bc b6a88393 96f965 ab 6ff72a70" \
+  /*                             ^^                               ^^ */
+
+  /* Note: Also different from the checksum in the paper */
+  
+#define H1 "79054025 255fb1a2 6e4bc422 aef54eb4"
+  
+  test_hash(&nettle_md5,
+           HL(M0 N0), H(H0));
+
+  test_hash(&nettle_md5,
+           HL(M1 N1), H(H0));
+
+  test_hash(&nettle_md5,
+           HL(M0 N2), H(H1));
+
+  test_hash(&nettle_md5,
+           HL(M1 N3), H(H1));
+
+  SUCCESS();
+}
+
+/* Intermediate values for the single _nettle_md5_compress call for
+   the first test case. Each row gives the values for a, b, c, d after
+   the i:th round. The row i = -1 gives the initial values, and i = 99
+   gives the output values.
+
+     i         a        b        c        d
+    -1: 67452301 efcdab89 98badcfe 10325476
+     0: a5202774 efcdab89 98badcfe 10325476
+     1: a5202774 efcdab89 98badcfe f59592dd
+    15: f56c7cf1 d6819c6a 5aa53f75 374943a7
+    16: 1c7d7513 d6819c6a 5aa53f75 374943a7
+    17: 1c7d7513 d6819c6a 5aa53f75 7bd57a3a
+    31: 13707036 a2205f1f 1c31c384 ae7813db
+    32: df63eaa1 a2205f1f 1c31c384 ae7813db
+    33: df63eaa1 a2205f1f 1c31c384 c3689f5b
+    47: 3f55edfd ca7d2dbd 68d84ea2 22a31f54
+    48: 93aa2577 ca7d2dbd 68d84ea2 22a31f54
+    49: 93aa2577 ca7d2dbd 68d84ea2 1688dc85
+    63: 7246fad3 14e45506 ff4ea3eb 6e10a476
+    99: d98c1dd4  4b2008f 980980e9 7e42f8ec
+*/
diff --git a/testsuite/memxor-test.c b/testsuite/memxor-test.c
new file mode 100644 (file)
index 0000000..3fa5165
--- /dev/null
@@ -0,0 +1,148 @@
+#include "testutils.h"
+#include "memxor.h"
+
+#define MAX_SIZE 256
+
+static uint8_t *
+set_align(uint8_t *buf, unsigned align)
+{
+  unsigned offset;
+  /* An extra redzon char at the beginning */
+  buf++;
+  offset = (uintptr_t) (buf) % sizeof(unsigned long);
+
+  if (offset < align)
+    buf += (align - offset);
+  else if (offset > align)
+    buf += (align + sizeof(unsigned long) - offset);
+
+  return buf;  
+}
+
+static void
+test_memxor (const uint8_t *a, const uint8_t *b, const uint8_t *c,
+            size_t size, unsigned align_dst, unsigned align_src)
+{
+  uint8_t dst_buf[MAX_SIZE + sizeof(unsigned long) + 1];
+  uint8_t src_buf[MAX_SIZE + sizeof(unsigned long) + 1];
+
+  uint8_t *dst = set_align (dst_buf, align_dst);
+  uint8_t *src = set_align (src_buf, align_src);
+
+  if (verbose)
+    fprintf(stderr, "size = %d, align_dst = %d, align_src = %d\n",
+             (int) size, align_dst, align_src);
+
+  memcpy (dst, a, size);
+  dst[-1] = 17;
+  dst[size] = 17;
+
+  memcpy (src, b, size);
+  memxor (dst, src, size);
+
+  ASSERT (MEMEQ (size, dst, c));
+  ASSERT (dst[-1] == 17);
+  ASSERT (dst[size] == 17);
+}
+
+static void
+test_memxor3 (const uint8_t *ain, const uint8_t *bin, const uint8_t *c,
+             size_t size, unsigned align_dst, unsigned align_a, unsigned align_b)
+{
+  uint8_t dst_buf[MAX_SIZE + sizeof(unsigned long) + 1];
+  uint8_t a_buf[MAX_SIZE + sizeof(unsigned long) + 1];
+  uint8_t b_buf[MAX_SIZE + sizeof(unsigned long) + 1];
+
+  uint8_t *dst = set_align (dst_buf, align_dst);
+  uint8_t *a = set_align (a_buf, align_a);
+  uint8_t *b = set_align (b_buf, align_b);
+
+  if (verbose)
+    fprintf(stderr, "size = %d, align_dst = %d, align_a = %d, align_b = %d\n",
+           (int) size, align_dst, align_a, align_b);
+
+  memset (dst, 0, size);
+  dst[-1] = 17;
+  dst[size] = 17;
+
+  memcpy (a, ain, size);
+  memcpy (b, bin, size);
+  memxor3 (dst, a, b, size);
+
+  ASSERT (MEMEQ (size, dst, c));
+  ASSERT (dst[-1] == 17);
+  ASSERT (dst[size] == 17);
+}
+
+int
+test_main(void)
+{
+  const uint8_t *a = H("ecc8737f 38f2f9e8 86b9d84c 42a9c7ef"
+                      "27a50860 49c6be97 c5cc6c35 3981b367"
+                      "f8b4397b 951e3b2f 35749fe1 25884fa6"
+                      "9361c97a ab1c6cce 494efb5a 1f108411"
+                      "21dc6386 e81b2410 2f04c29d e0ca1135"
+                      "c9f96f2e bb5b2e2d 8cb45df9 50c4755a"
+                      "362b7ead 4b930010 cbc69834 66221ba8"
+                      "c0b8d7ac 7ec3b700 6bdb1a3b 599f3e76"
+                      "a7e66a29 ee1fb98c 60a66c9e 0a1d9c49"
+                      "6367afc7 362d6ae1 f8799443 17e2b1a1"
+                      "ff1cc03c 9e2728ca a1f6598f 5a61bd56"
+                      "0826effc f3499da7 119249b6 fd643cd4"
+                      "2e7c74b0 f775fda4 a5617138 1e8520bf"
+                      "f17de57a decc36b6 9eceee6e d448f592"
+                      "be77a67a 1b91a5b3 62fab868 dcb046f6"
+                      "394b5335 b2eaa351 fc4456e4 35bb9c54");
+
+  const uint8_t *b = H("cac458ad fe87e226 6cb0ce3d cfa5cb3b"
+                      "963d0034 5811bb9e acf4675b 7464f800"
+                      "4b1bcff2 b2fa5dd0 0576aea6 888b8150"
+                      "bcba48f1 49bc33d2 e138b0d0 a29b486e"
+                      "f7e143c6 f9959596 6aaa4493 b0bea6f8"
+                      "1d778513 a3bfec7e 70cfe6a7 e31ad041"
+                      "5fe3371b 63aba991 dab9a3db 66310ebc"
+                      "24c2765d a722a131 2fc4d366 1f2e3388"
+                      "7e5b26d5 7b34bf4c 655d19da d1335362"
+                      "2fbc0d5d cc68c811 ef735c20 352986ef"
+                      "f47ac5c9 afa77f5a 20da6dd3 eb9dfb34"
+                      "0cdbf792 caf0d633 61d908da a4c0f2a9"
+                      "be7a573e 3b8d161c 47fc19be e47d7edc"
+                      "e5f00dae f64cbbb4 a081e1f0 381833d8"
+                      "30d302ff eed61887 3390d6b2 0048ac32"
+                      "9c6b2981 a224dcc1 6b1feebe 15834b1a");
+
+  const uint8_t *c = H("260c2bd2 c6751bce ea091671 8d0c0cd4"
+                      "b1980854 11d70509 69380b6e 4de54b67"
+                      "b3aff689 27e466ff 30023147 ad03cef6"
+                      "2fdb818b e2a05f1c a8764b8a bd8bcc7f"
+                      "d63d2040 118eb186 45ae860e 5074b7cd"
+                      "d48eea3d 18e4c253 fc7bbb5e b3dea51b"
+                      "69c849b6 2838a981 117f3bef 00131514"
+                      "e47aa1f1 d9e11631 441fc95d 46b10dfe"
+                      "d9bd4cfc 952b06c0 05fb7544 db2ecf2b"
+                      "4cdba29a fa45a2f0 170ac863 22cb374e"
+                      "0b6605f5 31805790 812c345c b1fc4662"
+                      "04fd186e 39b94b94 704b416c 59a4ce7d"
+                      "9006238e ccf8ebb8 e29d6886 faf85e63"
+                      "148de8d4 28808d02 3e4f0f9e ec50c64a"
+                      "8ea4a485 f547bd34 516a6eda dcf8eac4"
+                      "a5207ab4 10ce7f90 975bb85a 2038d74e");
+
+  const int size[] = {
+    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+    17, 23, 24, 25, 30, 31, 32, 33, 34, 35, 36, 37,
+    250, 251, 252, 253,254, 255, 256, -1
+  };
+
+  unsigned i, align_dst, align_a, align_b;
+  for (i = 0; size[i] >= 0; i++)
+    for (align_dst = 0; align_dst < sizeof(unsigned long); align_dst++)
+      for (align_a = 0; align_a < sizeof(unsigned long); align_a++)
+       {
+         test_memxor (a, b, c, size[i], align_dst, align_a);
+         for (align_b = 0; align_b < sizeof(unsigned long); align_b++)
+           test_memxor3 (a, b, c, size[i], align_dst, align_a, align_b);
+       }
+
+  SUCCESS();
+}
diff --git a/testsuite/meta-armor-test.c b/testsuite/meta-armor-test.c
new file mode 100644 (file)
index 0000000..a99064b
--- /dev/null
@@ -0,0 +1,27 @@
+#include "testutils.h"
+#include "nettle-meta.h"
+
+const char* armors[] = {
+  "base16",
+  "base64"
+};
+
+int
+test_main(void)
+{
+  int i,j;
+  int count = sizeof(armors)/sizeof(*armors);
+  for (i = 0; i < count; i++) {
+    for (j = 0; NULL != nettle_armors[j]; j++) {
+      if (0 == strcmp(armors[i], nettle_armors[j]->name))
+        break;
+    }
+    ASSERT(NULL != nettle_armors[j]); /* make sure we found a matching armor */
+  }
+  j = 0;
+  while (NULL != nettle_armors[j])
+    j++;
+  ASSERT(j == count); /* we are not missing testing any armors */
+  SUCCESS();
+}
+  
diff --git a/testsuite/meta-cipher-test.c b/testsuite/meta-cipher-test.c
new file mode 100644 (file)
index 0000000..1bb74d8
--- /dev/null
@@ -0,0 +1,43 @@
+#include "testutils.h"
+#include "nettle-meta.h"
+
+const char* ciphers[] = {
+  "aes128",
+  "aes192",
+  "aes256",
+  "arctwo40",
+  "arctwo64",
+  "arctwo128",
+  "arctwo_gutmann128",
+  "arcfour128",
+  "camellia128",
+  "camellia192",
+  "camellia256",
+  "cast128",
+  "serpent128",
+  "serpent192",
+  "serpent256",
+  "twofish128",
+  "twofish192",
+  "twofish256"
+};
+
+int
+test_main(void)
+{
+  int i,j;
+  int count = sizeof(ciphers)/sizeof(*ciphers);
+  for (i = 0; i < count; i++) {
+    for (j = 0; NULL != nettle_ciphers[j]; j++) {
+      if (0 == strcmp(ciphers[i], nettle_ciphers[j]->name))
+        break;
+    }
+    ASSERT(NULL != nettle_ciphers[j]); /* make sure we found a matching cipher */
+  }
+  j = 0;
+  while (NULL != nettle_ciphers[j])
+    j++;
+  ASSERT(j == count); /* we are not missing testing any ciphers */
+  SUCCESS();
+}
+  
diff --git a/testsuite/meta-hash-test.c b/testsuite/meta-hash-test.c
new file mode 100644 (file)
index 0000000..6db279b
--- /dev/null
@@ -0,0 +1,34 @@
+#include "testutils.h"
+#include "nettle-meta.h"
+
+const char* hashes[] = {
+  "md2",
+  "md4",
+  "md5",
+  "ripemd160",
+  "sha1",
+  "sha224",
+  "sha256",
+  "sha384",
+  "sha512"
+};
+
+int
+test_main(void)
+{
+  int i,j;
+  int count = sizeof(hashes)/sizeof(*hashes);
+  for (i = 0; i < count; i++) {
+    for (j = 0; NULL != nettle_hashes[j]; j++) {
+      if (0 == strcmp(hashes[i], nettle_hashes[j]->name))
+        break;
+    }
+    ASSERT(NULL != nettle_hashes[j]); /* make sure we found a matching hash */
+  }
+  j = 0;
+  while (NULL != nettle_hashes[j])
+    j++;
+  ASSERT(j == count); /* we are not missing testing any hashes */
+  SUCCESS();
+}
+  
diff --git a/testsuite/pkcs1-conv-test b/testsuite/pkcs1-conv-test
new file mode 100755 (executable)
index 0000000..e1ce3db
--- /dev/null
@@ -0,0 +1,51 @@
+#! /bin/sh
+
+if [ -z "$srcdir" ] ; then
+  srcdir=`pwd`
+fi
+
+[ -x ../tools/pkcs1-conv ] || exit 77
+
+# Private RSA key, generated by openssl
+../tools/pkcs1-conv >testkey.priv <<EOF || exit 1
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQC3792bBgQ/mc8aYOFaLEJES/JipmLAeVgznob/Vrzvdcx+bl6L
+6gTphctU9ToOLC049dZYW3DJ53owUmbQgqB0vvLTjM9lGSEw4oXLrp7x/XVo/fZM
+UcRWq5H8Z0l6KANXHwcVcsjjqPBJ6WD/Is3o9rb58GU9GZcsMO2Zoh8z6wIDAQAB
+AoGABP+iwRS/xs6yPyBE34N2ZY6+zomBA4QIrpZvSr8bsVI9NW5gaWL5sTLunKdx
+ZXMz42li4tHRVdtRicCjhKUYIShH6J3ACKnBsCHwK6MgEyuDifxhmVt/b5xQNdOL
+bckwBXCL/XwkIkSgrvgUk/cXcvDXSdf7cRX+tgEHlbGjWGkCQQDaS9Xm3ZTIJ1CO
+/chlET2Cf/e5GzC79njzeg5oDyTG7qlXZudpZv5D6NatVoIDF4gfey6NKB7DNehT
+ff+v9wztAkEA17TN+cuFBuZX+KT3K7J1uavGqWOypDUy/h7PINODJLzoWAWnw94H
+NSu6/pXo1Q1WBMQa1jB1qxJaLpBp56iBNwJAUp6JIouSl/5pOvVKNxZDVXThaSml
+VD6AoIX9ldzFapVBelb0FqxoZ4NkXM50/n6VgnS4tawNmIx6lb8GWq8CMQJBAM5S
+lMofzyggX3jnYbycQFrOYYFYaWEDubi0A27koYYcYyj+j8+bqc1D/OLSxRg0X1jD
+st+5DnQJY9UyMPpyhNUCQQChMjCAamJP3xC7bOoza//k7E9kvx5IZcEsQWqok5BO
+PSVKy/gGBeN1Q7Rj+XoybQ/SqLpfgTYRI9UpbKmpkNuq
+-----END RSA PRIVATE KEY-----
+EOF
+
+../tools/pkcs1-conv >testkey.pub <<EOF || exit 1
+# Corresponding public key
+-----BEGIN PUBLIC KEY-----
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3792bBgQ/mc8aYOFaLEJES/Ji
+pmLAeVgznob/Vrzvdcx+bl6L6gTphctU9ToOLC049dZYW3DJ53owUmbQgqB0vvLT
+jM9lGSEw4oXLrp7x/XVo/fZMUcRWq5H8Z0l6KANXHwcVcsjjqPBJ6WD/Is3o9rb5
+8GU9GZcsMO2Zoh8z6wIDAQAB
+-----END PUBLIC KEY-----
+EOF
+
+../examples/rsa-sign testkey.priv >testsignature <<EOF || exit 1
+gazonk
+EOF
+
+# Signature on the data "gazonk\n", using sha1 and the above key
+cat > testsignature2 <<EOF && diff testsignature testsignature2 || exit 1
+5c96ffe7e925224ce6e98648bf2ed3193cab2fc82af9c7fa7fdc5b623bde1d77c5409129d16d1127ae4fad519c24059fe85f4a4360a900f3dee906e6de2ecd010fa56c02d3f7d0772d43439464a91b025722a6f0b6cb65aee1017b29aff4511f90315caae0be74c2ac496474896e7e3ad200cb7c609ddef5c674272964e4b780
+EOF
+
+../examples/rsa-verify testkey.pub testsignature <<EOF || exit 1
+gazonk
+EOF
+
+exit 0
diff --git a/testsuite/pkcs1-test.c b/testsuite/pkcs1-test.c
new file mode 100644 (file)
index 0000000..283e742
--- /dev/null
@@ -0,0 +1,18 @@
+#include "testutils.h"
+
+#include "pkcs1.h"
+
+int
+test_main(void)
+{
+  uint8_t buffer[16];
+  uint8_t expected[16] = {    1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                          0xff, 0xff, 0xff, 0xff, 0,    'a',  'b',  'c' };
+
+  pkcs1_signature_prefix(sizeof(buffer), buffer,
+                        3, "abc", 0);
+
+  ASSERT(MEMEQ(sizeof(buffer), buffer, expected));
+
+  SUCCESS();
+}
diff --git a/testsuite/random-prime-test.c b/testsuite/random-prime-test.c
new file mode 100644 (file)
index 0000000..6fdb449
--- /dev/null
@@ -0,0 +1,28 @@
+#include "testutils.h"
+
+#include "knuth-lfib.h"
+
+int
+test_main(void)
+{
+  struct knuth_lfib_ctx lfib;
+  mpz_t p;
+  unsigned bits;
+
+  knuth_lfib_init(&lfib, 17);
+
+  mpz_init(p);
+  for (bits = 6; bits < 1000; bits = bits + 1 + bits/20)
+    {
+      if (verbose)
+       fprintf(stderr, "bits = %d\n", bits);
+      
+      nettle_random_prime(p, bits, 0,
+                         &lfib, (nettle_random_func *) knuth_lfib_random,
+                         NULL, NULL);
+      ASSERT (mpz_sizeinbase (p, 2) == bits);
+      ASSERT (mpz_probab_prime_p(p, 25));
+    }
+
+  SUCCESS();
+}
diff --git a/testsuite/ripemd160-test.c b/testsuite/ripemd160-test.c
new file mode 100644 (file)
index 0000000..1237b70
--- /dev/null
@@ -0,0 +1,37 @@
+#include "testutils.h"
+#include "ripemd160.h"
+
+int
+test_main(void)
+{
+  test_hash(&nettle_ripemd160, 0, "",
+      H("9c1185a5c5e9fc54612808977ee8f548b2258d31"));
+
+  test_hash(&nettle_ripemd160, 1, "a",
+      H("0bdc9d2d256b3ee9daae347be6f4dc835a467ffe"));
+
+  test_hash(&nettle_ripemd160, 3, "abc",
+      H("8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"));
+
+  test_hash(&nettle_ripemd160, 26, "abcdefghijklmnopqrstuvwxyz",
+      H("f71c27109c692c1b56bbdceb5b9d2865b3708dbc"));
+
+  test_hash(&nettle_ripemd160, 14, "message digest",
+      H("5d0689ef49d2fae572b881b123a85ffa21595f36"));
+
+  test_hash(&nettle_ripemd160, 62,
+      "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+      "abcdefghijklmnopqrstuvwxyz0123456789",
+      H("b0e20b6e3116640286ed3a87a5713079b21f5189"));
+
+  test_hash(&nettle_ripemd160,  80,
+      "1234567890123456789012345678901234567890"
+      "1234567890123456789012345678901234567890",
+      H("9b752e45573d4b39f4dbd3323cab82bf63326bfb"));
+
+  /* Additional test vector, from Daniel Kahn Gillmor */
+  test_hash(&nettle_ripemd160, LDATA("38"),
+      H("6b2d075b1cd34cd1c3e43a995f110c55649dad0e"));
+
+  SUCCESS();
+}
diff --git a/testsuite/rsa-encrypt-test.c b/testsuite/rsa-encrypt-test.c
new file mode 100644 (file)
index 0000000..c009b75
--- /dev/null
@@ -0,0 +1,67 @@
+#include "testutils.h"
+
+#include "rsa.h"
+#include "knuth-lfib.h"
+
+int
+test_main(void)
+{
+  struct rsa_public_key pub;
+  struct rsa_private_key key;
+  struct knuth_lfib_ctx lfib;
+
+  /* FIXME: How is this spelled? */
+  const uint8_t *msg = "Squemish ossifrage";
+  unsigned msg_length;
+
+  uint8_t *decrypted;
+  unsigned decrypted_length;
+  
+  mpz_t gibberish;
+
+  rsa_private_key_init(&key);
+  rsa_public_key_init(&pub);
+  mpz_init(gibberish);
+
+  knuth_lfib_init(&lfib, 17);
+  
+  test_rsa_set_key_1(&pub, &key);
+  msg_length = strlen(msg);
+
+  if (verbose)
+    fprintf(stderr, "msg: `%s', length = %d\n", msg, msg_length);
+  
+  ASSERT(rsa_encrypt(&pub,
+                    &lfib, (nettle_random_func *) knuth_lfib_random,
+                    msg_length, msg,
+                    gibberish));
+
+  if (verbose)
+    {
+      /* In which GMP version was gmp_fprintf introduced? */
+      fprintf(stderr, "encrypted: ");
+      mpz_out_str(stderr, 10, gibberish);
+    }
+  
+  decrypted = xalloc(msg_length + 1);
+
+  decrypted_length = msg_length - 1;
+  ASSERT(!rsa_decrypt(&key, &decrypted_length, decrypted, gibberish));
+
+  decrypted_length = msg_length;
+  ASSERT(rsa_decrypt(&key, &decrypted_length, decrypted, gibberish));
+  ASSERT(decrypted_length == msg_length);
+  ASSERT(MEMEQ(msg_length, msg, decrypted));
+
+  decrypted_length = key.size;
+  ASSERT(rsa_decrypt(&key, &decrypted_length, decrypted, gibberish));
+  ASSERT(decrypted_length == msg_length);
+  ASSERT(MEMEQ(msg_length, msg, decrypted));
+  
+  rsa_private_key_clear(&key);
+  rsa_public_key_clear(&pub);
+  mpz_clear(gibberish);
+  free(decrypted);
+  SUCCESS();
+}
+  
diff --git a/testsuite/rsa-keygen-test.c b/testsuite/rsa-keygen-test.c
new file mode 100644 (file)
index 0000000..84b151e
--- /dev/null
@@ -0,0 +1,79 @@
+#include "testutils.h"
+
+#include "knuth-lfib.h"
+
+static void
+progress(void *ctx UNUSED, int c)
+{
+  fputc(c, stderr);
+}
+
+int
+test_main(void)
+{
+  struct rsa_public_key pub;
+  struct rsa_private_key key;
+  
+  struct knuth_lfib_ctx lfib;
+
+  mpz_t expected;
+  
+  mpz_init(expected);
+  
+  rsa_private_key_init(&key);
+  rsa_public_key_init(&pub);
+
+  /* Generate a 1024 bit key with random e */
+  knuth_lfib_init(&lfib, 13);
+
+  if (!rsa_generate_keypair(&pub, &key,
+                           &lfib, (nettle_random_func *) knuth_lfib_random,
+                           NULL, verbose ? progress : NULL,
+                           1024, 50))
+    FAIL();
+
+  test_rsa_key(&pub, &key);
+  
+  mpz_set_str(expected,
+             "2554579b857a9da3" "409dbd65c994b701" "aabf7347a78bd730"
+             "1525b5f511f326dd" "c05e1fd6c282faed" "6c79a4eb30539f10"
+             "46db024fe33174f5" "441da5fa175bf781" "8f7117c86cdacf9a"
+             "4589c048cc013eca" "7536d0868aca610a" "c20718e3fec3e835"
+             "f6c2fd920cba1be9" "e94a6c7238d9b2ee" "67ecc9f3d4a9a487"
+             "042190b66582b36a", 16);
+
+  test_rsa_md5(&pub, &key, expected);
+
+  /* Generate a 2000 bit key with fixed e */
+  knuth_lfib_init(&lfib, 17);
+
+  mpz_set_ui(pub.e, 17);
+  if (!rsa_generate_keypair(&pub, &key,
+                           &lfib, (nettle_random_func *) knuth_lfib_random,
+                           NULL, verbose ? progress : NULL,
+                           2000, 0))
+    FAIL();
+
+  test_rsa_key(&pub, &key);
+
+  mpz_set_str(expected,
+             "8c57dfb754270179" "600aced45b45490a" "56715da51f8d029d"
+             "057b58187670f9e4" "1a2da64cd3435483" "16b26c860ca97aed"
+             "fd3ebf5e3dd97226" "1d1b5536da483863" "f9ad5f47437e7a2a"
+             "0119bb0045c64f5a" "cb634d7aff7051b4" "3d01b1c8bc13cc93"
+             "0799d57ada86394f" "1286b5ae9480d167" "8f48e9e78bf3ea4f"
+             "1ed9a9e381c8f046" "3a25bf30238e7c59" "1c9998255141f628"
+             "68e8a01871587152" "38df08281894a5b9" "e9026b55337f9f29"
+             "240793935b05162b" "8fa8d2390d7cb407" "52413dd5f7bccdad"
+             "232e1c27bae30548" "09797991e13dee5d" "c688985433e63050"
+             "6d9a171e144ef442" "eb001166bd95bcdd" "92b3c2e0bd4012a2"
+             "2dd05cb032f6ab6b" "dd7c", 16);
+
+  test_rsa_sha1(&pub, &key, expected);
+  
+  rsa_private_key_clear(&key);
+  rsa_public_key_clear(&pub);
+  mpz_clear(expected);
+
+  SUCCESS();
+}
diff --git a/testsuite/rsa-test.c b/testsuite/rsa-test.c
new file mode 100644 (file)
index 0000000..8fc37b5
--- /dev/null
@@ -0,0 +1,182 @@
+#include "testutils.h"
+
+int
+test_main(void)
+{
+  struct rsa_public_key pub;
+  struct rsa_private_key key;
+
+  mpz_t expected;
+  
+  mpz_init(expected);
+  
+  rsa_private_key_init(&key);
+  rsa_public_key_init(&pub);
+
+  test_rsa_set_key_1(&pub, &key);
+  
+  /* Test md5 signatures */
+  mpz_set_str(expected,
+             "53bf517009fa956e" "3daa6adc95e8663d" "3759002f488bbbad"
+             "e49f62792d85dbcc" "293f68e2b68ef89a" "c5bd42d98f845325"
+             "3e6c1b76fc337db5" "e0053f255c55faf3" "eb6cc568ad7f5013"
+             "5b269a64acb9eaa7" "b7f09d9bd90310e6" "4c58f6dbe673ada2"
+             "67c97a9d99e19f9d" "87960d9ce3f0d5ce" "84f401fe7e10fa24"
+             "28b9bffcf9", 16);
+
+  test_rsa_md5(&pub, &key, expected);
+
+  /* Test sha1 signature */
+  mpz_set_str(expected,
+             "129b405ed85db88c" "55d35344c4b52854" "496516b4d63d8211"
+             "80a0c24d6ced9047" "33065a564bbd33d0" "a5cdfd204b9c6d15"
+             "78337207c2f1662d" "c73906c7a0f2bf5c" "af92cef9121957b1"
+             "dcb111ff47b92389" "888e384d0cfd1b1e" "e5d7003a8feff3fd"
+             "dd6a71d242a79272" "25234d67ba369441" "c12ae555c697754e"
+             "a17f93fa92", 16);
+
+  test_rsa_sha1(&pub, &key, expected);
+
+  mpz_set_str(expected,
+             "13f9e43f7a401a73" "0a74985c01520d76" "bf5f2e2dff91e93b"
+             "9267d8c388d6937b" "d4bc6f1fa31618a9" "b5e3a1a875af72f5"
+             "0e805dbfebdf4348" "7d49763f0b365e78" "d2c0ea8fb3785897"
+             "782289a58f998907" "248c9cdf2c643d7e" "6ba6b55026227773"
+             "6f19caa69c4fc6d7" "7e2e5d4cd6b7a82b" "900d201ffd000448"
+             "685e5a4f3e", 16);
+
+  test_rsa_sha256(&pub, &key, expected);
+
+  mpz_set_str(expected,
+             "06327f717f43bcf3" "5994e567e8241963" "8c22e1057a7771e7"
+             "a665bb7441a39cc8" "7762f6b1a459cae3" "281462ed3f6aec48"
+             "15c2365797a02af6" "8a603adf276c46f6" "e6afb25d07c57f47"
+             "c516aff84abda629" "cc83d9364eb3616d" "7d4ddf0e9a25fac5"
+             "7d56a252b0cb7b1f" "8266b525e9b893af" "116e7845c0969a9f"
+             "603e2543f3", 16);
+
+  test_rsa_sha512(&pub, &key, expected);
+
+  /* 777-bit key, generated by
+   *
+   *   lsh-keygen -a rsa -l 777 -f advanced-hex
+   *
+   * Interesting because the size of n doesn't equal the sum of the
+   * sizes of p and q. 
+   *
+   * (private-key (rsa-pkcs1
+   *        (n #013b04440e3eef25 d51c738d508a7fa8 b3445180c342af0f
+   *            4cb5a789047300e2 cfc5c5450974cfc2 448aeaaa7f43c374
+   *            c9a3b038b181f2d1 0f1a2327fd2c087b a49bf1086969fd2c
+   *            d1df3fd69f81fa4b 162cc8bbb363fc95 b7b24b9c53d0c67e
+   *            f52b#)
+   *        (e #3f1a012d#)
+   *        (d #f9bae89dacca6cca c21e0412b4df8355 6fe7c5322bbae8ad
+   *            3f11494fd12bc076 d4a7da3050fe109d 2074db09cc6a93b4
+   *            745479522558379e a0ddfa74f86c9e9e a22c3b0e93d51447
+   *            0feb38105dd35395 63b91ee32776f40c 67b2a175690f7abb
+   *            25#)
+   *        (p #0b73c990eeda0a2a 2c26416052c85560 0c5c0f5ce86a8326
+   *            166acea91786237a 7ff884e66dbfdd3a ab9d9801414c1506
+   *            8b#)
+   *        (q #1b81c19a62802a41 9c99283331b0badb 08eb0c25ffce0fbf
+   *            50017850036f32f3 2132a845b91a5236 61f7b451d587383f
+   *            e1#)
+   *        (a #0a912fc93a6cca6b 3521725a3065b3be 3c9745e29c93303d
+   *            7d29316c6cafa4a2 89945f964fcdea59 1f9d248b0b6734be
+   *            c9#)
+   *        (b #1658eca933251813 1eb19c77aba13d73 e0b8f4ce986d7615
+   *            764c6b0b03c18146 46b7f332c43e05c5 351e09006979ca5b
+   *            05#)
+   *        (c #0114720dace7b27f 2bf2850c1804869f 79a0aad0ec02e6b4
+   *            05e1831619db2f10 bb9b6a8fd5c95df2 eb78f303ea0c0cc8
+   *            06#)))
+   */
+  
+  mpz_set_str(pub.n,
+             "013b04440e3eef25" "d51c738d508a7fa8" "b3445180c342af0f"
+             "4cb5a789047300e2" "cfc5c5450974cfc2" "448aeaaa7f43c374"
+             "c9a3b038b181f2d1" "0f1a2327fd2c087b" "a49bf1086969fd2c"
+             "d1df3fd69f81fa4b" "162cc8bbb363fc95" "b7b24b9c53d0c67e"
+             "f52b", 16);
+  
+  mpz_set_str(pub.e, "3f1a012d", 16);
+
+  if (!rsa_public_key_prepare(&pub))
+    FAIL();
+  
+  mpz_set_str(key.p,
+             "0b73c990eeda0a2a" "2c26416052c85560" "0c5c0f5ce86a8326"
+             "166acea91786237a" "7ff884e66dbfdd3a" "ab9d9801414c1506"
+             "8b", 16);
+  
+  mpz_set_str(key.q,
+             "1b81c19a62802a41" "9c99283331b0badb" "08eb0c25ffce0fbf"
+             "50017850036f32f3" "2132a845b91a5236" "61f7b451d587383f"
+             "e1", 16);
+  
+  mpz_set_str(key.a,
+             "0a912fc93a6cca6b" "3521725a3065b3be" "3c9745e29c93303d"
+             "7d29316c6cafa4a2" "89945f964fcdea59" "1f9d248b0b6734be"
+             "c9", 16);
+  
+  mpz_set_str(key.b,
+             "1658eca933251813" "1eb19c77aba13d73" "e0b8f4ce986d7615"
+             "764c6b0b03c18146" "46b7f332c43e05c5" "351e09006979ca5b"
+             "05", 16);
+  
+  mpz_set_str(key.c,
+             "0114720dace7b27f" "2bf2850c1804869f" "79a0aad0ec02e6b4"
+             "05e1831619db2f10" "bb9b6a8fd5c95df2" "eb78f303ea0c0cc8"
+             "06", 16);
+
+  if (!rsa_private_key_prepare(&key))
+    FAIL();
+
+  if (pub.size != key.size)
+    FAIL();
+
+  /* Test md5 signatures */
+  mpz_set_str(expected,
+             "011b939f6fbacf7f" "7d3217b022d07477" "e582e34d4bbddd4c"
+             "31520647417fc8a6" "18b2e196d799cedd" "d8f5c062fd796b0f"
+             "72ab46db2ac6ec74" "39d856be3f746cc4" "3e0a15429954736a"
+             "60a8b3c6ea93d2cb" "c69085c307d72517" "07d43bf97a3b51eb"
+             "9e89", 16);
+
+  test_rsa_md5(&pub, &key, expected);
+
+  /* Test sha1 signature */
+  mpz_set_str(expected,
+             "648c49e0ed045547" "08381d0bcd03b7bd" "b0f80a0e9030525d"
+             "234327a1c96b8660" "f1c01c6f15ae76d0" "4f53a53806b7e4db"
+             "1f789e6e89b538f6" "88fcbd2caa6abef0" "5432d52f3de463a4"
+             "a9e6de94f1b7bb68" "3c07edf0924fc93f" "56e1a0dba8f7491c"
+             "5c", 16);
+
+  test_rsa_sha1(&pub, &key, expected);
+
+  mpz_set_str(expected,
+             "d759bb28b4d249a2" "f8b67bdbb1ab7f50" "c88712fbcabc2956"
+             "1ec6ca3f8fdafe7a" "38433d7da287b8f7" "87857274c1640b2b"
+             "e652cd89c501d570" "3980a0af5c6bb60c" "f84feab25b099d06"
+             "e2519accb73dac43" "fb8bdad28835f3bd" "84c43678fe2ef41f"
+             "af", 16);
+
+  test_rsa_sha256(&pub, &key, expected);
+
+  mpz_set_str(expected,
+             "f761aae6273d6149" "06d8c208fb2897ca" "d798a46af4985b86"
+             "51d51e6a3e11cbe0" "84f18ba8979c0f54" "11493f7c6e770560"
+             "03db2146b4dbcaa6" "4aae2e02aab9ff7b" "1ddf77dc72145cf1"
+             "c26ebde7c708cdc1" "62e167a7ac33967b" "386a40ea4a988d17"
+             "47", 16);
+
+  test_rsa_sha512(&pub, &key, expected);
+
+  rsa_private_key_clear(&key);
+  rsa_public_key_clear(&pub);
+  mpz_clear(expected);
+
+  SUCCESS();
+}
diff --git a/testsuite/rsa2sexp-test.c b/testsuite/rsa2sexp-test.c
new file mode 100644 (file)
index 0000000..596a978
--- /dev/null
@@ -0,0 +1,107 @@
+#include "testutils.h"
+
+#include "buffer.h"
+
+int
+test_main(void)
+{
+  struct rsa_public_key pub;
+  struct rsa_private_key priv;
+
+  struct nettle_buffer buffer;
+  
+  rsa_public_key_init(&pub);
+  rsa_private_key_init(&priv);
+
+  mpz_set_str(pub.n,
+             "085c3408989acae4faec3cbbad91c90d34c1d259cd74121a"
+             "36f38b0b51424a9b2be514a04377113a6cdafe79dd7d5f2e"
+             "cc8b5e9661189b86a7b22239907c25", 16);
+  mpz_set_str(pub.e, "36ad4b1d", 16);
+
+  ASSERT(rsa_public_key_prepare(&pub));
+  
+  mpz_set_str(priv.d,
+             "06ee6d4ff3c239e408150daf8117abfa36a40ad4455d9059"
+             "a86d52f33a2de07418a0a699594588c64810248c9412d554"
+             "f74af947c73c32007e87c92f0937ed", 16);
+
+  mpz_set_str(priv.p,
+             "03259879b24315e9cf14254824c7935d807cdb6990f414a0"
+             "f65e6065130a611f", 16);
+
+  mpz_set_str(priv.q,
+             "02a81ba73bad45fc73b36deffce52d1b73e0747f4d8a8264"
+             "8cecd310448ea63b", 16);
+
+  mpz_set_str(priv.a,
+             "026cbdad5dd0046e093f060ecd5b4ac918e098b0278bb752"
+             "b7cadd6a8944f0b9", 16);
+
+  mpz_set_str(priv.b,
+             "0148751e622d6d58e3bb094afd6edacf7370351d068e2ce9"
+             "f565c5528c4a7473", 16);
+
+  mpz_set_str(priv.c,
+             "f8a458ea73a018dc6fa56863e3bc6de405f364f77dee6f09"
+             "62679ea1a8282e", 16);
+
+  ASSERT(rsa_private_key_prepare(&priv));
+  
+  nettle_buffer_init(&buffer);
+  ASSERT(rsa_keypair_to_sexp(&buffer, "rsa", &pub, &priv));
+
+  if (verbose)
+    {
+      printf("private:");
+      print_hex(buffer.size, buffer.contents);  
+    }
+  
+  ASSERT(MEMEQH(buffer.size, buffer.contents,
+               "2831313a707269766174652d6b657928"
+               "333a72736128313a6e36333a085c3408"
+               "989acae4faec3cbbad91c90d34c1d259"
+               "cd74121a36f38b0b51424a9b2be514a0"
+               "4377113a6cdafe79dd7d5f2ecc8b5e96"
+               "61189b86a7b22239907c252928313a65"
+               "343a36ad4b1d2928313a6436333a06ee"
+               "6d4ff3c239e408150daf8117abfa36a4"
+               "0ad4455d9059a86d52f33a2de07418a0"
+               "a699594588c64810248c9412d554f74a"
+               "f947c73c32007e87c92f0937ed292831"
+               "3a7033323a03259879b24315e9cf1425"
+               "4824c7935d807cdb6990f414a0f65e60"
+               "65130a611f2928313a7133323a02a81b"
+               "a73bad45fc73b36deffce52d1b73e074"
+               "7f4d8a82648cecd310448ea63b292831"
+               "3a6133323a026cbdad5dd0046e093f06"
+               "0ecd5b4ac918e098b0278bb752b7cadd"
+               "6a8944f0b92928313a6233323a014875"
+               "1e622d6d58e3bb094afd6edacf737035"
+               "1d068e2ce9f565c5528c4a7473292831"
+               "3a6333323a00f8a458ea73a018dc6fa5"
+               "6863e3bc6de405f364f77dee6f096267"
+               "9ea1a8282e292929"));
+
+  nettle_buffer_clear(&buffer);
+  ASSERT(rsa_keypair_to_sexp(&buffer, NULL, &pub, NULL));
+
+  if (verbose)
+    {
+      printf("public:");
+      print_hex(buffer.size, buffer.contents);  
+    }
+  ASSERT(MEMEQH(buffer.size, buffer.contents,
+               "2831303a7075626c69632d6b65792839"
+               "3a7273612d706b63733128313a6e3633"
+               "3a085c3408989acae4faec3cbbad91c9"
+               "0d34c1d259cd74121a36f38b0b51424a"
+               "9b2be514a04377113a6cdafe79dd7d5f"
+               "2ecc8b5e9661189b86a7b22239907c25"
+               "2928313a65343a36ad4b1d292929"));
+
+  rsa_public_key_clear(&pub);
+  rsa_private_key_clear(&priv);
+  
+  SUCCESS();
+}
diff --git a/testsuite/run-tests b/testsuite/run-tests
new file mode 100755 (executable)
index 0000000..f240599
--- /dev/null
@@ -0,0 +1,104 @@
+#! /bin/sh
+
+failed=0
+all=0
+
+debug='no'
+testflags=''
+
+if [ -z "$srcdir" ] ; then
+  srcdir=`pwd`
+fi
+
+export srcdir
+
+# When used in make rules, we sometimes get the filenames VPATH
+# expanded, but usually not. 
+find_program () {
+    case "$1" in
+       */*)
+         echo "$1"
+         ;;
+       *)
+         if [ -x "$1" ] ; then
+             echo "./$1"
+         else
+             echo "$srcdir/$1"
+         fi
+         ;;
+    esac
+}
+
+env_program () {
+  if [ -x "$1" ] ; then
+    if "$1"; then : ; else
+      echo FAIL: $1
+      exit 1
+    fi
+  fi
+}
+
+test_program () {
+  testname=`basename "$1" .exe`
+  testname=`basename "$testname" -test`
+  "$1" $testflags
+  case "$?" in
+      0)
+       echo PASS: $testname
+       all=`expr $all + 1`
+       ;;
+      77)
+       echo SKIP: $testname
+      ;;
+      *)
+       echo FAIL: $testname
+       failed=`expr $failed + 1`
+       all=`expr $all + 1`
+       ;;
+  esac
+}
+
+env_program `find_program setup-env`
+
+while test $# != 0
+do
+  case "$1" in
+  --debug)
+    debug=yes
+    ;;
+  -v)
+    testflags='-v'
+    ;;
+  -*)
+    echo >&2 'Unknown option `'"$1'" 
+    exit 1
+    ;;
+  *)
+    break
+    ;;
+  esac
+  shift
+done
+  
+if [ $# -eq 0 ] ; then
+  for f in *-test; do test_program "./$f"; done
+else
+  for f in "$@" ; do test_program `find_program "$f"`; done
+fi
+
+if [ $failed -eq 0 ] ; then
+  banner="All $all tests passed"
+else
+  banner="$failed of $all tests failed"
+fi
+dashes=`echo "$banner" | sed s/./=/g`
+echo "$dashes"
+echo "$banner"
+echo "$dashes"
+
+if [ "x$debug" = xno ] ; then
+  env_program `find_program teardown-env`
+fi
+
+[ "$failed" -eq 0 ]
+
diff --git a/testsuite/serpent-test.c b/testsuite/serpent-test.c
new file mode 100644 (file)
index 0000000..d9e193b
--- /dev/null
@@ -0,0 +1,291 @@
+#include "testutils.h"
+#include "serpent.h"
+
+static uint8_t *
+decode_hex_reverse (const char *hex)
+{
+  unsigned length = decode_hex_length (hex);
+  uint8_t *p = xalloc(length);
+  unsigned i;
+
+  decode_hex(p, hex);
+
+  for (i = 0; i < (length+1)/2; i++)
+    {
+      uint8_t t = p[i];
+      p[i] = p[length - 1 - i];
+      p[length - 1 - i] = t;
+    }
+  return p;
+}
+
+#define RH(x) decode_hex_reverse(x)
+#define RHL(x) decode_hex_length(x), decode_hex_reverse(x)
+
+int
+test_main(void)
+{
+  /* From libgcrypt */
+  test_cipher(&nettle_serpent128,
+             HL("0000000000000000 0000000000000000"),
+             HL("D29D576FCEA3A3A7 ED9099F29273D78E"),
+             H("B2288B968AE8B086 48D1CE9606FD992D"));
+  test_cipher(&nettle_serpent192,
+             HL("0000000000000000 0000000000000000 0000000000000000"),
+             HL("D29D576FCEABA3A7 ED9899F2927BD78E"),
+             H("130E353E1037C224 05E8FAEFB2C3C3E9"));
+  test_cipher(&nettle_serpent256,
+             HL("0000000000000000 0000000000000000"
+                "0000000000000000 0000000000000000"),
+             HL("D095576FCEA3E3A7 ED98D9F29073D78E"),
+             H("B90EE5862DE69168 F2BDD5125B45472B"));
+  test_cipher(&nettle_serpent256,
+             HL("0000000000000000 0000000000000000"
+                "0000000000000000 0000000000000000"),
+             HL("0000000001000000 0200000003000000"),
+             H("2061A42782BD52EC 691EC383B03BA77C"));
+
+  /* The first test for each key size from the ecb_vk.txt and ecb_vt.txt
+   * files in the serpent package. */
+
+  /* NOTE: These vectors uses strange byte-reversed order of inputs
+     and outputs. */
+  /* 128 bit key */
+
+  /* vk, 1 */
+  test_cipher(&nettle_serpent128,
+             RHL("8000000000000000 0000000000000000"),
+             RHL("0000000000000000 0000000000000000"),
+             RH("49AFBFAD9D5A3405 2CD8FFA5986BD2DD"));
+
+  /* vt, 1 */
+  test_cipher(&nettle_serpent128,
+             RHL("0000000000000000 0000000000000000"),
+             RHL("8000000000000000 0000000000000000"),
+             RH("10B5FFB720B8CB90 02A1142B0BA2E94A"));
+
+  /* 192 bit key */
+
+  /* vk, 1 */
+  test_cipher(&nettle_serpent192,
+             RHL("8000000000000000 0000000000000000"
+                "0000000000000000"),
+             RHL("0000000000000000 0000000000000000"),
+             RH("E78E5402C7195568 AC3678F7A3F60C66"));
+
+  /* vt, 1 */
+  test_cipher(&nettle_serpent192,
+             RHL("0000000000000000 0000000000000000"
+                "0000000000000000"),
+             RHL("8000000000000000 0000000000000000"),
+             RH("B10B271BA25257E1 294F2B51F076D0D9"));
+
+  /* 256 bit key */
+
+  /* vk, 1 */
+  test_cipher(&nettle_serpent256,
+             RHL("8000000000000000 0000000000000000"
+                "0000000000000000 0000000000000000"),
+             RHL("0000000000000000 0000000000000000"),
+             RH("ABED96E766BF28CB C0EBD21A82EF0819"));
+
+  /* vt, 1 */
+  test_cipher(&nettle_serpent256,
+             RHL("0000000000000000 0000000000000000"
+                "0000000000000000 0000000000000000"),
+             RHL("8000000000000000 0000000000000000"),
+             RH("DA5A7992B1B4AE6F 8C004BC8A7DE5520"));
+
+  /* Test vectors from
+     http://www.cs.technion.ac.il/~biham/Reports/Serpent/ */
+
+  /* serpent128 */
+  /* Set 4, vector#  0 */
+  test_cipher(&nettle_serpent128,
+             HL("000102030405060708090A0B0C0D0E0F"),
+             HL("00112233445566778899AABBCCDDEEFF"),
+             H("563E2CF8740A27C164804560391E9B27"));
+
+  /* Set 4, vector#  1 */
+  test_cipher(&nettle_serpent128,
+             HL("2BD6459F82C5B300952C49104881FF48"),
+             HL("EA024714AD5C4D84EA024714AD5C4D84"),
+             H("92D7F8EF2C36C53409F275902F06539F"));
+
+  /* serpent192 */
+  /* Set 4, vector#  0 */
+  test_cipher(&nettle_serpent192,
+             HL("000102030405060708090A0B0C0D0E0F1011121314151617"),
+             HL("00112233445566778899AABBCCDDEEFF"),
+             H("6AB816C82DE53B93005008AFA2246A02"));
+
+  /* Set 4, vector#  1 */
+  test_cipher(&nettle_serpent192,
+             HL("2BD6459F82C5B300952C49104881FF482BD6459F82C5B300"),
+             HL("EA024714AD5C4D84EA024714AD5C4D84"),
+             H("827B18C2678A239DFC5512842000E204"));
+
+  /* serpent256 */
+  /* Set 4, vector#  0 */
+  test_cipher(&nettle_serpent256,
+             HL("000102030405060708090A0B0C0D0E0F"
+                "101112131415161718191A1B1C1D1E1F"),
+             HL("00112233445566778899AABBCCDDEEFF"),
+             H("2868B7A2D28ECD5E4FDEFAC3C4330074"));
+
+  /* Set 4, vector#  1 */
+  test_cipher(&nettle_serpent256,
+             HL("2BD6459F82C5B300952C49104881FF48"
+                "2BD6459F82C5B300952C49104881FF48"),
+             HL("EA024714AD5C4D84EA024714AD5C4D84"),
+             H("3E507730776B93FDEA661235E1DD99F0"));
+
+  /* Test key padding. We use nettle_serpent256, which actually works
+     also with key sizes smaller than 32 bytes. */
+  test_cipher(&nettle_serpent256,
+             HL("00112233440100000000000000000000"
+                "00000000000000000000000000000000"),
+             HL("0000000001000000 0200000003000000"),
+             H("C1415AC653FD7C7F D917482EE8EBFE25"));
+
+  /* Currrently, key sizes smaller than SERPENT_MIN_KEY_SIZE bytes
+     (128 bits) are not supported. */
+  test_cipher(&nettle_serpent256,
+             HL("0011223344"),
+             HL("0000000001000000 0200000003000000"),
+             H("C1415AC653FD7C7F D917482EE8EBFE25"));
+
+  test_cipher(&nettle_serpent256,
+             HL("00112233445566778899aabbccddeeff"
+                "00010000000000000000000000000000"),
+             HL("0000000001000000 0200000003000000"),
+             H("8EB9C958EAFFDF42 009755D7B6458838"));
+
+  test_cipher(&nettle_serpent256,
+             HL("00112233445566778899aabbccddeeff"
+                "00"),
+             HL("0000000001000000 0200000003000000"),
+             H("8EB9C958EAFFDF42 009755D7B6458838"));
+
+  test_cipher(&nettle_serpent256,
+             HL("00112233445566778899aabbccddeeff"
+                "00112201000000000000000000000000"),
+             HL("0000000001000000 0200000003000000"),
+             H("C8A078D8212AC96D 9060E30EC5CBB5C7"));
+
+  test_cipher(&nettle_serpent256,
+             HL("00112233445566778899aabbccddeeff"
+                "001122"),
+             HL("0000000001000000 0200000003000000"),
+             H("C8A078D8212AC96D 9060E30EC5CBB5C7"));
+
+  /* Test with multiple blocks. */
+  test_cipher(&nettle_serpent128,
+             HL("e87450aa0fd87293fd0371483a459bd2"),
+             HL("a78a7a8d392f629d bd13674c8dce6fa2"),
+             H("b3d488986c80dea7 c5ebdab4907871c9"));
+
+  test_cipher(&nettle_serpent128,
+             HL("e87450aa0fd87293fd0371483a459bd2"),
+             HL("a78a7a8d392f629d bd13674c8dce6fa2"
+                "930c74dec02a11d8 c80d90b5e5c887a7"),
+             H("b3d488986c80dea7 c5ebdab4907871c9"
+               "a4b92b13b79afb37 5518b01bfd706a37"));
+
+  test_cipher(&nettle_serpent128,
+             HL("e87450aa0fd87293fd0371483a459bd2"),
+             HL("a78a7a8d392f629d bd13674c8dce6fa2"
+                "930c74dec02a11d8 c80d90b5e5c887a7"
+                "83c92a921b5b2028 d9cb313a5f07ab09"),
+             H("b3d488986c80dea7 c5ebdab4907871c9"
+               "a4b92b13b79afb37 5518b01bfd706a37"
+               "8e44c2d463df4531 165461699edbad03"));
+
+  test_cipher(&nettle_serpent128,
+             HL("91c8e949e12f0e38 7b2473238a3df1b6"),
+             HL("00000000 00000001 00000002 00000003"
+                "00000004 00000005 00000006 00000007"
+                "00000008 00000009 0000000a 0000000b"
+                "0000000c 0000000d 0000000e 0000000f"),
+             H("2db9f0a39d4f31a4 b1a83cd1032fe1bd"
+               "3606caa84a220b1b f6f43ff80a831203"
+               "8c6c8d2793dc10b3 904d30e194f086a6"
+               "b2f3e932b9b3f8d1 d4d074f7bd1ff7a3"));
+             
+  test_cipher(&nettle_serpent128,
+             HL("e87450aa0fd87293fd0371483a459bd2"),
+             HL("a78a7a8d392f629d bd13674c8dce6fa2"
+                "930c74dec02a11d8 c80d90b5e5c887a7"
+                "83c92a921b5b2028 d9cb313a5f07ab09"
+                "672eadf1624a2ed0 c42d1b08b076f75a"),
+             H("b3d488986c80dea7 c5ebdab4907871c9"
+               "a4b92b13b79afb37 5518b01bfd706a37"
+               "8e44c2d463df4531 165461699edbad03"
+               "30ac8c52697102ae 3b725dba79ceb250"));
+
+  test_cipher(&nettle_serpent128,
+             HL("e87450aa0fd87293fd0371483a459bd2"),
+             HL("a78a7a8d392f629d bd13674c8dce6fa2"
+                "930c74dec02a11d8 c80d90b5e5c887a7"
+                "83c92a921b5b2028 d9cb313a5f07ab09"
+                "672eadf1624a2ed0 c42d1b08b076f75a"
+                "7378272aa57ad7c8 803e326689541266"),
+             H("b3d488986c80dea7 c5ebdab4907871c9"
+               "a4b92b13b79afb37 5518b01bfd706a37"
+               "8e44c2d463df4531 165461699edbad03"
+               "30ac8c52697102ae 3b725dba79ceb250"
+               "d308b83478e86dbb 629f18736cca042f"));
+
+  test_cipher(&nettle_serpent128,
+             HL("e87450aa0fd87293fd0371483a459bd2"),
+             HL("a78a7a8d392f629d bd13674c8dce6fa2"
+                "930c74dec02a11d8 c80d90b5e5c887a7"
+                "83c92a921b5b2028 d9cb313a5f07ab09"
+                "672eadf1624a2ed0 c42d1b08b076f75a"
+                "7378272aa57ad7c8 803e326689541266"
+                "b7a2efda5721776f 4113d63a702ac3ae"),
+             H("b3d488986c80dea7 c5ebdab4907871c9"
+               "a4b92b13b79afb37 5518b01bfd706a37"
+               "8e44c2d463df4531 165461699edbad03"
+               "30ac8c52697102ae 3b725dba79ceb250"
+               "d308b83478e86dbb 629f18736cca042f"
+               "006b89e494469adf 0ee78c60684dff86"));
+    
+  test_cipher(&nettle_serpent128,
+             HL("e87450aa0fd87293fd0371483a459bd2"),
+             HL("a78a7a8d392f629d bd13674c8dce6fa2"
+                "930c74dec02a11d8 c80d90b5e5c887a7"
+                "83c92a921b5b2028 d9cb313a5f07ab09"
+                "672eadf1624a2ed0 c42d1b08b076f75a"
+                "7378272aa57ad7c8 803e326689541266"
+                "b7a2efda5721776f 4113d63a702ac3ae"
+                "cd1be7bbfad74819 644617f8656e9e5b"),
+             H("b3d488986c80dea7 c5ebdab4907871c9"
+               "a4b92b13b79afb37 5518b01bfd706a37"
+               "8e44c2d463df4531 165461699edbad03"
+               "30ac8c52697102ae 3b725dba79ceb250"
+               "d308b83478e86dbb 629f18736cca042f"
+               "006b89e494469adf 0ee78c60684dff86"
+               "5f2c99908ee77ffe aea3d30cb78a1ce1"));
+
+  test_cipher(&nettle_serpent128,
+             HL("e87450aa0fd87293fd0371483a459bd2"),
+             HL("a78a7a8d392f629d bd13674c8dce6fa2"
+                "930c74dec02a11d8 c80d90b5e5c887a7"
+                "83c92a921b5b2028 d9cb313a5f07ab09"
+                "672eadf1624a2ed0 c42d1b08b076f75a"
+                "7378272aa57ad7c8 803e326689541266"
+                "b7a2efda5721776f 4113d63a702ac3ae"
+                "cd1be7bbfad74819 644617f8656e9e5b"
+                "34d449409c1f850a 4cb6700d6ef3405f"),
+             H("b3d488986c80dea7 c5ebdab4907871c9"
+               "a4b92b13b79afb37 5518b01bfd706a37"
+               "8e44c2d463df4531 165461699edbad03"
+               "30ac8c52697102ae 3b725dba79ceb250"
+               "d308b83478e86dbb 629f18736cca042f"
+               "006b89e494469adf 0ee78c60684dff86"
+               "5f2c99908ee77ffe aea3d30cb78a1ce1"
+               "ebe855dd51532477 4d2d55969e032e6c"));
+
+  SUCCESS();
+}
diff --git a/testsuite/sexp-conv-test b/testsuite/sexp-conv-test
new file mode 100755 (executable)
index 0000000..a3470ab
--- /dev/null
@@ -0,0 +1,124 @@
+#! /bin/sh
+
+if [ -z "$srcdir" ] ; then
+  srcdir=`pwd`
+fi
+
+print_raw () {
+    printf "%s" "$1" > "$2"
+}
+
+print_nl () {
+    printf "%s\n" "$1" > "$2"
+}
+
+test_advanced () {
+    print_raw "$1" test.in
+    if ../tools/sexp-conv -s advanced <test.in >test1.out ; then
+       true
+    else
+       exit 1
+    fi
+    print_nl "$2" test2.out
+
+    if cmp test1.out test2.out ; then
+       true
+    else
+       exit 1;
+    fi
+}
+
+test_advanced_hex () {
+    print_raw "$1" test.in
+    if ../tools/sexp-conv -s hex <test.in >test1.out ; then
+       true
+    else
+       exit 1
+    fi
+    print_nl "$2" test2.out
+
+    if cmp test1.out test2.out ; then
+       true
+    else
+       exit 1;
+    fi
+}
+
+test_transport () {
+    print_raw "$1" test.in
+    if ../tools/sexp-conv -s transport <test.in >test1.out ; then
+       true
+    else
+       exit 1
+    fi
+    print_nl "$2" test2.out
+
+    if cmp test1.out test2.out ; then
+       true
+    else
+       exit 1;
+    fi
+}
+
+test_canonical () {
+    print_raw "$1" test.in
+    if ../tools/sexp-conv -s canonical <test.in >test1.out ; then
+       true
+    else
+       exit 1
+    fi
+    print_raw "$2" test2.out
+
+    if cmp test1.out test2.out ; then
+       true
+    else
+       exit 1;
+    fi
+}
+
+test_advanced '0:' '""'
+test_advanced '3:foo' 'foo'
+test_advanced '12:fooooooooooo' 'fooooooooooo'
+test_advanced '10:fooooooooo' 'fooooooooo'
+test_advanced '4:3des' '"3des"' 
+test_advanced '"foo"' 'foo' 
+test_advanced '4:foo
+' '"foo\n"'
+# Having the string end with a \ breaks with sysv echo. \x seems harmless.
+test_advanced '3:"\x' '"\"\\x"' 
+test_advanced '()' '()' 
+test_advanced '(foo bar baz)' '(foo bar
+     baz)' 
+test_advanced '; comment
+()' '; comment
+()' 
+test_advanced '(foo ; gazonk
+bar)' '(foo ; gazonk
+     bar)'
+
+test_advanced '(foo[bar]foo)' '(foo [bar]foo)'
+
+test_advanced '(#aabb#)' '(|qrs=|)'
+test_advanced '(|qrs=|)' '(|qrs=|)'
+test_advanced_hex '(|qrs=|)' '(#aabb#)'
+test_advanced_hex '(#aabb#)' '(#aabb#)'
+test_advanced_hex '{MToR}' '#11#'
+test_advanced_hex '|EQ==|' '#11#'
+
+test_transport '0:' '{MDo=}'
+test_transport '()' '{KCk=}'
+test_transport '1:A' '{MTpB}'
+test_transport 'foo' '{Mzpmb28=}'
+test_transport '(foo bar baz)' '{KDM6Zm9vMzpiYXIzOmJheik=}'
+
+test_canonical '""' '0:'
+test_canonical '{MDo=}' '0:'
+test_canonical '{KCk=}' '()'
+test_canonical '{MTpB}' '1:A'
+test_canonical 'foo' '3:foo'
+test_canonical 'fooooooooooo' '12:fooooooooooo'
+test_canonical 'fooooooooo' '10:fooooooooo'
+test_canonical '(foo bar baz)' '(3:foo3:bar3:baz)' 
+test_canonical '{KDM6Zm9vMzpiYXIzOmJheik=}' '(3:foo3:bar3:baz)' 
+
+exit 0
diff --git a/testsuite/sexp-format-test.c b/testsuite/sexp-format-test.c
new file mode 100644 (file)
index 0000000..33c585f
--- /dev/null
@@ -0,0 +1,160 @@
+#include "testutils.h"
+#include "sexp.h"
+
+#include "buffer.h"
+
+#if HAVE_LIBGMP
+# include "bignum.h"
+#endif
+
+int
+test_main(void)
+{
+  struct nettle_buffer buffer;
+
+  {
+    const uint8_t e[] = "(3:foo(3:bar17:xxxxxxxxxxxxxxxxx))";
+
+    nettle_buffer_init(&buffer);
+    ASSERT(sexp_format(&buffer, "(%0s(%0s%0s))",
+                      "foo", "bar", "xxxxxxxxxxxxxxxxx")
+          == strlen(e));
+    
+    ASSERT(sexp_format(NULL, "(%0s(%0s%0s))",
+                      "foo", "bar", "xxxxxxxxxxxxxxxxx")
+          == strlen(e));
+    
+    ASSERT(buffer.size == strlen(e));
+    ASSERT(MEMEQ(buffer.size, buffer.contents, e));
+  }
+  {
+    const uint8_t e[] = "{KDM6Zm9vKDM6YmFyMTc6eHh4eHh4eHh4eHh4eHh4eHgpKQ==}";
+
+    nettle_buffer_init(&buffer);
+    ASSERT(sexp_transport_format(&buffer, "(%0s(%0s%0s))",
+                      "foo", "bar", "xxxxxxxxxxxxxxxxx")
+          == strlen(e));
+    
+    ASSERT(sexp_transport_format(NULL, "(%0s(%0s%0s))",
+                                "foo", "bar", "xxxxxxxxxxxxxxxxx")
+          == strlen(e));
+    
+    ASSERT(buffer.size == strlen(e));
+    ASSERT(MEMEQ(buffer.size, buffer.contents, e));
+  }
+  {
+    const uint8_t e[] = "1:\0""1:a2:bc3:def4:ghij5:\x00\xDE\xAD\xBE\xEF";
+
+    nettle_buffer_init(&buffer);  
+    ASSERT(sexp_format(&buffer, "%i%i%i%i%i%i",
+                      0, 0x61, 0x6263, 0x646566, 0x6768696a, 0xDEADBEEF)
+          == LLENGTH(e));
+    
+    ASSERT(buffer.size == LLENGTH(e));
+    ASSERT(MEMEQ(buffer.size, buffer.contents, e));
+  }
+
+  {
+    const uint8_t e[] = "(3:foo(4:bar))";
+    
+    nettle_buffer_init(&buffer);  
+    ASSERT(sexp_format(&buffer, "(%0s%l)",
+                      "foo", 7, "(4:bar)")
+          == strlen(e));
+    
+    ASSERT(buffer.size == strlen(e));
+    ASSERT(MEMEQ(buffer.size, buffer.contents, e));
+  }
+
+  {
+    const uint8_t e[] = "([1:t]3:foo3:bar[6:gazonk]3:baz1:q)";
+
+    nettle_buffer_init(&buffer);
+    ASSERT(sexp_format(&buffer, "(%0t%0s%0s%0t%0s%0t%0s)",
+                      "t", "foo", "bar", "gazonk", "baz", NULL, "q")
+          == strlen(e));
+
+    ASSERT(MEMEQ(buffer.size, buffer.contents, e));
+  }
+
+  /* Try literals */
+  {
+    const uint8_t e[] = "(3:foo(3:bar17:xxxxxxxxxxxxxxxxx))";
+
+    nettle_buffer_init(&buffer);
+    ASSERT(sexp_format(&buffer, "(%0s(bar%0s))",
+                      "foo", "xxxxxxxxxxxxxxxxx")
+          == strlen(e));
+    
+    ASSERT(sexp_format(NULL, "(%0s(bar %0s))",
+                      "foo", "xxxxxxxxxxxxxxxxx")
+          == strlen(e));
+    
+    ASSERT(buffer.size == strlen(e));
+    ASSERT(MEMEQ(buffer.size, buffer.contents, e));
+  }
+  {
+    const uint8_t e[] = "(3:foo(3:bar17:xxxxxxxxxxxxxxxxx))";
+
+    nettle_buffer_init(&buffer);
+    ASSERT(sexp_format(&buffer, "(%0s(bar xxxxxxxxxxxxxxxxx))",
+                      "foo")
+          == strlen(e));
+    
+    ASSERT(sexp_format(NULL, "(%0s(bar xxxxxxxxxxxxxxxxx))",
+                      "foo")
+          == strlen(e));
+    
+    ASSERT(buffer.size == strlen(e));
+    ASSERT(MEMEQ(buffer.size, buffer.contents, e));
+  }
+
+  /* Literal parenthesis */
+  {
+    const uint8_t e[] = ")3:foo(3:bar";
+
+    nettle_buffer_init(&buffer);
+    ASSERT(sexp_format(&buffer, "%)foo%(%s", 3, "bar")
+          == strlen(e));
+    
+    ASSERT(sexp_format(NULL, "%)foo%(%s", 3, "bar")
+          == strlen(e));
+    
+    ASSERT(buffer.size == strlen(e));
+    ASSERT(MEMEQ(buffer.size, buffer.contents, e));
+  }
+  
+#if HAVE_LIBGMP
+  {
+    mpz_t x;
+    mpz_t y;
+    mpz_t z;
+    
+    const uint8_t e[] =
+      "(3:foo(3:bar1:\xff""11:abcdefghijk13:\0\x81""abcdefghijk))";
+
+    nettle_buffer_clear(&buffer);
+
+    mpz_init_set_si(x, -1);
+    nettle_mpz_init_set_str_256_u(y, 11, "abcdefghijk");
+    nettle_mpz_init_set_str_256_u(z, 12, "\x81""abcdefghijk");
+    nettle_buffer_init(&buffer);
+
+    ASSERT(sexp_format(&buffer, "(%0s(%0s%b%b%b))",
+                    "foo", "bar", x, y, z)
+          == LLENGTH(e));
+
+    ASSERT(sexp_format(NULL, "(%0s(%0s%b%b%b))",
+                    "foo", "bar", x, y, z)
+          == LLENGTH(e));
+    
+    ASSERT(buffer.size == LLENGTH(e));
+    ASSERT(MEMEQ(buffer.size, buffer.contents, e));
+
+    nettle_buffer_clear(&buffer);
+    mpz_clear(x);
+  }
+#endif /* HAVE_LIBGMP */
+
+  SUCCESS();
+}
diff --git a/testsuite/sexp-test.c b/testsuite/sexp-test.c
new file mode 100644 (file)
index 0000000..4e68f56
--- /dev/null
@@ -0,0 +1,99 @@
+#include "testutils.h"
+#include "sexp.h"
+
+int
+test_main(void)
+{
+  struct sexp_iterator i;
+  uint32_t x;
+  
+  ASSERT(sexp_iterator_first(&i, LDATA("")));
+  ASSERT(i.type == SEXP_END);
+
+  ASSERT(sexp_iterator_first(&i, LDATA("()")));
+  ASSERT(i.type == SEXP_LIST
+        && sexp_iterator_enter_list(&i)
+        && i.type == SEXP_END
+        && sexp_iterator_exit_list(&i)
+        && i.type == SEXP_END);
+
+  ASSERT(sexp_iterator_first(&i, LDATA("(")));
+  ASSERT(i.type == SEXP_LIST
+        && !sexp_iterator_enter_list(&i));
+
+  /* Check integers. */
+  ASSERT(sexp_iterator_first(&i, LDATA("1:\0"
+                                      "1:\x11"
+                                      "2:\x00\x11"
+                                      "2:\x00\x80"
+                                      "5:\x00\xaa\xbb\xcc\xdd")));
+  ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0);
+  ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0x11);
+  ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0x11);
+  ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0x80);
+  ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0xaabbccdd);
+  
+  ASSERT(sexp_iterator_first(&i, LDATA("3:foo0:[3:bar]12:xxxxxxxxxxxx")));
+  ASSERT(i.type == SEXP_ATOM
+        && !i.display_length && !i.display
+        && i.atom_length == 3 && MEMEQ(3, "foo", i.atom)
+
+        && sexp_iterator_next(&i) && i.type == SEXP_ATOM
+        && !i.display_length && !i.display
+        && !i.atom_length && i.atom
+
+        && sexp_iterator_next(&i) && i.type == SEXP_ATOM
+        && i.display_length == 3 && MEMEQ(3, "bar", i.display)
+        && i.atom_length == 12 && MEMEQ(12, "xxxxxxxxxxxx", i.atom)
+
+        && sexp_iterator_next(&i) && i.type == SEXP_END);
+  
+  /* Same data, transport encoded. */
+  
+  ASSERT(sexp_transport_iterator_first
+        (&i, LDUP("{Mzpmb28=} {MDo=} {WzM6YmFyXTEyOnh4eHh4eHh4eHh4eA==}")));
+  ASSERT(i.type == SEXP_ATOM
+        && !i.display_length && !i.display
+        && i.atom_length == 3 && MEMEQ(3, "foo", i.atom)
+
+        && sexp_iterator_next(&i) && i.type == SEXP_ATOM
+        && !i.display_length && !i.display
+        && !i.atom_length && i.atom
+
+        && sexp_iterator_next(&i) && i.type == SEXP_ATOM
+        && i.display_length == 3 && MEMEQ(3, "bar", i.display)
+        && i.atom_length == 12 && MEMEQ(12, "xxxxxxxxxxxx", i.atom)
+
+        && sexp_iterator_next(&i) && i.type == SEXP_END);
+  
+  {
+    static const uint8_t *keys[2] = { "n", "e" };
+    struct sexp_iterator v[2];
+    
+    ASSERT(sexp_iterator_first(&i, LDATA("((1:n2:xx3:foo)0:(1:y)(1:e))")));
+    ASSERT(sexp_iterator_enter_list(&i)
+          && sexp_iterator_assoc(&i, 2, keys, v));
+
+    ASSERT(v[0].type == SEXP_ATOM
+          && !v[0].display_length && !v[0].display
+          && v[0].atom_length == 2 && MEMEQ(2, "xx", v[0].atom)
+
+          && sexp_iterator_next(&v[0]) && v[0].type == SEXP_ATOM
+          && !v[0].display_length && !v[0].display
+          && v[0].atom_length == 3 && MEMEQ(3, "foo", v[0].atom)
+
+          && sexp_iterator_next(&v[0]) && v[0].type == SEXP_END);
+
+    ASSERT(v[1].type == SEXP_END);
+
+    ASSERT(sexp_iterator_first(&i, LDATA("((1:n))")));
+    ASSERT(sexp_iterator_enter_list(&i)
+          && !sexp_iterator_assoc(&i, 2, keys, v));
+
+    ASSERT(sexp_iterator_first(&i, LDATA("((1:n)(1:n3:foo))")));
+    ASSERT(sexp_iterator_enter_list(&i)
+          && !sexp_iterator_assoc(&i, 2, keys, v));    
+  }
+
+  SUCCESS();
+}
diff --git a/testsuite/sexp2rsa-test.c b/testsuite/sexp2rsa-test.c
new file mode 100644 (file)
index 0000000..2e7cd91
--- /dev/null
@@ -0,0 +1,46 @@
+#include "testutils.h"
+
+int
+test_main(void)
+{
+  struct rsa_public_key pub;
+  struct rsa_private_key priv;
+  
+  rsa_public_key_init(&pub);
+  rsa_private_key_init(&priv);
+
+  ASSERT(rsa_keypair_from_sexp
+        (&pub, &priv, 0,
+         HL("2831313a707269766174652d6b657928"
+            "333a72736128313a6e36333a085c3408"
+            "989acae4faec3cbbad91c90d34c1d259"
+            "cd74121a36f38b0b51424a9b2be514a0"
+            "4377113a6cdafe79dd7d5f2ecc8b5e96"
+            "61189b86a7b22239907c252928313a65"
+            "343a36ad4b1d2928313a6436333a06ee"
+            "6d4ff3c239e408150daf8117abfa36a4"
+            "0ad4455d9059a86d52f33a2de07418a0"
+            "a699594588c64810248c9412d554f74a"
+            "f947c73c32007e87c92f0937ed292831"
+            "3a7033323a03259879b24315e9cf1425"
+            "4824c7935d807cdb6990f414a0f65e60"
+            "65130a611f2928313a7133323a02a81b"
+            "a73bad45fc73b36deffce52d1b73e074"
+            "7f4d8a82648cecd310448ea63b292831"
+            "3a6133323a026cbdad5dd0046e093f06"
+            "0ecd5b4ac918e098b0278bb752b7cadd"
+            "6a8944f0b92928313a6233323a014875"
+            "1e622d6d58e3bb094afd6edacf737035"
+            "1d068e2ce9f565c5528c4a7473292831"
+            "3a6333323a00f8a458ea73a018dc6fa5"
+            "6863e3bc6de405f364f77dee6f096267"
+            "9ea1a8282e292929")));
+
+  test_rsa_key(&pub, &priv);
+
+  rsa_public_key_clear(&pub);
+  rsa_private_key_clear(&priv);
+  
+  SUCCESS();
+}
+
diff --git a/testsuite/sha1-huge-test.c b/testsuite/sha1-huge-test.c
new file mode 100644 (file)
index 0000000..4f1b4dc
--- /dev/null
@@ -0,0 +1,15 @@
+#include "testutils.h"
+#include "sha.h"
+
+int
+test_main(void)
+{
+  /* Hashes 10 000 000 x 30 000 bytes > 64 * 2^32. This overflows the
+     low word of the block counter. This test vector is not cross
+     checked with any other sha1 implementation. */
+  test_hash_large(&nettle_sha1, 10000000, 30000, 'a',
+                 H("0ba79364dc64648f 2074fb4bc5c28bcf"
+                   "b7a787b0"));
+
+  SUCCESS();
+}
diff --git a/testsuite/sha1-test.c b/testsuite/sha1-test.c
new file mode 100644 (file)
index 0000000..8319086
--- /dev/null
@@ -0,0 +1,67 @@
+#include "testutils.h"
+#include "sha.h"
+
+int
+test_main(void)
+{
+  test_hash(&nettle_sha1, 0, "",
+           H("DA39A3EE5E6B4B0D 3255BFEF95601890 AFD80709")); 
+
+  test_hash(&nettle_sha1, 1, "a",
+           H("86F7E437FAA5A7FC E15D1DDCB9EAEAEA 377667B8")); 
+
+  test_hash(&nettle_sha1, 3, "abc",
+           H("A9993E364706816A BA3E25717850C26C 9CD0D89D"));
+  
+  test_hash(&nettle_sha1, 26, "abcdefghijklmnopqrstuvwxyz",
+           H("32D10C7B8CF96570 CA04CE37F2A19D84 240D3A89"));
+  
+  test_hash(&nettle_sha1, 14, "message digest",
+           H("C12252CEDA8BE899 4D5FA0290A47231C 1D16AAE3")); 
+
+  test_hash(&nettle_sha1, 62,
+           "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+           "abcdefghijklmnopqrstuvwxyz0123456789",
+           H("761C457BF73B14D2 7E9E9265C46F4B4D DA11F940"));
+  
+  test_hash(&nettle_sha1,  80,
+           "1234567890123456789012345678901234567890"
+           "1234567890123456789012345678901234567890",
+           H("50ABF5706A150990 A08B2C5EA40FA0E5 85554732"));
+
+  /* Additional test vector, from Daniel Kahn Gillmor */
+  test_hash(&nettle_sha1, LDATA("38"),
+           H("5b384ce32d8cdef02bc3a139d4cac0a22bb029e8"));
+
+  SUCCESS();
+}
+
+/* These are intermediate values for the single sha1_compress call
+   that results from the first testcase, SHA1(""). Each row is the
+   values for A, B, C, D, E after the i:th round. The row i = -1 gives
+   the initial values, and i = 99 gives the output values.
+
+      i         A        B        C        D        E
+     -1: 67452301 efcdab89 98badcfe 10325476 c3d2e1f0
+      0: 67452301 7bf36ae2 98badcfe 10325476 1fb498b3
+      1: 59d148c0 7bf36ae2 98badcfe 5d43e370 1fb498b3
+     15: 40182905 4544b22e a13017ac ab703832 d8fd6547
+     16: 50060a41 4544b22e a13017ac  6bf9173 d8fd6547
+     17: 50060a41 4544b22e 28a9520e  6bf9173 f63f5951
+     18: 50060a41  b3088dd 28a9520e c1afe45c f63f5951
+     19: e758e8da  b3088dd 8a2a5483 c1afe45c f63f5951
+     20: e758e8da 42cc2237 8a2a5483 c1afe45c 90eb9850
+     21: b9d63a36 42cc2237 8a2a5483 7dbb787d 90eb9850
+     38:  e47bc31 62273351 b201788b 413c1d9a 2aeeae62
+     39: 9bdbdd71 62273351 ec805e22 413c1d9a 2aeeae62
+     40: 9bdbdd71 5889ccd4 ec805e22 413c1d9a 95aa398b
+     41: 66f6f75c 5889ccd4 ec805e22 5e28e858 95aa398b
+     58: 2164303a 982bcbca e1afab22 c5a3382e af9292fa
+     59: 9b9d2913 982bcbca b86beac8 c5a3382e af9292fa
+     60: 9b9d2913 a60af2f2 b86beac8 c5a3382e d37db937
+     61: e6e74a44 a60af2f2 b86beac8 85b9d227 d37db937
+     78: c57a6345 6e9d9f84 666b8bc6 852dc41a ec052519
+     79: 72f480ed 6e9d9f84 999ae2f1 852dc41a ec052519
+     99: da39a3ee 5e6b4b0d 3255bfef 95601890 afd80709
+     
+*/
diff --git a/testsuite/sha224-test.c b/testsuite/sha224-test.c
new file mode 100644 (file)
index 0000000..cef82af
--- /dev/null
@@ -0,0 +1,48 @@
+#include "testutils.h"
+#include "sha.h"
+
+int
+test_main(void)
+{
+  /* From FIPS180-2 addendum
+     (http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf) */
+  test_hash(&nettle_sha224, 3, "abc",
+           H("23097d22 3405d822 8642a477 bda255b3"
+             "2aadbce4 bda0b3f7 e36c9da7"));
+
+  test_hash(&nettle_sha224, 56,
+           "abcdbcdecdefdefgefghfghighij"
+           "hijkijkljklmklmnlmnomnopnopq",
+           H("75388b16 512776cc 5dba5da1 fd890150"
+             "b0c6455c b4f58b19 52522525"));
+
+  /* Additional test vectors, from Daniel Kahn Gillmor */
+  test_hash(&nettle_sha224, LDATA(""),
+           H("d14a028c2a3a2bc9 476102bb288234c4"
+             "15a2b01f828ea62a c5b3e42f"));
+  test_hash(&nettle_sha224, LDATA("a"),
+           H("abd37534c7d9a2ef b9465de931cd7055"
+             "ffdb8879563ae980 78d6d6d5"));
+  test_hash(&nettle_sha224, LDATA("38"),
+           H("4cfca6da32da6471 98225460722b7ea1"
+             "284f98c4b179e8db ae3f93d5"));
+  test_hash(&nettle_sha224, LDATA("message digest"),
+           H("2cb21c83ae2f004d e7e81c3c7019cbcb"
+             "65b71ab656b22d6d 0c39b8eb"));
+  test_hash(&nettle_sha224, LDATA("abcdefghijklmnopqrstuvwxyz"),
+           H("45a5f72c39c5cff2 522eb3429799e49e"
+             "5f44b356ef926bcf 390dccc2"));
+  test_hash(&nettle_sha224,
+           LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
+                 "ghijklmnopqrstuvwxyz0123456789"),
+           H("bff72b4fcb7d75e5 632900ac5f90d219"
+             "e05e97a7bde72e74 0db393d9"));
+  test_hash(&nettle_sha224,
+           LDATA("12345678901234567890123456789012"
+                 "34567890123456789012345678901234"
+                 "5678901234567890"),
+           H("b50aecbe4e9bb0b5 7bc5f3ae760a8e01"
+             "db24f203fb3cdcd1 3148046e"));
+
+  SUCCESS();
+}
diff --git a/testsuite/sha256-test.c b/testsuite/sha256-test.c
new file mode 100644 (file)
index 0000000..7499521
--- /dev/null
@@ -0,0 +1,55 @@
+#include "testutils.h"
+#include "sha.h"
+
+int
+test_main(void)
+{
+  /* From FIPS180-2 */
+  test_hash(&nettle_sha256, 3, "abc",
+           H("ba7816bf8f01cfea 414140de5dae2223"
+             "b00361a396177a9c b410ff61f20015ad"));
+
+  test_hash(&nettle_sha256, 56,
+           "abcdbcdecdefdefgefghfghighij"
+           "hijkijkljklmklmnlmnomnopnopq",
+           H("248d6a61d20638b8 e5c026930c3e6039"
+             "a33ce45964ff2167 f6ecedd419db06c1"));
+
+  test_hash(&nettle_sha256, 112,
+           "abcdefghbcdefghicdefghijdefg"
+           "hijkefghijklfghijklmghijklmn"
+           "hijklmnoijklmnopjklmnopqklmn"
+           "opqrlmnopqrsmnopqrstnopqrstu",
+           H("cf5b16a778af8380 036ce59e7b049237"
+             "0b249b11e8f07a51 afac45037afee9d1"));
+
+  /* Additional test vectors, from Daniel Kahn Gillmor */
+  test_hash(&nettle_sha256, LDATA(""),
+           H("e3b0c44298fc1c14 9afbf4c8996fb924"
+             "27ae41e4649b934c a495991b7852b855"));
+  test_hash(&nettle_sha256, LDATA("a"),
+           H("ca978112ca1bbdca fac231b39a23dc4d"
+             "a786eff8147c4e72 b9807785afee48bb"));
+  test_hash(&nettle_sha256, LDATA("38"),
+           H("aea92132c4cbeb26 3e6ac2bf6c183b5d"
+             "81737f179f21efdc 5863739672f0f470"));
+  test_hash(&nettle_sha256, LDATA("message digest"),
+           H("f7846f55cf23e14e ebeab5b4e1550cad"
+             "5b509e3348fbc4ef a3a1413d393cb650"));
+  test_hash(&nettle_sha256, LDATA("abcdefghijklmnopqrstuvwxyz"),
+           H("71c480df93d6ae2f 1efad1447c66c952"
+             "5e316218cf51fc8d 9ed832f2daf18b73"));
+  test_hash(&nettle_sha256,
+           LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
+                 "ghijklmnopqrstuvwxyz0123456789"),
+           H("db4bfcbd4da0cd85 a60c3c37d3fbd880"
+             "5c77f15fc6b1fdfe 614ee0a7c8fdb4c0"));
+  test_hash(&nettle_sha256,
+           LDATA("12345678901234567890123456789012"
+                 "34567890123456789012345678901234"
+                 "5678901234567890"),
+           H("f371bc4a311f2b00 9eef952dd83ca80e"
+             "2b60026c8e935592 d0f9c308453c813e"));
+
+  SUCCESS();
+}
diff --git a/testsuite/sha384-test.c b/testsuite/sha384-test.c
new file mode 100644 (file)
index 0000000..086e115
--- /dev/null
@@ -0,0 +1,57 @@
+#include "testutils.h"
+#include "sha.h"
+
+int
+test_main(void)
+{
+  test_hash(&nettle_sha384, 3, "abc",
+           H("cb00753f45a35e8b b5a03d699ac65007"
+             "272c32ab0eded163 1a8b605a43ff5bed"
+             "8086072ba1e7cc23 58baeca134c825a7"));
+  
+  test_hash(&nettle_sha384, 112,
+           "abcdefghbcdefghicdefghijdefg"
+           "hijkefghijklfghijklmghijklmn"
+           "hijklmnoijklmnopjklmnopqklmn"
+           "opqrlmnopqrsmnopqrstnopqrstu",
+           H("09330c33f71147e8 3d192fc782cd1b47"
+             "53111b173b3b05d2 2fa08086e3b0f712"
+             "fcc7c71a557e2db9 66c3e9fa91746039"));
+
+  /* Additional test vectors, from Daniel Kahn Gillmor */
+  test_hash(&nettle_sha384, LDATA(""),
+           H("38b060a751ac9638 4cd9327eb1b1e36a"
+             "21fdb71114be0743 4c0cc7bf63f6e1da"
+             "274edebfe76f65fb d51ad2f14898b95b"));
+  test_hash(&nettle_sha384, LDATA("a"),
+           H("54a59b9f22b0b808 80d8427e548b7c23"
+             "abd873486e1f035d ce9cd697e8517503"
+             "3caa88e6d57bc35e fae0b5afd3145f31"));
+  test_hash(&nettle_sha384, LDATA("38"),
+           H("c071d202ad950b6a 04a5f15c24596a99"
+             "3af8b212467958d5 70a3ffd478006063"
+             "8e3a3d06637691d3 012bd31122071b2c"));
+  test_hash(&nettle_sha384, LDATA("message digest"),
+           H("473ed35167ec1f5d 8e550368a3db39be"
+             "54639f828868e945 4c239fc8b52e3c61"
+             "dbd0d8b4de1390c2 56dcbb5d5fd99cd5"));
+  test_hash(&nettle_sha384, LDATA("abcdefghijklmnopqrstuvwxyz"),
+           H("feb67349df3db6f5 924815d6c3dc133f"
+             "091809213731fe5c 7b5f4999e463479f"
+             "f2877f5f2936fa63 bb43784b12f3ebb4"));
+  test_hash(&nettle_sha384,
+           LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
+                 "ghijklmnopqrstuvwxyz0123456789"),
+           H("1761336e3f7cbfe5 1deb137f026f89e0"
+             "1a448e3b1fafa640 39c1464ee8732f11"
+             "a5341a6f41e0c202 294736ed64db1a84"));
+  test_hash(&nettle_sha384,
+           LDATA("12345678901234567890123456789012"
+                 "34567890123456789012345678901234"
+                 "5678901234567890"),
+           H("b12932b0627d1c06 0942f54477641556"
+             "55bd4da0c9afa6dd 9b9ef53129af1b8f"
+             "b0195996d2de9ca0 df9d821ffee67026"));
+
+  SUCCESS();
+}
diff --git a/testsuite/sha512-test.c b/testsuite/sha512-test.c
new file mode 100644 (file)
index 0000000..97bde53
--- /dev/null
@@ -0,0 +1,66 @@
+#include "testutils.h"
+#include "sha.h"
+
+int
+test_main(void)
+{
+  test_hash(&nettle_sha512, 3, "abc",
+           H("ddaf35a193617aba cc417349ae204131"
+             "12e6fa4e89a97ea2 0a9eeee64b55d39a"
+             "2192992a274fc1a8 36ba3c23a3feebbd"
+             "454d4423643ce80e 2a9ac94fa54ca49f"));
+  
+  test_hash(&nettle_sha512, 112,
+           "abcdefghbcdefghicdefghijdefg"
+           "hijkefghijklfghijklmghijklmn"
+           "hijklmnoijklmnopjklmnopqklmn"
+           "opqrlmnopqrsmnopqrstnopqrstu",
+           H("8e959b75dae313da 8cf4f72814fc143f"
+             "8f7779c6eb9f7fa1 7299aeadb6889018"
+             "501d289e4900f7e4 331b99dec4b5433a"
+             "c7d329eeb6dd2654 5e96e55b874be909"));
+
+  /* Additional test vectors, from Daniel Kahn Gillmor */
+  test_hash(&nettle_sha512, LDATA(""),
+           H("cf83e1357eefb8bd f1542850d66d8007"
+             "d620e4050b5715dc 83f4a921d36ce9ce"
+             "47d0d13c5d85f2b0 ff8318d2877eec2f"
+             "63b931bd47417a81 a538327af927da3e"));
+  test_hash(&nettle_sha512, LDATA("a"),
+           H("1f40fc92da241694 750979ee6cf582f2"
+             "d5d7d28e18335de0 5abc54d0560e0f53"
+             "02860c652bf08d56 0252aa5e74210546"
+             "f369fbbbce8c12cf c7957b2652fe9a75"));
+  test_hash(&nettle_sha512, LDATA("38"),
+           H("caae34a5e8103126 8bcdaf6f1d8c04d3"
+             "7b7f2c349afb705b 575966f63e2ebf0f"
+             "d910c3b05160ba08 7ab7af35d40b7c71"
+             "9c53cd8b947c9611 1f64105fd45cc1b2"));
+  test_hash(&nettle_sha512, LDATA("message digest"),
+           H("107dbf389d9e9f71 a3a95f6c055b9251"
+             "bc5268c2be16d6c1 3492ea45b0199f33"
+             "09e16455ab1e9611 8e8a905d5597b720"
+             "38ddb372a8982604 6de66687bb420e7c"));
+  test_hash(&nettle_sha512, LDATA("abcdefghijklmnopqrstuvwxyz"),
+           H("4dbff86cc2ca1bae 1e16468a05cb9881"
+             "c97f1753bce36190 34898faa1aabe429"
+             "955a1bf8ec483d74 21fe3c1646613a59"
+             "ed5441fb0f321389 f77f48a879c7b1f1"));
+  test_hash(&nettle_sha512,
+           LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
+                 "ghijklmnopqrstuvwxyz0123456789"),
+           H("1e07be23c26a86ea 37ea810c8ec78093"
+             "52515a970e9253c2 6f536cfc7a9996c4"
+             "5c8370583e0a78fa 4a90041d71a4ceab"
+             "7423f19c71b9d5a3 e01249f0bebd5894"));
+  test_hash(&nettle_sha512,
+           LDATA("12345678901234567890123456789012"
+                 "34567890123456789012345678901234"
+                 "5678901234567890"),
+           H("72ec1ef1124a45b0 47e8b7c75a932195"
+             "135bb61de24ec0d1 914042246e0aec3a"
+             "2354e093d76f3048 b456764346900cb1"
+             "30d2a4fd5dd16abb 5e30bcb850dee843"));
+
+  SUCCESS();
+}
diff --git a/testsuite/symbols-test b/testsuite/symbols-test
new file mode 100755 (executable)
index 0000000..b487126
--- /dev/null
@@ -0,0 +1,42 @@
+#! /bin/sh
+
+# Check that all exported symbols use the nettle prefix.
+
+if [ -z "$srcdir" ] ; then
+  srcdir=`pwd`
+fi
+
+# FIXME: Check libhogweed.a too.
+
+# * nm on aix seems to generate bogus outbut including random binary
+#   data. Using -g is a workaround to get rid of that. But nm -g
+#   doesn't work on Solaris-2.4, so try nm -g first, and plain nm if
+#   -g isn't recognized.
+#
+# * gcc on x86 generates functions like __i686.get_pc_thunk.bx in pic
+#   code.
+
+( nm -g ../libnettle.a || nm ../libnettle.a ) \
+    | grep ' [DRT] ' | egrep -v '( |^)\.?_?(_?nettle_|memxor)|get_pc_thunk' \
+    | sort -k3 > test1.out
+
+if [ -s test1.out ] ; then
+    echo Exported symbols in libnettle.a, lacking the nettle prefix:
+    cat test1.out
+    exit 1
+fi
+
+if [ -s ../libhogweed.a ] ; then
+    ( nm -g ../libhogweed.a || nm ../libhogweed.a ) \
+       | grep ' [DRT] ' | egrep -v '( |^)\.?_?_?nettle_|get_pc_thunk' \
+       | sort -k3 > test1.out
+
+    if [ -s test1.out ] ; then
+       echo Exported symbols in libhogweed.a, lacking the nettle prefix:
+       cat test1.out
+       exit 1
+    fi
+fi
+
+exit 0
+
diff --git a/testsuite/teardown-env b/testsuite/teardown-env
new file mode 100755 (executable)
index 0000000..2c547ad
--- /dev/null
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+rm -rf testkey.priv testkey.pub testsignature testsignature2
diff --git a/testsuite/testutils.c b/testsuite/testutils.c
new file mode 100644 (file)
index 0000000..d77bb7e
--- /dev/null
@@ -0,0 +1,1075 @@
+/* testutils.c */
+
+#include "testutils.h"
+
+#include "cbc.h"
+#include "ctr.h"
+#include "knuth-lfib.h"
+#include "nettle-internal.h"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* -1 means invalid */
+static const signed char hex_digits[0x100] =
+  {
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+     0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
+    -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+  };
+
+void *
+xalloc(size_t size)
+{
+  void *p = malloc(size);
+  if (size && !p)
+    {
+      fprintf(stderr, "Virtual memory exhausted.\n");
+      abort();
+    }
+
+  return p;
+}
+
+unsigned
+decode_hex_length(const char *h)
+{
+  const unsigned char *hex = (const unsigned char *) h;
+  unsigned count;
+  unsigned i;
+  
+  for (count = i = 0; hex[i]; i++)
+    {
+      if (isspace(hex[i]))
+       continue;
+      if (hex_digits[hex[i]] < 0)
+       abort();
+      count++;
+    }
+
+  if (count % 2)
+    abort();
+  return count / 2;  
+}
+
+int
+decode_hex(uint8_t *dst, const char *h)
+{  
+  const unsigned char *hex = (const unsigned char *) h;
+  unsigned i = 0;
+  
+  for (;;)
+  {
+    int high, low;
+    
+    while (*hex && isspace(*hex))
+      hex++;
+
+    if (!*hex)
+      return 1;
+
+    high = hex_digits[*hex++];
+    if (high < 0)
+      return 0;
+
+    while (*hex && isspace(*hex))
+      hex++;
+
+    if (!*hex)
+      return 0;
+
+    low = hex_digits[*hex++];
+    if (low < 0)
+      return 0;
+
+    dst[i++] = (high << 4) | low;
+  }
+}
+
+const uint8_t *
+decode_hex_dup(const char *hex)
+{
+  uint8_t *p;
+  unsigned length = decode_hex_length(hex);
+
+  p = xalloc(length);
+
+  if (decode_hex(p, hex))
+    return p;
+  else
+    {
+      free(p);
+      return NULL;
+    }
+}
+
+void
+print_hex(unsigned length, const uint8_t *data)
+{
+  unsigned i;
+  
+  for (i = 0; i < length; i++)
+    {
+      switch (i % 16)
+       {
+       default:
+         break;
+       case 0:
+         printf("\n");
+         break;
+       case 8:
+         printf(" ");
+         break;
+       }
+      printf("%02x", data[i]);
+    }
+  printf("\n");
+}
+
+int verbose = 0;
+
+int
+main(int argc, char **argv)
+{
+  if (argc > 1)
+    {
+      if (argc == 2 && !strcmp(argv[1], "-v"))
+       verbose = 1;
+      else
+       {
+         fprintf(stderr, "Invalid argument `%s', only accepted option is `-v'.\n",
+                 argv[1]);
+         return 1;
+       }
+    }
+
+  return test_main();
+}
+
+void
+test_cipher(const struct nettle_cipher *cipher,
+           unsigned key_length,
+           const uint8_t *key,
+           unsigned length,
+           const uint8_t *cleartext,
+           const uint8_t *ciphertext)
+{
+  void *ctx = xalloc(cipher->context_size);
+  uint8_t *data = xalloc(length);
+
+  cipher->set_encrypt_key(ctx, key_length, key);
+  cipher->encrypt(ctx, length, data, cleartext);
+
+  if (!MEMEQ(length, data, ciphertext))
+    {
+      fprintf(stderr, "Encrypt failed:\nInput:");
+      print_hex(length, cleartext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      print_hex(length, ciphertext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+  cipher->set_decrypt_key(ctx, key_length, key);
+  cipher->decrypt(ctx, length, data, data);
+
+  if (!MEMEQ(length, data, cleartext))
+    {
+      fprintf(stderr, "Decrypt failed:\nInput:");
+      print_hex(length, ciphertext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      print_hex(length, cleartext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+
+  free(ctx);
+  free(data);
+}
+
+void
+test_cipher_cbc(const struct nettle_cipher *cipher,
+               unsigned key_length,
+               const uint8_t *key,
+               unsigned length,
+               const uint8_t *cleartext,
+               const uint8_t *ciphertext,
+               const uint8_t *iiv)
+{
+  void *ctx = xalloc(cipher->context_size);
+  uint8_t *data = xalloc(length);
+  uint8_t *iv = xalloc(cipher->block_size);
+  
+  cipher->set_encrypt_key(ctx, key_length, key);
+  memcpy(iv, iiv, cipher->block_size);
+
+  cbc_encrypt(ctx, cipher->encrypt,
+             cipher->block_size, iv,
+             length, data, cleartext);
+
+  if (!MEMEQ(length, data, ciphertext))
+    {
+      fprintf(stderr, "CBC encrypt failed:\nInput:");
+      print_hex(length, cleartext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      print_hex(length, ciphertext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+  cipher->set_decrypt_key(ctx, key_length, key);
+  memcpy(iv, iiv, cipher->block_size);
+
+  cbc_decrypt(ctx, cipher->decrypt,
+             cipher->block_size, iv,
+             length, data, data);
+
+  if (!MEMEQ(length, data, cleartext))
+    {
+      fprintf(stderr, "CBC decrypt failed:\nInput:");
+      print_hex(length, ciphertext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      print_hex(length, cleartext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+  free(ctx);
+  free(data);
+  free(iv);
+}
+
+void
+test_cipher_ctr(const struct nettle_cipher *cipher,
+               unsigned key_length,
+               const uint8_t *key,
+               unsigned length,
+               const uint8_t *cleartext,
+               const uint8_t *ciphertext,
+               const uint8_t *ictr)
+{
+  void *ctx = xalloc(cipher->context_size);
+  uint8_t *data = xalloc(length);
+  uint8_t *ctr = xalloc(cipher->block_size);
+  
+  cipher->set_encrypt_key(ctx, key_length, key);
+  memcpy(ctr, ictr, cipher->block_size);
+
+  ctr_crypt(ctx, cipher->encrypt,
+           cipher->block_size, ctr,
+           length, data, cleartext);
+
+  if (!MEMEQ(length, data, ciphertext))
+    {
+      fprintf(stderr, "CTR encrypt failed:\nInput:");
+      print_hex(length, cleartext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      print_hex(length, ciphertext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+
+  memcpy(ctr, ictr, cipher->block_size);
+
+  ctr_crypt(ctx, cipher->encrypt,
+           cipher->block_size, ctr,
+           length, data, data);
+
+  if (!MEMEQ(length, data, cleartext))
+    {
+      fprintf(stderr, "CTR decrypt failed:\nInput:");
+      print_hex(length, ciphertext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      print_hex(length, cleartext);
+      fprintf(stderr, "\n");
+      FAIL();
+    }
+
+  free(ctx);
+  free(data);
+  free(ctr);
+}
+
+void
+test_cipher_stream(const struct nettle_cipher *cipher,
+                  unsigned key_length,
+                  const uint8_t *key,
+                  unsigned length,
+                  const uint8_t *cleartext,
+                  const uint8_t *ciphertext)
+{
+  unsigned block;
+  
+  void *ctx = xalloc(cipher->context_size);
+  uint8_t *data = xalloc(length + 1);
+  
+  for (block = 1; block <= length; block++)
+    {
+      unsigned i;
+
+      memset(data, 0x17, length + 1);
+      cipher->set_encrypt_key(ctx, key_length, key);
+
+      for (i = 0; i + block < length; i += block)
+       {
+         cipher->encrypt(ctx, block, data + i, cleartext + i);
+         if (data[i + block] != 0x17)
+           FAIL();
+       }
+
+      cipher->encrypt(ctx, length - i, data + i, cleartext + i);
+      if (data[length] != 0x17)
+       FAIL();
+      
+      if (!MEMEQ(length, data, ciphertext))
+       {
+         fprintf(stderr, "Encrypt failed, block size %d\nInput:", block);
+         print_hex(length, cleartext);
+         fprintf(stderr, "\nOutput: ");
+         print_hex(length, data);
+         fprintf(stderr, "\nExpected:");
+         print_hex(length, ciphertext);
+         fprintf(stderr, "\n");
+         FAIL();           
+       }
+    }
+  
+  cipher->set_decrypt_key(ctx, key_length, key);
+  cipher->decrypt(ctx, length, data, data);
+
+  if (data[length] != 0x17)
+    FAIL();
+
+  if (!MEMEQ(length, data, cleartext))
+    {
+      fprintf(stderr, "Decrypt failed\nInput:");
+      print_hex(length, ciphertext);
+      fprintf(stderr, "\nOutput: ");
+      print_hex(length, data);
+      fprintf(stderr, "\nExpected:");
+      print_hex(length, cleartext);
+      fprintf(stderr, "\n");
+      FAIL();      
+    }
+
+  free(ctx);
+  free(data);
+}
+
+void
+test_aead(const struct nettle_aead *aead,
+         unsigned key_length,
+         const uint8_t *key,
+         unsigned auth_length,
+         const uint8_t *authtext,
+         unsigned length,
+         const uint8_t *cleartext,
+         const uint8_t *ciphertext,
+         unsigned iv_length,
+         const uint8_t *iv,
+         const uint8_t *digest)
+{
+  void *ctx = xalloc(aead->context_size);
+  uint8_t *data = xalloc(length);
+  uint8_t *buffer = xalloc(aead->block_size);
+
+  /* encryption */
+  memset(buffer, 0, aead->block_size);
+  aead->set_key(ctx, key_length, key);
+
+  aead->set_iv(ctx, iv_length, iv);
+
+  if (auth_length)
+    aead->update(ctx, auth_length, authtext);
+    
+  if (length)
+    aead->encrypt(ctx, length, data, cleartext);
+
+  aead->digest(ctx, aead->block_size, buffer);
+
+  if (!MEMEQ(length, data, ciphertext))
+    FAIL();
+
+  if (!MEMEQ(aead->block_size, buffer, digest))
+    FAIL();
+
+  /* decryption */
+  memset(buffer, 0, aead->block_size);
+  aead->set_iv(ctx, iv_length, iv);
+
+  if (auth_length)
+    aead->update(ctx, auth_length, authtext);
+    
+  if (length)
+    aead->decrypt(ctx, length, data, data);
+
+  aead->digest(ctx, aead->block_size, buffer);
+
+  if (!MEMEQ(length, data, cleartext))
+    FAIL();
+
+  if (!MEMEQ(aead->block_size, buffer, digest))
+    FAIL();
+
+  free(ctx);
+  free(data);
+  free(buffer);
+}
+
+void
+test_hash(const struct nettle_hash *hash,
+         unsigned length,
+         const uint8_t *data,
+         const uint8_t *digest)
+{
+  void *ctx = xalloc(hash->context_size);
+  uint8_t *buffer = xalloc(hash->digest_size);
+
+  hash->init(ctx);
+  hash->update(ctx, length, data);
+  hash->digest(ctx, hash->digest_size, buffer);
+
+  if (!MEMEQ(hash->digest_size, digest, buffer))
+    FAIL();
+
+  memset(buffer, 0, hash->digest_size);
+
+  hash->init(ctx);
+  hash->update(ctx, length, data);
+  hash->digest(ctx, hash->digest_size - 1, buffer);
+
+  if (!MEMEQ(hash->digest_size - 1, digest, buffer))
+    FAIL();
+
+  if (buffer[hash->digest_size - 1])
+    FAIL();
+
+  free(ctx);
+  free(buffer);
+}
+
+void
+test_hash_large(const struct nettle_hash *hash,
+               unsigned count, unsigned length,
+               uint8_t c,
+               const uint8_t *digest)
+{
+  void *ctx = xalloc(hash->context_size);
+  uint8_t *buffer = xalloc(hash->digest_size);
+  uint8_t *data = xalloc(length);
+  unsigned i;
+
+  memset(data, c, length);
+
+  hash->init(ctx);
+  for (i = 0; i < count; i++)
+    hash->update(ctx, length, data);
+  hash->digest(ctx, hash->digest_size, buffer);
+
+  print_hex(hash->digest_size, buffer);
+
+  if (!MEMEQ(hash->digest_size, digest, buffer))
+    FAIL();
+
+  free(ctx);
+  free(buffer);
+  free(data);
+}
+
+void
+test_mac(const struct nettle_mac *mac,
+        unsigned key_length, const uint8_t *key,
+        unsigned msg_length, const uint8_t *msg,
+        const uint8_t *digest)
+{
+  void *ctx = xalloc(mac->context_size);
+  uint8_t *buffer = xalloc(mac->digest_size);
+
+  mac->set_key(ctx, key_length, key);
+  mac->update(ctx, msg_length, msg);
+  mac->digest(ctx, mac->digest_size, buffer);
+  ASSERT(MEMEQ(mac->digest_size, digest, buffer));
+
+  free(ctx);
+  free(buffer);
+}
+
+void
+test_armor(const struct nettle_armor *armor,
+           unsigned data_length,
+           const uint8_t *data,
+           const uint8_t *ascii)
+{
+  unsigned ascii_length = strlen(ascii);
+  uint8_t *buffer = xalloc(1 + ascii_length);
+  uint8_t *check = xalloc(1 + armor->decode_length(ascii_length));
+  void *encode = xalloc(armor->encode_context_size);
+  void *decode = xalloc(armor->decode_context_size);
+  unsigned done;
+
+  ASSERT(ascii_length
+        <= (armor->encode_length(data_length) + armor->encode_final_length));
+  ASSERT(data_length <= armor->decode_length(ascii_length));
+  
+  memset(buffer, 0x33, 1 + ascii_length);
+  memset(check, 0x55, 1 + data_length);
+
+  armor->encode_init(encode);
+  
+  done = armor->encode_update(encode, buffer, data_length, data);
+  done += armor->encode_final(encode, buffer + done);
+  ASSERT(done == ascii_length);
+
+  if (!MEMEQ(ascii_length, buffer, ascii))
+    FAIL();
+
+  if (0x33 != buffer[strlen(ascii)])
+    FAIL();  
+
+  armor->decode_init(decode);
+  done = armor->decode_length(ascii_length);
+
+  ASSERT(armor->decode_update(decode, &done, check, ascii_length, buffer));
+  ASSERT(done == data_length);
+  ASSERT(armor->decode_final(decode));
+  
+  if (!MEMEQ(data_length, check, data))
+    FAIL();
+
+  if (0x55 != check[data_length])
+    FAIL();
+
+  free(buffer);
+  free(check);
+  free(encode);
+  free(decode);
+}
+
+#if HAVE_LIBGMP
+/* Missing in current gmp */
+static void
+mpz_togglebit (mpz_t x, unsigned long int bit)
+{
+  if (mpz_tstbit(x, bit))
+    mpz_clrbit(x, bit);
+  else
+    mpz_setbit(x, bit);
+}
+#endif /* HAVE_LIBGMP */
+
+#if WITH_HOGWEED
+#define SIGN(key, hash, msg, signature) do {           \
+  hash##_update(&hash, LDATA(msg));                    \
+  ASSERT(rsa_##hash##_sign(key, &hash, signature));    \
+} while(0)
+
+#define VERIFY(key, hash, msg, signature) (    \
+  hash##_update(&hash, LDATA(msg)),            \
+  rsa_##hash##_verify(key, &hash, signature)   \
+)
+
+void
+test_rsa_set_key_1(struct rsa_public_key *pub,
+                  struct rsa_private_key *key)
+{
+  /* Initialize key pair for test programs */
+  /* 1000-bit key, generated by
+   *
+   *   lsh-keygen -a rsa -l 1000 -f advanced-hex
+   *
+   * (private-key (rsa-pkcs1 
+   *        (n #69abd505285af665 36ddc7c8f027e6f0 ed435d6748b16088
+   *            4fd60842b3a8d7fb bd8a3c98f0cc50ae 4f6a9f7dd73122cc
+   *            ec8afa3f77134406 f53721973115fc2d 8cfbba23b145f28d
+   *            84f81d3b6ae8ce1e 2850580c026e809b cfbb52566ea3a3b3
+   *            df7edf52971872a7 e35c1451b8636d22 279a8fb299368238
+   *            e545fbb4cf#)
+   *        (e #0db2ad57#)
+   *        (d #3240a56f4cd0dcc2 4a413eb4ea545259 5c83d771a1c2ba7b
+   *            ec47c5b43eb4b374 09bd2aa1e236dd86 481eb1768811412f
+   *            f8d91be3545912af b55c014cb55ceac6 54216af3b85d5c4f
+   *            4a32894e3b5dfcde 5b2875aa4dc8d9a8 6afd0ca92ef50d35
+   *            bd09f1c47efb4c8d c631e07698d362aa 4a83fd304e66d6c5
+   *            468863c307#)
+   *        (p #0a66399919be4b4d e5a78c5ea5c85bf9 aba8c013cb4a8732
+   *            14557a12bd67711e bb4073fd39ad9a86 f4e80253ad809e5b
+   *            f2fad3bc37f6f013 273c9552c9f489#)
+   *        (q #0a294f069f118625 f5eae2538db9338c 776a298eae953329
+   *            9fd1eed4eba04e82 b2593bc98ba8db27 de034da7daaea795
+   *            2d55b07b5f9a5875 d1ca5f6dcab897#)
+   *        (a #011b6c48eb592eee e85d1bb35cfb6e07 344ea0b5e5f03a28
+   *            5b405396cbc78c5c 868e961db160ba8d 4b984250930cf79a
+   *            1bf8a9f28963de53 128aa7d690eb87#)
+   *        (b #0409ecf3d2557c88 214f1af5e1f17853 d8b2d63782fa5628
+   *            60cf579b0833b7ff 5c0529f2a97c6452 2fa1a8878a9635ab
+   *            ce56debf431bdec2 70b308fa5bf387#)
+   *        (c #04e103ee925cb5e6 6653949fa5e1a462 c9e65e1adcd60058
+   *            e2df9607cee95fa8 daec7a389a7d9afc 8dd21fef9d83805a
+   *            40d46f49676a2f6b 2926f70c572c00#)))
+   */
+  
+  mpz_set_str(pub->n,
+             "69abd505285af665" "36ddc7c8f027e6f0" "ed435d6748b16088"
+             "4fd60842b3a8d7fb" "bd8a3c98f0cc50ae" "4f6a9f7dd73122cc"
+             "ec8afa3f77134406" "f53721973115fc2d" "8cfbba23b145f28d"
+             "84f81d3b6ae8ce1e" "2850580c026e809b" "cfbb52566ea3a3b3"
+             "df7edf52971872a7" "e35c1451b8636d22" "279a8fb299368238"
+             "e545fbb4cf", 16);
+  mpz_set_str(pub->e, "0db2ad57", 16);
+
+  if (!rsa_public_key_prepare(pub))
+    FAIL();
+  
+  /* d is not used */
+#if 0  
+  mpz_set_str(key->d,
+             "3240a56f4cd0dcc2" "4a413eb4ea545259" "5c83d771a1c2ba7b"
+             "ec47c5b43eb4b374" "09bd2aa1e236dd86" "481eb1768811412f"
+             "f8d91be3545912af" "b55c014cb55ceac6" "54216af3b85d5c4f"
+             "4a32894e3b5dfcde" "5b2875aa4dc8d9a8" "6afd0ca92ef50d35"
+             "bd09f1c47efb4c8d" "c631e07698d362aa" "4a83fd304e66d6c5"
+             "468863c307", 16);
+#endif
+  
+  mpz_set_str(key->p,
+             "0a66399919be4b4d" "e5a78c5ea5c85bf9" "aba8c013cb4a8732"
+             "14557a12bd67711e" "bb4073fd39ad9a86" "f4e80253ad809e5b"
+             "f2fad3bc37f6f013" "273c9552c9f489", 16);
+
+  mpz_set_str(key->q,
+             "0a294f069f118625" "f5eae2538db9338c" "776a298eae953329"
+             "9fd1eed4eba04e82" "b2593bc98ba8db27" "de034da7daaea795"
+             "2d55b07b5f9a5875" "d1ca5f6dcab897", 16);
+  
+  mpz_set_str(key->a,
+             "011b6c48eb592eee" "e85d1bb35cfb6e07" "344ea0b5e5f03a28"
+             "5b405396cbc78c5c" "868e961db160ba8d" "4b984250930cf79a"
+             "1bf8a9f28963de53" "128aa7d690eb87", 16);
+  
+  mpz_set_str(key->b,
+             "0409ecf3d2557c88" "214f1af5e1f17853" "d8b2d63782fa5628"
+             "60cf579b0833b7ff" "5c0529f2a97c6452" "2fa1a8878a9635ab"
+             "ce56debf431bdec2" "70b308fa5bf387", 16);
+  
+  mpz_set_str(key->c,
+             "04e103ee925cb5e6" "6653949fa5e1a462" "c9e65e1adcd60058"
+             "e2df9607cee95fa8" "daec7a389a7d9afc" "8dd21fef9d83805a"
+             "40d46f49676a2f6b" "2926f70c572c00", 16);
+
+  if (!rsa_private_key_prepare(key))
+    FAIL();
+
+  if (pub->size != key->size)
+    FAIL();
+}
+
+void
+test_rsa_md5(struct rsa_public_key *pub,
+            struct rsa_private_key *key,
+            mpz_t expected)
+{
+  struct md5_ctx md5;
+  mpz_t signature;
+
+  md5_init(&md5);
+  mpz_init(signature);
+  
+  SIGN(key, md5, "The magic words are squeamish ossifrage", signature);
+
+  if (verbose)
+    {
+      fprintf(stderr, "rsa-md5 signature: ");
+      mpz_out_str(stderr, 16, signature);
+      fprintf(stderr, "\n");
+    }
+
+  if (mpz_cmp(signature, expected))
+    FAIL();
+  
+  /* Try bad data */
+  if (VERIFY(pub, md5,
+            "The magick words are squeamish ossifrage", signature))
+    FAIL();
+
+  /* Try correct data */
+  if (!VERIFY(pub, md5,
+             "The magic words are squeamish ossifrage", signature))
+    FAIL();
+
+  /* Try bad signature */
+  mpz_togglebit(signature, 17);
+
+  if (VERIFY(pub, md5,
+            "The magic words are squeamish ossifrage", signature))
+    FAIL();
+
+  mpz_clear(signature);
+}
+
+void
+test_rsa_sha1(struct rsa_public_key *pub,
+             struct rsa_private_key *key,
+             mpz_t expected)
+{
+  struct sha1_ctx sha1;
+  mpz_t signature;
+
+  sha1_init(&sha1);
+  mpz_init(signature);
+
+  SIGN(key, sha1, "The magic words are squeamish ossifrage", signature);
+
+  if (verbose)
+    {
+      fprintf(stderr, "rsa-sha1 signature: ");
+      mpz_out_str(stderr, 16, signature);
+      fprintf(stderr, "\n");
+    }
+
+  if (mpz_cmp(signature, expected))
+    FAIL();
+  
+  /* Try bad data */
+  if (VERIFY(pub, sha1,
+            "The magick words are squeamish ossifrage", signature))
+    FAIL();
+
+  /* Try correct data */
+  if (!VERIFY(pub, sha1,
+             "The magic words are squeamish ossifrage", signature))
+    FAIL();
+
+  /* Try bad signature */
+  mpz_togglebit(signature, 17);
+
+  if (VERIFY(pub, sha1,
+            "The magic words are squeamish ossifrage", signature))
+    FAIL();
+
+  mpz_clear(signature);
+}
+
+void
+test_rsa_sha256(struct rsa_public_key *pub,
+               struct rsa_private_key *key,
+               mpz_t expected)
+{
+  struct sha256_ctx sha256;
+  mpz_t signature;
+
+  sha256_init(&sha256);
+  mpz_init(signature);
+
+  SIGN(key, sha256, "The magic words are squeamish ossifrage", signature);
+
+  if (verbose)
+    {
+      fprintf(stderr, "rsa-sha256 signature: ");
+      mpz_out_str(stderr, 16, signature);
+      fprintf(stderr, "\n");
+    }
+
+  if (mpz_cmp(signature, expected))
+    FAIL();
+  
+  /* Try bad data */
+  if (VERIFY(pub, sha256,
+            "The magick words are squeamish ossifrage", signature))
+    FAIL();
+
+  /* Try correct data */
+  if (!VERIFY(pub, sha256,
+             "The magic words are squeamish ossifrage", signature))
+    FAIL();
+
+  /* Try bad signature */
+  mpz_togglebit(signature, 17);
+
+  if (VERIFY(pub, sha256,
+            "The magic words are squeamish ossifrage", signature))
+    FAIL();
+
+  mpz_clear(signature);
+}
+
+void
+test_rsa_sha512(struct rsa_public_key *pub,
+               struct rsa_private_key *key,
+               mpz_t expected)
+{
+  struct sha512_ctx sha512;
+  mpz_t signature;
+
+  sha512_init(&sha512);
+  mpz_init(signature);
+
+  SIGN(key, sha512, "The magic words are squeamish ossifrage", signature);
+
+  if (verbose)
+    {
+      fprintf(stderr, "rsa-sha512 signature: ");
+      mpz_out_str(stderr, 16, signature);
+      fprintf(stderr, "\n");
+    }
+
+  if (mpz_cmp(signature, expected))
+    FAIL();
+  
+  /* Try bad data */
+  if (VERIFY(pub, sha512,
+            "The magick words are squeamish ossifrage", signature))
+    FAIL();
+
+  /* Try correct data */
+  if (!VERIFY(pub, sha512,
+             "The magic words are squeamish ossifrage", signature))
+    FAIL();
+
+  /* Try bad signature */
+  mpz_togglebit(signature, 17);
+
+  if (VERIFY(pub, sha512,
+            "The magic words are squeamish ossifrage", signature))
+    FAIL();
+
+  mpz_clear(signature);
+}
+
+#undef SIGN
+#undef VERIFY
+
+void
+test_rsa_key(struct rsa_public_key *pub,
+            struct rsa_private_key *key)
+{
+  mpz_t tmp;
+  mpz_t phi;
+  
+  mpz_init(tmp); mpz_init(phi);
+  
+  if (verbose)
+    {
+      /* FIXME: Use gmp_printf */
+      fprintf(stderr, "Public key: n=");
+      mpz_out_str(stderr, 16, pub->n);
+      fprintf(stderr, "\n    e=");
+      mpz_out_str(stderr, 16, pub->e);
+
+      fprintf(stderr, "\n\nPrivate key: d=");
+      mpz_out_str(stderr, 16, key->d);
+      fprintf(stderr, "\n    p=");
+      mpz_out_str(stderr, 16, key->p);
+      fprintf(stderr, "\n    q=");
+      mpz_out_str(stderr, 16, key->q);
+      fprintf(stderr, "\n    a=");
+      mpz_out_str(stderr, 16, key->a);
+      fprintf(stderr, "\n    b=");
+      mpz_out_str(stderr, 16, key->b);
+      fprintf(stderr, "\n    c=");
+      mpz_out_str(stderr, 16, key->c);
+      fprintf(stderr, "\n\n");
+    }
+
+  /* Check n = p q */
+  mpz_mul(tmp, key->p, key->q);
+  if (mpz_cmp(tmp, pub->n))
+    FAIL();
+
+  /* Check c q = 1 mod p */
+  mpz_mul(tmp, key->c, key->q);
+  mpz_fdiv_r(tmp, tmp, key->p);
+  if (mpz_cmp_ui(tmp, 1))
+    FAIL();
+
+  /* Check ed = 1 (mod phi) */
+  mpz_sub_ui(phi, key->p, 1);
+  mpz_sub_ui(tmp, key->q, 1);
+
+  mpz_mul(phi, phi, tmp);
+
+  mpz_mul(tmp, pub->e, key->d);
+  mpz_fdiv_r(tmp, tmp, phi);
+  if (mpz_cmp_ui(tmp, 1))
+    FAIL();
+
+  /* Check a e = 1 (mod (p-1) ) */
+  mpz_sub_ui(phi, key->p, 1);
+  mpz_mul(tmp, pub->e, key->a);
+  mpz_fdiv_r(tmp, tmp, phi);
+  if (mpz_cmp_ui(tmp, 1))
+    FAIL();
+  
+  /* Check b e = 1 (mod (q-1) ) */
+  mpz_sub_ui(phi, key->q, 1);
+  mpz_mul(tmp, pub->e, key->b);
+  mpz_fdiv_r(tmp, tmp, phi);
+  if (mpz_cmp_ui(tmp, 1))
+    FAIL();
+  
+  mpz_clear(tmp); mpz_clear(phi);
+}
+
+/* Requires that the context is named like the hash algorithm. */
+#define DSA_VERIFY(key, hash, msg, signature)  \
+  (hash##_update(&hash, LDATA(msg)),           \
+   dsa_##hash##_verify(key, &hash, signature))
+
+void
+test_dsa160(const struct dsa_public_key *pub,
+           const struct dsa_private_key *key,
+           const struct dsa_signature *expected)
+{
+  struct sha1_ctx sha1;
+  struct dsa_signature signature;
+  struct knuth_lfib_ctx lfib;
+  
+  sha1_init(&sha1);
+  dsa_signature_init(&signature);
+  knuth_lfib_init(&lfib, 1111);
+  
+  sha1_update(&sha1, LDATA("The magic words are squeamish ossifrage"));
+  ASSERT (dsa_sha1_sign(pub, key,
+                       &lfib, (nettle_random_func *) knuth_lfib_random,
+                       &sha1, &signature));
+
+  if (verbose)
+    {
+      fprintf(stderr, "dsa160 signature: ");
+      mpz_out_str(stderr, 16, signature.r);
+      fprintf(stderr, ", ");
+      mpz_out_str(stderr, 16, signature.s);
+      fprintf(stderr, "\n");
+    }
+
+  if (expected)
+    if (mpz_cmp (signature.r, expected->r)
+       || mpz_cmp (signature.s, expected->s))
+      FAIL();
+  
+  /* Try bad data */
+  if (DSA_VERIFY(pub, sha1,
+                "The magick words are squeamish ossifrage", &signature))
+    FAIL();
+
+  /* Try correct data */
+  if (!DSA_VERIFY(pub, sha1,
+                "The magic words are squeamish ossifrage", &signature))
+    FAIL();
+
+  /* Try bad signature */
+  mpz_togglebit(signature.r, 17);
+
+  if (DSA_VERIFY(pub, sha1,
+                "The magic words are squeamish ossifrage", &signature))
+    FAIL();
+
+  dsa_signature_clear(&signature);
+}
+
+void
+test_dsa256(const struct dsa_public_key *pub,
+           const struct dsa_private_key *key,
+           const struct dsa_signature *expected)
+{
+  struct sha256_ctx sha256;
+  struct dsa_signature signature;
+  struct knuth_lfib_ctx lfib;
+  
+  sha256_init(&sha256);
+  dsa_signature_init(&signature);
+  knuth_lfib_init(&lfib, 1111);
+  
+  sha256_update(&sha256, LDATA("The magic words are squeamish ossifrage"));
+  ASSERT (dsa_sha256_sign(pub, key,
+                       &lfib, (nettle_random_func *) knuth_lfib_random,
+                       &sha256, &signature));
+  
+  if (verbose)
+    {
+      fprintf(stderr, "dsa256 signature: ");
+      mpz_out_str(stderr, 16, signature.r);
+      fprintf(stderr, ", ");
+      mpz_out_str(stderr, 16, signature.s);
+      fprintf(stderr, "\n");
+    }
+
+  if (expected)
+    if (mpz_cmp (signature.r, expected->r)
+       || mpz_cmp (signature.s, expected->s))
+      FAIL();
+  
+  /* Try bad data */
+  if (DSA_VERIFY(pub, sha256,
+                "The magick words are squeamish ossifrage", &signature))
+    FAIL();
+
+  /* Try correct data */
+  if (!DSA_VERIFY(pub, sha256,
+                "The magic words are squeamish ossifrage", &signature))
+    FAIL();
+
+  /* Try bad signature */
+  mpz_togglebit(signature.r, 17);
+
+  if (DSA_VERIFY(pub, sha256,
+                "The magic words are squeamish ossifrage", &signature))
+    FAIL();
+
+  dsa_signature_clear(&signature);
+}
+
+void
+test_dsa_key(struct dsa_public_key *pub,
+            struct dsa_private_key *key,
+            unsigned q_size)
+{
+  mpz_t t;
+
+  mpz_init(t);
+
+  ASSERT(mpz_sizeinbase(pub->q, 2) == q_size);
+  ASSERT(mpz_sizeinbase(pub->p, 2) >= DSA_SHA1_MIN_P_BITS);
+  
+  ASSERT(mpz_probab_prime_p(pub->p, 10));
+
+  ASSERT(mpz_probab_prime_p(pub->q, 10));
+
+  mpz_fdiv_r(t, pub->p, pub->q);
+
+  ASSERT(0 == mpz_cmp_ui(t, 1));
+
+  ASSERT(mpz_cmp_ui(pub->g, 1) > 0);
+  
+  mpz_powm(t, pub->g, pub->q, pub->p);
+  ASSERT(0 == mpz_cmp_ui(t, 1));
+  
+  mpz_powm(t, pub->g, key->x, pub->p);
+  ASSERT(0 == mpz_cmp(t, pub->y));
+};
+
+#endif /* WITH_HOGWEED */
+
diff --git a/testsuite/testutils.h b/testsuite/testutils.h
new file mode 100644 (file)
index 0000000..265cc49
--- /dev/null
@@ -0,0 +1,226 @@
+#ifndef NETTLE_TESTUTILS_H_INCLUDED
+#define NETTLE_TESTUTILS_H_INCLUDED
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-types.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#if HAVE_LIBGMP
+# include "bignum.h"
+#endif
+
+#if WITH_HOGWEED
+# include "rsa.h"
+# include "dsa.h"
+#endif
+
+#include "nettle-meta.h"
+
+/* Forward declare */
+struct nettle_aead;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *
+xalloc(size_t size);
+
+/* Decodes a NUL-terminated hex string. */
+
+unsigned
+decode_hex_length(const char *hex);
+
+int
+decode_hex(uint8_t *dst, const char *hex);
+
+/* Allocates space */
+const uint8_t *
+decode_hex_dup(const char *hex);
+
+void
+print_hex(unsigned length, const uint8_t *data);
+
+/* The main program */
+int
+test_main(void);
+
+extern int verbose;
+
+/* FIXME: When interface stabilizes, move to nettle-meta.h */
+struct nettle_mac
+{
+  const char *name;
+
+  /* Size of the context struct */
+  unsigned context_size;
+
+  /* Size of digests */
+  unsigned digest_size;
+
+  /* Suggested key size; other sizes are sometimes possible. */
+  unsigned key_size;
+  
+  nettle_set_key_func *set_key;
+  nettle_hash_update_func *update;
+  nettle_hash_digest_func *digest;
+};
+
+#define _NETTLE_HMAC(name, NAME, keysize) {    \
+  #name,                                       \
+  sizeof(struct hmac_##name##_ctx),            \
+  NAME##_DIGEST_SIZE,                          \
+  NAME##_DIGEST_SIZE,                          \
+  hmac_##name##_set_key,                       \
+  hmac_##name##_update,                                \
+  hmac_##name##_digest,                                \
+}
+void
+test_cipher(const struct nettle_cipher *cipher,
+           unsigned key_length,
+           const uint8_t *key,
+           unsigned length,
+           const uint8_t *cleartext,
+           const uint8_t *ciphertext);
+
+void
+test_cipher_cbc(const struct nettle_cipher *cipher,
+               unsigned key_length,
+               const uint8_t *key,
+               unsigned length,
+               const uint8_t *cleartext,
+               const uint8_t *ciphertext,
+               const uint8_t *iv);
+
+void
+test_cipher_ctr(const struct nettle_cipher *cipher,
+               unsigned key_length,
+               const uint8_t *key,
+               unsigned length,
+               const uint8_t *cleartext,
+               const uint8_t *ciphertext,
+               const uint8_t *iv);
+
+void
+test_cipher_stream(const struct nettle_cipher *cipher,
+                  unsigned key_length,
+                  const uint8_t *key,
+                  unsigned length,
+                  const uint8_t *cleartext,
+                  const uint8_t *ciphertext);
+
+void
+test_aead(const struct nettle_aead *aead,
+         unsigned key_length,
+         const uint8_t *key,
+         unsigned auth_length,
+         const uint8_t *authtext,
+         unsigned length,
+         const uint8_t *cleartext,
+         const uint8_t *ciphertext,
+         unsigned iv_length,
+         const uint8_t *iv,
+         const uint8_t *digest);
+
+void
+test_hash(const struct nettle_hash *hash,
+         unsigned length,
+         const uint8_t *data,
+         const uint8_t *digest);
+
+void
+test_hash_large(const struct nettle_hash *hash,
+               unsigned count, unsigned length,
+               uint8_t c,
+               const uint8_t *digest);
+
+void
+test_mac(const struct nettle_mac *mac,
+        unsigned key_length, const uint8_t *key,
+        unsigned msg_length, const uint8_t *msg,
+        const uint8_t *digest);
+
+void
+test_armor(const struct nettle_armor *armor,
+           unsigned data_length,
+           const uint8_t *data,
+           const uint8_t *ascii);
+
+#if WITH_HOGWEED
+void
+test_rsa_set_key_1(struct rsa_public_key *pub,
+                  struct rsa_private_key *key);
+
+void
+test_rsa_md5(struct rsa_public_key *pub,
+            struct rsa_private_key *key,
+            mpz_t expected);
+
+void
+test_rsa_sha1(struct rsa_public_key *pub,
+             struct rsa_private_key *key,
+             mpz_t expected);
+
+void
+test_rsa_sha256(struct rsa_public_key *pub,
+               struct rsa_private_key *key,
+               mpz_t expected);
+
+void
+test_rsa_sha512(struct rsa_public_key *pub,
+               struct rsa_private_key *key,
+               mpz_t expected);
+
+void
+test_rsa_key(struct rsa_public_key *pub,
+            struct rsa_private_key *key);
+
+void
+test_dsa160(const struct dsa_public_key *pub,
+           const struct dsa_private_key *key,
+           const struct dsa_signature *expected);
+
+void
+test_dsa256(const struct dsa_public_key *pub,
+           const struct dsa_private_key *key,
+           const struct dsa_signature *expected);
+
+void
+test_dsa_key(struct dsa_public_key *pub,
+            struct dsa_private_key *key,
+            unsigned q_size);
+
+#endif /* WITH_HOGWEED */
+
+#ifdef __cplusplus
+}
+#endif
+
+#define H2(d, s) decode_hex((d), (s))
+#define H(x) decode_hex_dup(x)
+#define HL(x) decode_hex_length(x), decode_hex_dup(x)
+
+/* LDATA needs to handle NUL characters. */
+#define LLENGTH(x) (sizeof(x) - 1)
+#define LDATA(x) (sizeof(x) - 1), x
+#define LDUP(x) strlen(x), strdup(x)
+
+#define MEMEQ(length, a, b) (!memcmp((a), (b), (length)))
+#define MEMEQH(length, a, b) \
+((length) == decode_hex_length((b)) \
+ && !memcmp((a), decode_hex_dup((b)), (length)))
+
+#define FAIL() abort()
+#define SKIP() exit(77)
+#define SUCCESS() return EXIT_SUCCESS
+
+#define ASSERT(x) do { if (!(x)) FAIL(); } while(0)
+
+#endif /* NETTLE_TESTUTILS_H_INCLUDED */
diff --git a/testsuite/twofish-test.c b/testsuite/twofish-test.c
new file mode 100644 (file)
index 0000000..65558d3
--- /dev/null
@@ -0,0 +1,28 @@
+#include "testutils.h"
+#include "twofish.h"
+
+int
+test_main(void)
+{
+  /* 128 bit key */
+  test_cipher(&nettle_twofish128,
+             HL("0000000000000000 0000000000000000"),
+             HL("0000000000000000 0000000000000000"),
+             H("9F589F5CF6122C32 B6BFEC2F2AE8C35A"));
+
+  /* 192 bit key */
+  test_cipher(&nettle_twofish192,
+             HL("0123456789ABCDEF FEDCBA9876543210"
+                "0011223344556677"),
+             HL("0000000000000000 0000000000000000"),
+             H("CFD1D2E5A9BE9CDF 501F13B892BD2248"));
+
+  /* 256 bit key */
+  test_cipher(&nettle_twofish256,
+             HL("0123456789ABCDEF FEDCBA9876543210"
+                "0011223344556677 8899AABBCCDDEEFF"),
+             HL("0000000000000000 0000000000000000"),
+             H("37527BE0052334B8 9F0CFCCAE87CFA20"));
+
+  SUCCESS();
+}
diff --git a/testsuite/yarrow-test.c b/testsuite/yarrow-test.c
new file mode 100644 (file)
index 0000000..5f01e76
--- /dev/null
@@ -0,0 +1,221 @@
+#include "testutils.h"
+#include "yarrow.h"
+#include "knuth-lfib.h"
+
+#include "macros.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Lagged fibonacci sequence as described in Knuth 3.6 */
+
+struct knuth_lfib_ctx lfib;
+
+static int
+get_event(FILE *f, struct sha256_ctx *hash,
+          unsigned *key, unsigned *time)
+{
+  static int t = 0;
+  uint8_t buf[1];
+  
+  int c = getc(f);
+  if (c == EOF)
+    return 0;
+
+  buf[0] = c;
+  sha256_update(hash, sizeof(buf), buf);
+    
+  *key = c;
+
+  t += (knuth_lfib_get(&lfib) % 10000);
+  *time = t;
+
+  return 1;
+}
+
+static FILE *
+open_file(const char *name)
+{
+  /* Tries opening the file in $srcdir, if set, otherwise the current
+   * working directory */
+
+  const char *srcdir = getenv("srcdir");
+  if (srcdir && srcdir[0])
+    {
+      /* Leaks this name, but that doesn't matter. */
+      char *buf = xalloc(strlen(name) + strlen(srcdir) + 10);
+      sprintf(buf, "%s/%s", srcdir, name);
+      name = buf;
+    }
+
+  /* Opens the file in text mode. */
+  return fopen(name, "r");
+}
+
+int
+test_main(void)
+{
+  FILE *input;
+  
+  struct yarrow256_ctx yarrow;
+  struct yarrow_key_event_ctx estimator;
+
+  struct yarrow_source sources[2];
+
+  struct sha256_ctx output_hash;
+  struct sha256_ctx input_hash;
+  uint8_t digest[SHA256_DIGEST_SIZE];
+
+  uint8_t seed_file[YARROW256_SEED_FILE_SIZE];
+
+  const uint8_t *expected_output
+    = decode_hex_dup("dd304aacac3dc95e 70d684a642967c89"
+                    "58501f7c8eb88b79 43b2ffccde6f0f79");
+
+  const uint8_t *expected_input
+    = decode_hex_dup("e0596cf006025506 65d1195f32a87e4a"
+                    "5c354910dfbd0a31 e2105b262f5ce3d8");
+
+  const uint8_t *expected_seed_file
+    = decode_hex_dup("b03518f32b1084dd 983e6a445d47bb6f"
+                    "13bb7b998740d570 503d6aaa62e28901");
+  
+  unsigned c; unsigned t;
+
+  unsigned processed = 0;
+  unsigned output = 0;
+
+  unsigned i;
+  
+  static const char zeroes[100];
+
+  yarrow256_init(&yarrow, 2, sources);
+  
+  yarrow_key_event_init(&estimator);
+  sha256_init(&input_hash);
+  sha256_init(&output_hash);
+
+  knuth_lfib_init(&lfib, 31416);
+
+  /* Fake input to source 0 */
+  yarrow256_update(&yarrow, 0, 200, sizeof(zeroes), zeroes);
+
+  if (verbose)
+    printf("source 0 entropy: %d\n",
+          sources[0].estimate[YARROW_SLOW]);
+  
+  assert(!yarrow256_is_seeded(&yarrow));
+
+  input = open_file("gold-bug.txt");
+
+  if (!input)
+    {
+      fprintf(stderr, "Couldn't open `gold-bug.txt', errno = %d\n",
+              errno);
+      return EXIT_FAILURE;
+    }
+  
+  while (get_event(input, &input_hash, &c, &t))
+    {
+      uint8_t buf[8];
+
+      processed++;
+      
+      WRITE_UINT32(buf, c);
+      WRITE_UINT32(buf + 4, t);
+      yarrow256_update(&yarrow, 1,
+                       yarrow_key_event_estimate(&estimator, c, t),
+                       sizeof(buf), buf);
+
+      if (yarrow256_is_seeded(&yarrow))
+        {
+          static const unsigned sizes[4] = { 1, 16, 500, 37 };
+          unsigned size = sizes[processed % 4];
+          
+          uint8_t buf[500];
+
+          if (verbose && !output)
+            printf("Generator was seeded after %d events\n",
+                  processed);
+          
+          yarrow256_random(&yarrow, size, buf);
+
+          sha256_update(&output_hash, size, buf);
+
+         if (verbose)
+           {
+             printf("%02x ", buf[0]);
+             if (! (processed % 16))
+               printf("\n");
+           }
+          output += size;
+        }
+    }
+
+  if (verbose)
+    {
+      printf("\n");
+      
+      for (i = 0; i<2; i++)
+       printf("source %d, (fast, slow) entropy: (%d, %d)\n",
+              i,
+              sources[i].estimate[YARROW_FAST],
+              sources[i].estimate[YARROW_SLOW]); 
+      
+      printf("Processed input: %d octets\n", processed);
+      printf("         sha256:");
+    }
+
+  sha256_digest(&input_hash, sizeof(digest), digest);
+
+  if (verbose)
+    {
+      print_hex(sizeof(digest), digest);
+      printf("\n");
+    }
+  
+  if (memcmp(digest, expected_input, sizeof(digest)))
+    {
+      fprintf(stderr, "Failed.\n");
+      return EXIT_FAILURE;
+    }
+
+  yarrow256_random(&yarrow, sizeof(seed_file), seed_file);
+  if (verbose)
+    {
+      printf("New seed file: ");
+      print_hex(sizeof(seed_file), seed_file);
+      printf("\n");
+    }
+
+  if (memcmp(seed_file, expected_seed_file, sizeof(seed_file)))
+    {
+      fprintf(stderr, "Failed.\n");
+      return EXIT_FAILURE;
+    }
+  
+  if (verbose)
+    {
+      printf("Generated output: %d octets\n", output);
+      printf("          sha256:");
+    }
+  
+  sha256_digest(&output_hash, sizeof(digest), digest);
+
+  if (verbose)
+    {
+      print_hex(sizeof(digest), digest);
+      printf("\n");
+    }
+  
+  if (memcmp(digest, expected_output, sizeof(digest)))
+    {
+      fprintf(stderr, "Failed.\n");
+      return EXIT_FAILURE;
+    }
+  
+  return EXIT_SUCCESS;
+}
diff --git a/texinfo.tex b/texinfo.tex
new file mode 100644 (file)
index 0000000..7f876b4
--- /dev/null
@@ -0,0 +1,9287 @@
+% texinfo.tex -- TeX macros to handle Texinfo files.
+%
+% Load plain if necessary, i.e., if running under initex.
+\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+%
+\def\texinfoversion{2009-03-22.17}
+%
+% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
+% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+% 2007, 2008, 2009 Free Software Foundation, Inc.
+%
+% This texinfo.tex file is free software: you can redistribute it and/or
+% modify it under the terms of the GNU General Public License as
+% published by the Free Software Foundation, either version 3 of the
+% License, or (at your option) any later version.
+%
+% This texinfo.tex file 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/>.
+%
+% As a special exception, when this file is read by TeX when processing
+% a Texinfo source document, you may use the result without
+% restriction.  (This has been our intent since Texinfo was invented.)
+%
+% Please try the latest version of texinfo.tex before submitting bug
+% reports; you can get the latest version from:
+%   http://www.gnu.org/software/texinfo/ (the Texinfo home page), or
+%   ftp://tug.org/tex/texinfo.tex
+%     (and all CTAN mirrors, see http://www.ctan.org).
+% The texinfo.tex in any given distribution could well be out
+% of date, so if that's what you're using, please check.
+%
+% Send bug reports to bug-texinfo@gnu.org.  Please include including a
+% complete document in each bug report with which we can reproduce the
+% problem.  Patches are, of course, greatly appreciated.
+%
+% To process a Texinfo manual with TeX, it's most reliable to use the
+% texi2dvi shell script that comes with the distribution.  For a simple
+% manual foo.texi, however, you can get away with this:
+%   tex foo.texi
+%   texindex foo.??
+%   tex foo.texi
+%   tex foo.texi
+%   dvips foo.dvi -o  # or whatever; this makes foo.ps.
+% The extra TeX runs get the cross-reference information correct.
+% Sometimes one run after texindex suffices, and sometimes you need more
+% than two; texi2dvi does it as many times as necessary.
+%
+% It is possible to adapt texinfo.tex for other languages, to some
+% extent.  You can get the existing language-specific files from the
+% full Texinfo distribution.
+%
+% The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
+
+
+\message{Loading texinfo [version \texinfoversion]:}
+
+% If in a .fmt file, print the version number
+% and turn on active characters that we couldn't do earlier because
+% they might have appeared in the input file name.
+\everyjob{\message{[Texinfo version \texinfoversion]}%
+  \catcode`+=\active \catcode`\_=\active}
+
+
+\chardef\other=12
+
+% We never want plain's \outer definition of \+ in Texinfo.
+% For @tex, we can use \tabalign.
+\let\+ = \relax
+
+% Save some plain tex macros whose names we will redefine.
+\let\ptexb=\b
+\let\ptexbullet=\bullet
+\let\ptexc=\c
+\let\ptexcomma=\,
+\let\ptexdot=\.
+\let\ptexdots=\dots
+\let\ptexend=\end
+\let\ptexequiv=\equiv
+\let\ptexexclam=\!
+\let\ptexfootnote=\footnote
+\let\ptexgtr=>
+\let\ptexhat=^
+\let\ptexi=\i
+\let\ptexindent=\indent
+\let\ptexinsert=\insert
+\let\ptexlbrace=\{
+\let\ptexless=<
+\let\ptexnewwrite\newwrite
+\let\ptexnoindent=\noindent
+\let\ptexplus=+
+\let\ptexrbrace=\}
+\let\ptexslash=\/
+\let\ptexstar=\*
+\let\ptext=\t
+\let\ptextop=\top
+{\catcode`\'=\active
+\global\let\ptexquoteright'}% Math-mode def from plain.tex.
+\let\ptexraggedright=\raggedright
+
+% If this character appears in an error message or help string, it
+% starts a new line in the output.
+\newlinechar = `^^J
+
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+  \let\linenumber = \empty % Pre-3.0.
+\else
+  \def\linenumber{l.\the\inputlineno:\space}
+\fi
+
+% Set up fixed words for English if not already set.
+\ifx\putwordAppendix\undefined  \gdef\putwordAppendix{Appendix}\fi
+\ifx\putwordChapter\undefined   \gdef\putwordChapter{Chapter}\fi
+\ifx\putwordfile\undefined      \gdef\putwordfile{file}\fi
+\ifx\putwordin\undefined        \gdef\putwordin{in}\fi
+\ifx\putwordIndexIsEmpty\undefined     \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
+\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
+\ifx\putwordInfo\undefined      \gdef\putwordInfo{Info}\fi
+\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
+\ifx\putwordMethodon\undefined  \gdef\putwordMethodon{Method on}\fi
+\ifx\putwordNoTitle\undefined   \gdef\putwordNoTitle{No Title}\fi
+\ifx\putwordof\undefined        \gdef\putwordof{of}\fi
+\ifx\putwordon\undefined        \gdef\putwordon{on}\fi
+\ifx\putwordpage\undefined      \gdef\putwordpage{page}\fi
+\ifx\putwordsection\undefined   \gdef\putwordsection{section}\fi
+\ifx\putwordSection\undefined   \gdef\putwordSection{Section}\fi
+\ifx\putwordsee\undefined       \gdef\putwordsee{see}\fi
+\ifx\putwordSee\undefined       \gdef\putwordSee{See}\fi
+\ifx\putwordShortTOC\undefined  \gdef\putwordShortTOC{Short Contents}\fi
+\ifx\putwordTOC\undefined       \gdef\putwordTOC{Table of Contents}\fi
+%
+\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi
+\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi
+\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi
+\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi
+\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi
+\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi
+\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi
+\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi
+\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi
+\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi
+\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi
+\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi
+%
+\ifx\putwordDefmac\undefined    \gdef\putwordDefmac{Macro}\fi
+\ifx\putwordDefspec\undefined   \gdef\putwordDefspec{Special Form}\fi
+\ifx\putwordDefvar\undefined    \gdef\putwordDefvar{Variable}\fi
+\ifx\putwordDefopt\undefined    \gdef\putwordDefopt{User Option}\fi
+\ifx\putwordDeffunc\undefined   \gdef\putwordDeffunc{Function}\fi
+
+% Since the category of space is not known, we have to be careful.
+\chardef\spacecat = 10
+\def\spaceisspace{\catcode`\ =\spacecat}
+
+% sometimes characters are active, so we need control sequences.
+\chardef\colonChar = `\:
+\chardef\commaChar = `\,
+\chardef\dashChar  = `\-
+\chardef\dotChar   = `\.
+\chardef\exclamChar= `\!
+\chardef\lquoteChar= `\`
+\chardef\questChar = `\?
+\chardef\rquoteChar= `\'
+\chardef\semiChar  = `\;
+\chardef\underChar = `\_
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+% The following is used inside several \edef's.
+\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname}
+
+% Hyphenation fixes.
+\hyphenation{
+  Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script
+  ap-pen-dix bit-map bit-maps
+  data-base data-bases eshell fall-ing half-way long-est man-u-script
+  man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm
+  par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces
+  spell-ing spell-ings
+  stand-alone strong-est time-stamp time-stamps which-ever white-space
+  wide-spread wrap-around
+}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen\bindingoffset
+\newdimen\normaloffset
+\newdimen\pagewidth \newdimen\pageheight
+
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt}
+
+% @| inserts a changebar to the left of the current line.  It should
+% surround any changed text.  This approach does *not* work if the
+% change spans more than two lines of output.  To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change).
+%
+\def\|{%
+  % \vadjust can only be used in horizontal mode.
+  \leavevmode
+  %
+  % Append this vertical mode material after the current line in the output.
+  \vadjust{%
+    % We want to insert a rule with the height and depth of the current
+    % leading; that is exactly what \strutbox is supposed to record.
+    \vskip-\baselineskip
+    %
+    % \vadjust-items are inserted at the left edge of the type.  So
+    % the \llap here moves out into the left-hand margin.
+    \llap{%
+      %
+      % For a thicker or thinner bar, change the `1pt'.
+      \vrule height\baselineskip width1pt
+      %
+      % This is the space between the bar and the text.
+      \hskip 12pt
+    }%
+  }%
+}
+
+% Sometimes it is convenient to have everything in the transcript file
+% and nothing on the terminal.  We don't just call \tracingall here,
+% since that produces some useless output on the terminal.  We also make
+% some effort to order the tracing commands to reduce output in the log
+% file; cf. trace.sty in LaTeX.
+%
+\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+\def\loggingall{%
+  \tracingstats2
+  \tracingpages1
+  \tracinglostchars2  % 2 gives us more in etex
+  \tracingparagraphs1
+  \tracingoutput1
+  \tracingmacros2
+  \tracingrestores1
+  \showboxbreadth\maxdimen \showboxdepth\maxdimen
+  \ifx\eTeXversion\undefined\else % etex gives us more logging
+    \tracingscantokens1
+    \tracingifs1
+    \tracinggroups1
+    \tracingnesting2
+    \tracingassigns1
+  \fi
+  \tracingcommands3  % 3 gives us more in etex
+  \errorcontextlines16
+}%
+
+% add check for \lastpenalty to plain's definitions.  If the last thing
+% we did was a \nobreak, we don't want to insert more space.
+%
+\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount
+  \removelastskip\penalty-50\smallskip\fi\fi}
+\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount
+  \removelastskip\penalty-100\medskip\fi\fi}
+\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount
+  \removelastskip\penalty-200\bigskip\fi\fi}
+
+% For @cropmarks command.
+% Do @cropmarks to get crop marks.
+%
+\newif\ifcropmarks
+\let\cropmarks = \cropmarkstrue
+%
+% Dimensions to add cropmarks at corners.
+% Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
+\newdimen\cornerlong  \cornerlong=1pc
+\newdimen\cornerthick \cornerthick=.3pt
+\newdimen\topandbottommargin \topandbottommargin=.75in
+
+% Output a mark which sets \thischapter, \thissection and \thiscolor.
+% We dump everything together because we only have one kind of mark.
+% This works because we only use \botmark / \topmark, not \firstmark.
+%
+% A mark contains a subexpression of the \ifcase ... \fi construct.
+% \get*marks macros below extract the needed part using \ifcase.
+%
+% Another complication is to let the user choose whether \thischapter
+% (\thissection) refers to the chapter (section) in effect at the top
+% of a page, or that at the bottom of a page.  The solution is
+% described on page 260 of The TeXbook.  It involves outputting two
+% marks for the sectioning macros, one before the section break, and
+% one after.  I won't pretend I can describe this better than DEK...
+\def\domark{%
+  \toks0=\expandafter{\lastchapterdefs}%
+  \toks2=\expandafter{\lastsectiondefs}%
+  \toks4=\expandafter{\prevchapterdefs}%
+  \toks6=\expandafter{\prevsectiondefs}%
+  \toks8=\expandafter{\lastcolordefs}%
+  \mark{%
+                   \the\toks0 \the\toks2
+      \noexpand\or \the\toks4 \the\toks6
+    \noexpand\else \the\toks8
+  }%
+}
+% \topmark doesn't work for the very first chapter (after the title
+% page or the contents), so we use \firstmark there -- this gets us
+% the mark with the chapter defs, unless the user sneaks in, e.g.,
+% @setcolor (or @url, or @link, etc.) between @contents and the very
+% first @chapter.
+\def\gettopheadingmarks{%
+  \ifcase0\topmark\fi
+  \ifx\thischapter\empty \ifcase0\firstmark\fi \fi
+}
+\def\getbottomheadingmarks{\ifcase1\botmark\fi}
+\def\getcolormarks{\ifcase2\topmark\fi}
+
+% Avoid "undefined control sequence" errors.
+\def\lastchapterdefs{}
+\def\lastsectiondefs{}
+\def\prevchapterdefs{}
+\def\prevsectiondefs{}
+\def\lastcolordefs{}
+
+% Main output routine.
+\chardef\PAGE = 255
+\output = {\onepageout{\pagecontents\PAGE}}
+
+\newbox\headlinebox
+\newbox\footlinebox
+
+% \onepageout takes a vbox as an argument.  Note that \pagecontents
+% does insertions, but you have to call it yourself.
+\def\onepageout#1{%
+  \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
+  %
+  \ifodd\pageno  \advance\hoffset by \bindingoffset
+  \else \advance\hoffset by -\bindingoffset\fi
+  %
+  % Do this outside of the \shipout so @code etc. will be expanded in
+  % the headline as they should be, not taken literally (outputting ''code).
+  \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi
+  \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+  \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi
+  \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
+  %
+  {%
+    % Have to do this stuff outside the \shipout because we want it to
+    % take effect in \write's, yet the group defined by the \vbox ends
+    % before the \shipout runs.
+    %
+    \indexdummies         % don't expand commands in the output.
+    \normalturnoffactive  % \ in index entries must not stay \, e.g., if
+               % the page break happens to be in the middle of an example.
+               % 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
+               % {\code {{\tt \backslashcurfont }acronym}
+    \shipout\vbox{%
+      % Do this early so pdf references go to the beginning of the page.
+      \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
+      %
+      \ifcropmarks \vbox to \outervsize\bgroup
+        \hsize = \outerhsize
+        \vskip-\topandbottommargin
+        \vtop to0pt{%
+          \line{\ewtop\hfil\ewtop}%
+          \nointerlineskip
+          \line{%
+            \vbox{\moveleft\cornerthick\nstop}%
+            \hfill
+            \vbox{\moveright\cornerthick\nstop}%
+          }%
+          \vss}%
+        \vskip\topandbottommargin
+        \line\bgroup
+          \hfil % center the page within the outer (page) hsize.
+          \ifodd\pageno\hskip\bindingoffset\fi
+          \vbox\bgroup
+      \fi
+      %
+      \unvbox\headlinebox
+      \pagebody{#1}%
+      \ifdim\ht\footlinebox > 0pt
+        % Only leave this space if the footline is nonempty.
+        % (We lessened \vsize for it in \oddfootingyyy.)
+        % The \baselineskip=24pt in plain's \makefootline has no effect.
+        \vskip 24pt
+        \unvbox\footlinebox
+      \fi
+      %
+      \ifcropmarks
+          \egroup % end of \vbox\bgroup
+        \hfil\egroup % end of (centering) \line\bgroup
+        \vskip\topandbottommargin plus1fill minus1fill
+        \boxmaxdepth = \cornerthick
+        \vbox to0pt{\vss
+          \line{%
+            \vbox{\moveleft\cornerthick\nsbot}%
+            \hfill
+            \vbox{\moveright\cornerthick\nsbot}%
+          }%
+          \nointerlineskip
+          \line{\ewbot\hfil\ewbot}%
+        }%
+      \egroup % \vbox from first cropmarks clause
+      \fi
+    }% end of \shipout\vbox
+  }% end of group with \indexdummies
+  \advancepageno
+  \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+}
+
+\newinsert\margin \dimen\margin=\maxdimen
+
+\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+{\catcode`\@ =11
+\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+% marginal hacks, juha@viisa.uucp (Juha Takala)
+\ifvoid\margin\else % marginal info is present
+  \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
+\dimen@=\dp#1\relax \unvbox#1\relax
+\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
+}
+
+% Here are the rules for the cropmarks.  Note that they are
+% offset so that the space between them is truly \outerhsize or \outervsize
+% (P. A. MacKay, 12 November, 1986)
+%
+\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+\def\nstop{\vbox
+  {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+\def\nsbot{\vbox
+  {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+
+% Parse an argument, then pass it to #1.  The argument is the rest of
+% the input line (except we remove a trailing comment).  #1 should be a
+% macro which expects an ordinary undelimited TeX argument.
+%
+\def\parsearg{\parseargusing{}}
+\def\parseargusing#1#2{%
+  \def\argtorun{#2}%
+  \begingroup
+    \obeylines
+    \spaceisspace
+    #1%
+    \parseargline\empty% Insert the \empty token, see \finishparsearg below.
+}
+
+{\obeylines %
+  \gdef\parseargline#1^^M{%
+    \endgroup % End of the group started in \parsearg.
+    \argremovecomment #1\comment\ArgTerm%
+  }%
+}
+
+% First remove any @comment, then any @c comment.
+\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
+\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm}
+
+% Each occurrence of `\^^M' or `<space>\^^M' is replaced by a single space.
+%
+% \argremovec might leave us with trailing space, e.g.,
+%    @end itemize  @c foo
+% This space token undergoes the same procedure and is eventually removed
+% by \finishparsearg.
+%
+\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
+\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
+\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
+  \def\temp{#3}%
+  \ifx\temp\empty
+    % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp:
+    \let\temp\finishparsearg
+  \else
+    \let\temp\argcheckspaces
+  \fi
+  % Put the space token in:
+  \temp#1 #3\ArgTerm
+}
+
+% If a _delimited_ argument is enclosed in braces, they get stripped; so
+% to get _exactly_ the rest of the line, we had to prevent such situation.
+% We prepended an \empty token at the very beginning and we expand it now,
+% just before passing the control to \argtorun.
+% (Similarly, we have to think about #3 of \argcheckspacesY above: it is
+% either the null string, or it ends with \^^M---thus there is no danger
+% that a pair of braces would be stripped.
+%
+% But first, we have to remove the trailing space token.
+%
+\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}}
+
+% \parseargdef\foo{...}
+%      is roughly equivalent to
+% \def\foo{\parsearg\Xfoo}
+% \def\Xfoo#1{...}
+%
+% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
+% favourite TeX trick.  --kasal, 16nov03
+
+\def\parseargdef#1{%
+  \expandafter \doparseargdef \csname\string#1\endcsname #1%
+}
+\def\doparseargdef#1#2{%
+  \def#2{\parsearg#1}%
+  \def#1##1%
+}
+
+% Several utility definitions with active space:
+{
+  \obeyspaces
+  \gdef\obeyedspace{ }
+
+  % Make each space character in the input produce a normal interword
+  % space in the output.  Don't allow a line break at this space, as this
+  % is used only in environments like @example, where each line of input
+  % should produce a line of output anyway.
+  %
+  \gdef\sepspaces{\obeyspaces\let =\tie}
+
+  % If an index command is used in an @example environment, any spaces
+  % therein should become regular spaces in the raw index file, not the
+  % expansion of \tie (\leavevmode \penalty \@M \ ).
+  \gdef\unsepspaces{\let =\space}
+}
+
+
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+% Define the framework for environments in texinfo.tex.  It's used like this:
+%
+%   \envdef\foo{...}
+%   \def\Efoo{...}
+%
+% It's the responsibility of \envdef to insert \begingroup before the
+% actual body; @end closes the group after calling \Efoo.  \envdef also
+% defines \thisenv, so the current environment is known; @end checks
+% whether the environment name matches.  The \checkenv macro can also be
+% used to check whether the current environment is the one expected.
+%
+% Non-false conditionals (@iftex, @ifset) don't fit into this, so they
+% are not treated as environments; they don't open a group.  (The
+% implementation of @end takes care not to call \endgroup in this
+% special case.)
+
+
+% At run-time, environments start with this:
+\def\startenvironment#1{\begingroup\def\thisenv{#1}}
+% initialize
+\let\thisenv\empty
+
+% ... but they get defined via ``\envdef\foo{...}'':
+\long\def\envdef#1#2{\def#1{\startenvironment#1#2}}
+\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}}
+
+% Check whether we're in the right environment:
+\def\checkenv#1{%
+  \def\temp{#1}%
+  \ifx\thisenv\temp
+  \else
+    \badenverr
+  \fi
+}
+
+% Environment mismatch, #1 expected:
+\def\badenverr{%
+  \errhelp = \EMsimple
+  \errmessage{This command can appear only \inenvironment\temp,
+    not \inenvironment\thisenv}%
+}
+\def\inenvironment#1{%
+  \ifx#1\empty
+    out of any environment%
+  \else
+    in environment \expandafter\string#1%
+  \fi
+}
+
+% @end foo executes the definition of \Efoo.
+% But first, it executes a specialized version of \checkenv
+%
+\parseargdef\end{%
+  \if 1\csname iscond.#1\endcsname
+  \else
+    % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03
+    \expandafter\checkenv\csname#1\endcsname
+    \csname E#1\endcsname
+    \endgroup
+  \fi
+}
+
+\newhelp\EMsimple{Press RETURN to continue.}
+
+
+%% Simple single-character @ commands
+
+% @@ prints an @
+% Kludge this until the fonts are right (grr).
+\def\@{{\tt\char64}}
+
+% This is turned off because it was never documented
+% and you can use @w{...} around a quote to suppress ligatures.
+%% Define @` and @' to be the same as ` and '
+%% but suppressing ligatures.
+%\def\`{{`}}
+%\def\'{{'}}
+
+% Used to generate quoted braces.
+\def\mylbrace {{\tt\char123}}
+\def\myrbrace {{\tt\char125}}
+\let\{=\mylbrace
+\let\}=\myrbrace
+\begingroup
+  % Definitions to produce \{ and \} commands for indices,
+  % and @{ and @} for the aux/toc files.
+  \catcode`\{ = \other \catcode`\} = \other
+  \catcode`\[ = 1 \catcode`\] = 2
+  \catcode`\! = 0 \catcode`\\ = \other
+  !gdef!lbracecmd[\{]%
+  !gdef!rbracecmd[\}]%
+  !gdef!lbraceatcmd[@{]%
+  !gdef!rbraceatcmd[@}]%
+!endgroup
+
+% @comma{} to avoid , parsing problems.
+\let\comma = ,
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
+\let\, = \c
+\let\dotaccent = \.
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \t
+\let\ubaraccent = \b
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown @ordf @ordm
+% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
+\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+  \def\temp{#1}%
+  \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi
+  \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi
+  \else \errmessage{@dotless can be used only with i or j}%
+  \fi\fi
+}
+
+% The \TeX{} logo, as in plain, but resetting the spacing so that a
+% period following counts as ending a sentence.  (Idea found in latex.)
+%
+\edef\TeX{\TeX \spacefactor=1000 }
+
+% @LaTeX{} logo.  Not quite the same results as the definition in
+% latex.ltx, since we use a different font for the raised A; it's most
+% convenient for us to use an explicitly smaller font, rather than using
+% the \scriptstyle font (since we don't reset \scriptstyle and
+% \scriptscriptstyle).
+%
+\def\LaTeX{%
+  L\kern-.36em
+  {\setbox0=\hbox{T}%
+   \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}%
+  \kern-.15em
+  \TeX
+}
+
+% Be sure we're in horizontal mode when doing a tie, since we make space
+% equivalent to this in @example-like environments. Otherwise, a space
+% at the beginning of a line will start with \penalty -- and
+% since \penalty is valid in vertical mode, we'd end up putting the
+% penalty on the vertical list instead of in the new paragraph.
+{\catcode`@ = 11
+ % Avoid using \@M directly, because that causes trouble
+ % if the definition is written into an index file.
+ \global\let\tiepenalty = \@M
+ \gdef\tie{\leavevmode\penalty\tiepenalty\ }
+}
+
+% @: forces normal size whitespace following.
+\def\:{\spacefactor=1000 }
+
+% @* forces a line break.
+\def\*{\hfil\break\hbox{}\ignorespaces}
+
+% @/ allows a line break.
+\let\/=\allowbreak
+
+% @. is an end-of-sentence period.
+\def\.{.\spacefactor=\endofsentencespacefactor\space}
+
+% @! is an end-of-sentence bang.
+\def\!{!\spacefactor=\endofsentencespacefactor\space}
+
+% @? is an end-of-sentence query.
+\def\?{?\spacefactor=\endofsentencespacefactor\space}
+
+% @frenchspacing on|off  says whether to put extra space after punctuation.
+%
+\def\onword{on}
+\def\offword{off}
+%
+\parseargdef\frenchspacing{%
+  \def\temp{#1}%
+  \ifx\temp\onword \plainfrenchspacing
+  \else\ifx\temp\offword \plainnonfrenchspacing
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @frenchspacing option `\temp', must be on/off}%
+  \fi\fi
+}
+
+% @w prevents a word break.  Without the \leavevmode, @w at the
+% beginning of a paragraph, when TeX is still in vertical mode, would
+% produce a whole line of output instead of starting the paragraph.
+\def\w#1{\leavevmode\hbox{#1}}
+
+% @group ... @end group forces ... to be all on one page, by enclosing
+% it in a TeX vbox.  We use \vtop instead of \vbox to construct the box
+% to keep its height that of a normal line.  According to the rules for
+% \topskip (p.114 of the TeXbook), the glue inserted is
+% max (\topskip - \ht (first item), 0).  If that height is large,
+% therefore, no glue is inserted, and the space between the headline and
+% the text is small, which looks bad.
+%
+% Another complication is that the group might be very large.  This can
+% cause the glue on the previous page to be unduly stretched, because it
+% does not have much material.  In this case, it's better to add an
+% explicit \vfill so that the extra space is at the bottom.  The
+% threshold for doing this is if the group is more than \vfilllimit
+% percent of a page (\vfilllimit can be changed inside of @tex).
+%
+\newbox\groupbox
+\def\vfilllimit{0.7}
+%
+\envdef\group{%
+  \ifnum\catcode`\^^M=\active \else
+    \errhelp = \groupinvalidhelp
+    \errmessage{@group invalid in context where filling is enabled}%
+  \fi
+  \startsavinginserts
+  %
+  \setbox\groupbox = \vtop\bgroup
+    % Do @comment since we are called inside an environment such as
+    % @example, where each end-of-line in the input causes an
+    % end-of-line in the output.  We don't want the end-of-line after
+    % the `@group' to put extra space in the output.  Since @group
+    % should appear on a line by itself (according to the Texinfo
+    % manual), we don't worry about eating any user text.
+    \comment
+}
+%
+% The \vtop produces a box with normal height and large depth; thus, TeX puts
+% \baselineskip glue before it, and (when the next line of text is done)
+% \lineskip glue after it.  Thus, space below is not quite equal to space
+% above.  But it's pretty close.
+\def\Egroup{%
+    % To get correct interline space between the last line of the group
+    % and the first line afterwards, we have to propagate \prevdepth.
+    \endgraf % Not \par, as it may have been set to \lisppar.
+    \global\dimen1 = \prevdepth
+  \egroup           % End the \vtop.
+  % \dimen0 is the vertical size of the group's box.
+  \dimen0 = \ht\groupbox  \advance\dimen0 by \dp\groupbox
+  % \dimen2 is how much space is left on the page (more or less).
+  \dimen2 = \pageheight   \advance\dimen2 by -\pagetotal
+  % if the group doesn't fit on the current page, and it's a big big
+  % group, force a page break.
+  \ifdim \dimen0 > \dimen2
+    \ifdim \pagetotal < \vfilllimit\pageheight
+      \page
+    \fi
+  \fi
+  \box\groupbox
+  \prevdepth = \dimen1
+  \checkinserts
+}
+%
+% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+% message, so this ends up printing `@group can only ...'.
+%
+\newhelp\groupinvalidhelp{%
+group can only be used in environments such as @example,^^J%
+where each line of input produces a line of output.}
+
+% @need space-in-mils
+% forces a page break if there is not space-in-mils remaining.
+
+\newdimen\mil  \mil=0.001in
+
+% Old definition--didn't work.
+%\parseargdef\need{\par %
+%% This method tries to make TeX break the page naturally
+%% if the depth of the box does not fit.
+%{\baselineskip=0pt%
+%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak
+%\prevdepth=-1000pt
+%}}
+
+\parseargdef\need{%
+  % Ensure vertical mode, so we don't make a big box in the middle of a
+  % paragraph.
+  \par
+  %
+  % If the @need value is less than one line space, it's useless.
+  \dimen0 = #1\mil
+  \dimen2 = \ht\strutbox
+  \advance\dimen2 by \dp\strutbox
+  \ifdim\dimen0 > \dimen2
+    %
+    % Do a \strut just to make the height of this box be normal, so the
+    % normal leading is inserted relative to the preceding line.
+    % And a page break here is fine.
+    \vtop to #1\mil{\strut\vfil}%
+    %
+    % TeX does not even consider page breaks if a penalty added to the
+    % main vertical list is 10000 or more.  But in order to see if the
+    % empty box we just added fits on the page, we must make it consider
+    % page breaks.  On the other hand, we don't want to actually break the
+    % page after the empty box.  So we use a penalty of 9999.
+    %
+    % There is an extremely small chance that TeX will actually break the
+    % page at this \penalty, if there are no other feasible breakpoints in
+    % sight.  (If the user is using lots of big @group commands, which
+    % almost-but-not-quite fill up a page, TeX will have a hard time doing
+    % good page breaking, for example.)  However, I could not construct an
+    % example where a page broke at this \penalty; if it happens in a real
+    % document, then we can reconsider our strategy.
+    \penalty9999
+    %
+    % Back up by the size of the box, whether we did a page break or not.
+    \kern -#1\mil
+    %
+    % Do not allow a page break right after this kern.
+    \nobreak
+  \fi
+}
+
+% @br   forces paragraph break (and is undocumented).
+
+\let\br = \par
+
+% @page forces the start of a new page.
+%
+\def\page{\par\vfill\supereject}
+
+% @exdent text....
+% outputs text on separate line in roman font, starting at standard page margin
+
+% This records the amount of indent in the innermost environment.
+% That's how much \exdent should take out.
+\newskip\exdentamount
+
+% This defn is used inside fill environments such as @defun.
+\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}
+
+% This defn is used inside nofill environments such as @example.
+\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount
+  \leftline{\hskip\leftskip{\rm#1}}}}
+
+% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
+% paragraph.  For more general purposes, use the \margin insertion
+% class.  WHICH is `l' or `r'.
+%
+\newskip\inmarginspacing \inmarginspacing=1cm
+\def\strutdepth{\dp\strutbox}
+%
+\def\doinmargin#1#2{\strut\vadjust{%
+  \nobreak
+  \kern-\strutdepth
+  \vtop to \strutdepth{%
+    \baselineskip=\strutdepth
+    \vss
+    % if you have multiple lines of stuff to put here, you'll need to
+    % make the vbox yourself of the appropriate size.
+    \ifx#1l%
+      \llap{\ignorespaces #2\hskip\inmarginspacing}%
+    \else
+      \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
+    \fi
+    \null
+  }%
+}}
+\def\inleftmargin{\doinmargin l}
+\def\inrightmargin{\doinmargin r}
+%
+% @inmargin{TEXT [, RIGHT-TEXT]}
+% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
+% else use TEXT for both).
+%
+\def\inmargin#1{\parseinmargin #1,,\finish}
+\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
+  \setbox0 = \hbox{\ignorespaces #2}%
+  \ifdim\wd0 > 0pt
+    \def\lefttext{#1}%  have both texts
+    \def\righttext{#2}%
+  \else
+    \def\lefttext{#1}%  have only one text
+    \def\righttext{#1}%
+  \fi
+  %
+  \ifodd\pageno
+    \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin
+  \else
+    \def\temp{\inleftmargin\lefttext}%
+  \fi
+  \temp
+}
+
+% @include FILE -- \input text of FILE.
+%
+\def\include{\parseargusing\filenamecatcodes\includezzz}
+\def\includezzz#1{%
+  \pushthisfilestack
+  \def\thisfile{#1}%
+  {%
+    \makevalueexpandable  % we want to expand any @value in FILE.
+    \turnoffactive        % and allow special characters in the expansion
+    \indexnofonts         % Allow `@@' and other weird things in file names.
+    \edef\temp{\noexpand\input #1 }%
+    %
+    % This trickery is to read FILE outside of a group, in case it makes
+    % definitions, etc.
+    \expandafter
+  }\temp
+  \popthisfilestack
+}
+\def\filenamecatcodes{%
+  \catcode`\\=\other
+  \catcode`~=\other
+  \catcode`^=\other
+  \catcode`_=\other
+  \catcode`|=\other
+  \catcode`<=\other
+  \catcode`>=\other
+  \catcode`+=\other
+  \catcode`-=\other
+  \catcode`\`=\other
+  \catcode`\'=\other
+}
+
+\def\pushthisfilestack{%
+  \expandafter\pushthisfilestackX\popthisfilestack\StackTerm
+}
+\def\pushthisfilestackX{%
+  \expandafter\pushthisfilestackY\thisfile\StackTerm
+}
+\def\pushthisfilestackY #1\StackTerm #2\StackTerm {%
+  \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}%
+}
+
+\def\popthisfilestack{\errthisfilestackempty}
+\def\errthisfilestackempty{\errmessage{Internal error:
+  the stack of filenames is empty.}}
+
+\def\thisfile{}
+
+% @center line
+% outputs that line, centered.
+%
+\parseargdef\center{%
+  \ifhmode
+    \let\next\centerH
+  \else
+    \let\next\centerV
+  \fi
+  \next{\hfil \ignorespaces#1\unskip \hfil}%
+}
+\def\centerH#1{%
+  {%
+    \hfil\break
+    \advance\hsize by -\leftskip
+    \advance\hsize by -\rightskip
+    \line{#1}%
+    \break
+  }%
+}
+\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}}
+
+% @sp n   outputs n lines of vertical space
+
+\parseargdef\sp{\vskip #1\baselineskip}
+
+% @comment ...line which is ignored...
+% @c is the same as @comment
+% @ignore ... @end ignore  is another way to write a comment
+
+\def\comment{\begingroup \catcode`\^^M=\other%
+\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
+\commentxxx}
+{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
+
+\let\c=\comment
+
+% @paragraphindent NCHARS
+% We'll use ems for NCHARS, close enough.
+% NCHARS can also be the word `asis' or `none'.
+% We cannot feasibly implement @paragraphindent asis, though.
+%
+\def\asisword{asis} % no translation, these are keywords
+\def\noneword{none}
+%
+\parseargdef\paragraphindent{%
+  \def\temp{#1}%
+  \ifx\temp\asisword
+  \else
+    \ifx\temp\noneword
+      \defaultparindent = 0pt
+    \else
+      \defaultparindent = #1em
+    \fi
+  \fi
+  \parindent = \defaultparindent
+}
+
+% @exampleindent NCHARS
+% We'll use ems for NCHARS like @paragraphindent.
+% It seems @exampleindent asis isn't necessary, but
+% I preserve it to make it similar to @paragraphindent.
+\parseargdef\exampleindent{%
+  \def\temp{#1}%
+  \ifx\temp\asisword
+  \else
+    \ifx\temp\noneword
+      \lispnarrowing = 0pt
+    \else
+      \lispnarrowing = #1em
+    \fi
+  \fi
+}
+
+% @firstparagraphindent WORD
+% If WORD is `none', then suppress indentation of the first paragraph
+% after a section heading.  If WORD is `insert', then do indent at such
+% paragraphs.
+%
+% The paragraph indentation is suppressed or not by calling
+% \suppressfirstparagraphindent, which the sectioning commands do.
+% We switch the definition of this back and forth according to WORD.
+% By default, we suppress indentation.
+%
+\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent}
+\def\insertword{insert}
+%
+\parseargdef\firstparagraphindent{%
+  \def\temp{#1}%
+  \ifx\temp\noneword
+    \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent
+  \else\ifx\temp\insertword
+    \let\suppressfirstparagraphindent = \relax
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @firstparagraphindent option `\temp'}%
+  \fi\fi
+}
+
+% Here is how we actually suppress indentation.  Redefine \everypar to
+% \kern backwards by \parindent, and then reset itself to empty.
+%
+% We also make \indent itself not actually do anything until the next
+% paragraph.
+%
+\gdef\dosuppressfirstparagraphindent{%
+  \gdef\indent{%
+    \restorefirstparagraphindent
+    \indent
+  }%
+  \gdef\noindent{%
+    \restorefirstparagraphindent
+    \noindent
+  }%
+  \global\everypar = {%
+    \kern -\parindent
+    \restorefirstparagraphindent
+  }%
+}
+
+\gdef\restorefirstparagraphindent{%
+  \global \let \indent = \ptexindent
+  \global \let \noindent = \ptexnoindent
+  \global \everypar = {}%
+}
+
+
+% @asis just yields its argument.  Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math outputs its argument in math mode.
+%
+% One complication: _ usually means subscripts, but it could also mean
+% an actual _ character, as in @math{@var{some_variable} + 1}.  So make
+% _ active, and distinguish by seeing if the current family is \slfam,
+% which is what @var uses.
+{
+  \catcode`\_ = \active
+  \gdef\mathunderscore{%
+    \catcode`\_=\active
+    \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
+  }
+}
+% Another complication: we want \\ (and @\) to output a \ character.
+% FYI, plain.tex uses \\ as a temporary control sequence (why?), but
+% this is not advertised and we don't care.  Texinfo does not
+% otherwise define @\.
+%
+% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
+\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
+%
+\def\math{%
+  \tex
+  \mathunderscore
+  \let\\ = \mathbackslash
+  \mathactive
+  % make the texinfo accent commands work in math mode
+  \let\"=\ddot
+  \let\'=\acute
+  \let\==\bar
+  \let\^=\hat
+  \let\`=\grave
+  \let\u=\breve
+  \let\v=\check
+  \let\~=\tilde
+  \let\dotaccent=\dot
+  $\finishmath
+}
+\def\finishmath#1{#1$\endgroup}  % Close the group opened by \tex.
+
+% Some active characters (such as <) are spaced differently in math.
+% We have to reset their definitions in case the @math was an argument
+% to a command which sets the catcodes (such as @item or @section).
+%
+{
+  \catcode`^ = \active
+  \catcode`< = \active
+  \catcode`> = \active
+  \catcode`+ = \active
+  \catcode`' = \active
+  \gdef\mathactive{%
+    \let^ = \ptexhat
+    \let< = \ptexless
+    \let> = \ptexgtr
+    \let+ = \ptexplus
+    \let' = \ptexquoteright
+  }
+}
+
+% Some math mode symbols.
+\def\bullet{$\ptexbullet$}
+\def\geq{\ifmmode \ge\else $\ge$\fi}
+\def\leq{\ifmmode \le\else $\le$\fi}
+\def\minus{\ifmmode -\else $-$\fi}
+
+% @dots{} outputs an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in the cm
+% typewriter fonts as three actual period characters; on the other hand,
+% in other typewriter fonts three periods are wider than 1.5em.  So do
+% whichever is larger.
+%
+\def\dots{%
+  \leavevmode
+  \setbox0=\hbox{...}% get width of three periods
+  \ifdim\wd0 > 1.5em
+    \dimen0 = \wd0
+  \else
+    \dimen0 = 1.5em
+  \fi
+  \hbox to \dimen0{%
+    \hskip 0pt plus.25fil
+    .\hskip 0pt plus1fil
+    .\hskip 0pt plus1fil
+    .\hskip 0pt plus.5fil
+  }%
+}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+  \dots
+  \spacefactor=\endofsentencespacefactor
+}
+
+% @comma{} is so commas can be inserted into text without messing up
+% Texinfo's parsing.
+%
+\let\comma = ,
+
+% @refill is a no-op.
+\let\refill=\relax
+
+% If working on a large document in chapters, it is convenient to
+% be able to disable indexing, cross-referencing, and contents, for test runs.
+% This is done with @novalidate (before @setfilename).
+%
+\newif\iflinks \linkstrue % by default we want the aux files.
+\let\novalidate = \linksfalse
+
+% @setfilename is done at the beginning of every texinfo file.
+% So open here the files we need to have open while reading the input.
+% This makes it possible to make a .fmt file for texinfo.
+\def\setfilename{%
+   \fixbackslash  % Turn off hack to swallow `\input texinfo'.
+   \iflinks
+     \tryauxfile
+     % Open the new aux file.  TeX will close it automatically at exit.
+     \immediate\openout\auxfile=\jobname.aux
+   \fi % \openindices needs to do some work in any case.
+   \openindices
+   \let\setfilename=\comment % Ignore extra @setfilename cmds.
+   %
+   % If texinfo.cnf is present on the system, read it.
+   % Useful for site-wide @afourpaper, etc.
+   \openin 1 texinfo.cnf
+   \ifeof 1 \else \input texinfo.cnf \fi
+   \closein 1
+   %
+   \comment % Ignore the actual filename.
+}
+
+% Called from \setfilename.
+%
+\def\openindices{%
+  \newindex{cp}%
+  \newcodeindex{fn}%
+  \newcodeindex{vr}%
+  \newcodeindex{tp}%
+  \newcodeindex{ky}%
+  \newcodeindex{pg}%
+}
+
+% @bye.
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+
+\message{pdf,}
+% adobe `portable' document format
+\newcount\tempnum
+\newcount\lnkcount
+\newtoks\filename
+\newcount\filenamelength
+\newcount\pgn
+\newtoks\toksA
+\newtoks\toksB
+\newtoks\toksC
+\newtoks\toksD
+\newbox\boxA
+\newcount\countA
+\newif\ifpdf
+\newif\ifpdfmakepagedest
+
+% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
+% can be set).  So we test for \relax and 0 as well as \undefined,
+% borrowed from ifpdf.sty.
+\ifx\pdfoutput\undefined
+\else
+  \ifx\pdfoutput\relax
+  \else
+    \ifcase\pdfoutput
+    \else
+      \pdftrue
+    \fi
+  \fi
+\fi
+
+% PDF uses PostScript string constants for the names of xref targets,
+% for display in the outlines, and in other places.  Thus, we have to
+% double any backslashes.  Otherwise, a name like "\node" will be
+% interpreted as a newline (\n), followed by o, d, e.  Not good.
+% http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html
+% (and related messages, the final outcome is that it is up to the TeX
+% user to double the backslashes and otherwise make the string valid, so
+% that's what we do).
+
+% double active backslashes.
+%
+{\catcode`\@=0 \catcode`\\=\active
+ @gdef@activebackslashdouble{%
+   @catcode`@\=@active
+   @let\=@doublebackslash}
+}
+
+% To handle parens, we must adopt a different approach, since parens are
+% not active characters.  hyperref.dtx (which has the same problem as
+% us) handles it with this amazing macro to replace tokens, with minor
+% changes for Texinfo.  It is included here under the GPL by permission
+% from the author, Heiko Oberdiek.
+%
+% #1 is the tokens to replace.
+% #2 is the replacement.
+% #3 is the control sequence with the string.
+%
+\def\HyPsdSubst#1#2#3{%
+  \def\HyPsdReplace##1#1##2\END{%
+    ##1%
+    \ifx\\##2\\%
+    \else
+      #2%
+      \HyReturnAfterFi{%
+        \HyPsdReplace##2\END
+      }%
+    \fi
+  }%
+  \xdef#3{\expandafter\HyPsdReplace#3#1\END}%
+}
+\long\def\HyReturnAfterFi#1\fi{\fi#1}
+
+% #1 is a control sequence in which to do the replacements.
+\def\backslashparens#1{%
+  \xdef#1{#1}% redefine it as its expansion; the definition is simply
+             % \lastnode when called from \setref -> \pdfmkdest.
+  \HyPsdSubst{(}{\realbackslash(}{#1}%
+  \HyPsdSubst{)}{\realbackslash)}{#1}%
+}
+
+\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images
+with PDF output, and none of those formats could be found.  (.eps cannot
+be supported due to the design of the PDF format; use regular TeX (DVI
+output) for that.)}
+
+\ifpdf
+  %
+  % Color manipulation macros based on pdfcolor.tex.
+  \def\cmykDarkRed{0.28 1 1 0.35}
+  \def\cmykBlack{0 0 0 1}
+  %
+  % k sets the color for filling (usual text, etc.);
+  % K sets the color for stroking (thin rules, e.g., normal _'s).
+  \def\pdfsetcolor#1{\pdfliteral{#1 k  #1 K}}
+  %
+  % Set color, and create a mark which defines \thiscolor accordingly,
+  % so that \makeheadline knows which color to restore.
+  \def\setcolor#1{%
+    \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}%
+    \domark
+    \pdfsetcolor{#1}%
+  }
+  %
+  \def\maincolor{\cmykBlack}
+  \pdfsetcolor{\maincolor}
+  \edef\thiscolor{\maincolor}
+  \def\lastcolordefs{}
+  %
+  \def\makefootline{%
+    \baselineskip24pt
+    \line{\pdfsetcolor{\maincolor}\the\footline}%
+  }
+  %
+  \def\makeheadline{%
+    \vbox to 0pt{%
+      \vskip-22.5pt
+      \line{%
+        \vbox to8.5pt{}%
+        % Extract \thiscolor definition from the marks.
+        \getcolormarks
+        % Typeset the headline with \maincolor, then restore the color.
+        \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}%
+      }%
+      \vss
+    }%
+    \nointerlineskip
+  }
+  %
+  %
+  \pdfcatalog{/PageMode /UseOutlines}
+  %
+  % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto).
+  \def\dopdfimage#1#2#3{%
+    \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
+    \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
+    %
+    % pdftex (and the PDF format) support .png, .jpg, .pdf (among
+    % others).  Let's try in that order.
+    \let\pdfimgext=\empty
+    \begingroup
+      \openin 1 #1.png \ifeof 1
+        \openin 1 #1.jpg \ifeof 1
+          \openin 1 #1.jpeg \ifeof 1
+            \openin 1 #1.JPG \ifeof 1
+              \openin 1 #1.pdf \ifeof 1
+                \openin 1 #1.PDF \ifeof 1
+                  \errhelp = \nopdfimagehelp
+                  \errmessage{Could not find image file #1 for pdf}%
+                \else \gdef\pdfimgext{PDF}%
+                \fi
+              \else \gdef\pdfimgext{pdf}%
+              \fi
+            \else \gdef\pdfimgext{JPG}%
+            \fi
+          \else \gdef\pdfimgext{jpeg}%
+          \fi
+        \else \gdef\pdfimgext{jpg}%
+        \fi
+      \else \gdef\pdfimgext{png}%
+      \fi
+      \closein 1
+    \endgroup
+    %
+    % without \immediate, ancient pdftex seg faults when the same image is
+    % included twice.  (Version 3.14159-pre-1.0-unofficial-20010704.)
+    \ifnum\pdftexversion < 14
+      \immediate\pdfimage
+    \else
+      \immediate\pdfximage
+    \fi
+      \ifdim \wd0 >0pt width \imagewidth \fi
+      \ifdim \wd2 >0pt height \imageheight \fi
+      \ifnum\pdftexversion<13
+         #1.\pdfimgext
+       \else
+         {#1.\pdfimgext}%
+       \fi
+    \ifnum\pdftexversion < 14 \else
+      \pdfrefximage \pdflastximage
+    \fi}
+  %
+  \def\pdfmkdest#1{{%
+    % We have to set dummies so commands such as @code, and characters
+    % such as \, aren't expanded when present in a section title.
+    \indexnofonts
+    \turnoffactive
+    \activebackslashdouble
+    \makevalueexpandable
+    \def\pdfdestname{#1}%
+    \backslashparens\pdfdestname
+    \safewhatsit{\pdfdest name{\pdfdestname} xyz}%
+  }}
+  %
+  % used to mark target names; must be expandable.
+  \def\pdfmkpgn#1{#1}
+  %
+  % by default, use a color that is dark enough to print on paper as
+  % nearly black, but still distinguishable for online viewing.
+  \def\urlcolor{\cmykDarkRed}
+  \def\linkcolor{\cmykDarkRed}
+  \def\endlink{\setcolor{\maincolor}\pdfendlink}
+  %
+  % Adding outlines to PDF; macros for calculating structure of outlines
+  % come from Petr Olsak
+  \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
+    \else \csname#1\endcsname \fi}
+  \def\advancenumber#1{\tempnum=\expnumber{#1}\relax
+    \advance\tempnum by 1
+    \expandafter\xdef\csname#1\endcsname{\the\tempnum}}
+  %
+  % #1 is the section text, which is what will be displayed in the
+  % outline by the pdf viewer.  #2 is the pdf expression for the number
+  % of subentries (or empty, for subsubsections).  #3 is the node text,
+  % which might be empty if this toc entry had no corresponding node.
+  % #4 is the page number
+  %
+  \def\dopdfoutline#1#2#3#4{%
+    % Generate a link to the node text if that exists; else, use the
+    % page number.  We could generate a destination for the section
+    % text in the case where a section has no node, but it doesn't
+    % seem worth the trouble, since most documents are normally structured.
+    \def\pdfoutlinedest{#3}%
+    \ifx\pdfoutlinedest\empty
+      \def\pdfoutlinedest{#4}%
+    \else
+      % Doubled backslashes in the name.
+      {\activebackslashdouble \xdef\pdfoutlinedest{#3}%
+       \backslashparens\pdfoutlinedest}%
+    \fi
+    %
+    % Also double the backslashes in the display string.
+    {\activebackslashdouble \xdef\pdfoutlinetext{#1}%
+     \backslashparens\pdfoutlinetext}%
+    %
+    \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}%
+  }
+  %
+  \def\pdfmakeoutlines{%
+    \begingroup
+      % Thanh's hack / proper braces in bookmarks
+      \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace
+      \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace
+      %
+      % Read toc silently, to get counts of subentries for \pdfoutline.
+      \def\numchapentry##1##2##3##4{%
+       \def\thischapnum{##2}%
+       \def\thissecnum{0}%
+       \def\thissubsecnum{0}%
+      }%
+      \def\numsecentry##1##2##3##4{%
+       \advancenumber{chap\thischapnum}%
+       \def\thissecnum{##2}%
+       \def\thissubsecnum{0}%
+      }%
+      \def\numsubsecentry##1##2##3##4{%
+       \advancenumber{sec\thissecnum}%
+       \def\thissubsecnum{##2}%
+      }%
+      \def\numsubsubsecentry##1##2##3##4{%
+       \advancenumber{subsec\thissubsecnum}%
+      }%
+      \def\thischapnum{0}%
+      \def\thissecnum{0}%
+      \def\thissubsecnum{0}%
+      %
+      % use \def rather than \let here because we redefine \chapentry et
+      % al. a second time, below.
+      \def\appentry{\numchapentry}%
+      \def\appsecentry{\numsecentry}%
+      \def\appsubsecentry{\numsubsecentry}%
+      \def\appsubsubsecentry{\numsubsubsecentry}%
+      \def\unnchapentry{\numchapentry}%
+      \def\unnsecentry{\numsecentry}%
+      \def\unnsubsecentry{\numsubsecentry}%
+      \def\unnsubsubsecentry{\numsubsubsecentry}%
+      \readdatafile{toc}%
+      %
+      % Read toc second time, this time actually producing the outlines.
+      % The `-' means take the \expnumber as the absolute number of
+      % subentries, which we calculated on our first read of the .toc above.
+      %
+      % We use the node names as the destinations.
+      \def\numchapentry##1##2##3##4{%
+        \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}%
+      \def\numsecentry##1##2##3##4{%
+        \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}%
+      \def\numsubsecentry##1##2##3##4{%
+        \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}%
+      \def\numsubsubsecentry##1##2##3##4{% count is always zero
+        \dopdfoutline{##1}{}{##3}{##4}}%
+      %
+      % PDF outlines are displayed using system fonts, instead of
+      % document fonts.  Therefore we cannot use special characters,
+      % since the encoding is unknown.  For example, the eogonek from
+      % Latin 2 (0xea) gets translated to a | character.  Info from
+      % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100.
+      %
+      % xx to do this right, we have to translate 8-bit characters to
+      % their "best" equivalent, based on the @documentencoding.  Right
+      % now, I guess we'll just let the pdf reader have its way.
+      \indexnofonts
+      \setupdatafile
+      \catcode`\\=\active \otherbackslash
+      \input \tocreadfilename
+    \endgroup
+  }
+  %
+  \def\skipspaces#1{\def\PP{#1}\def\D{|}%
+    \ifx\PP\D\let\nextsp\relax
+    \else\let\nextsp\skipspaces
+      \ifx\p\space\else\addtokens{\filename}{\PP}%
+        \advance\filenamelength by 1
+      \fi
+    \fi
+    \nextsp}
+  \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax}
+  \ifnum\pdftexversion < 14
+    \let \startlink \pdfannotlink
+  \else
+    \let \startlink \pdfstartlink
+  \fi
+  % make a live url in pdf output.
+  \def\pdfurl#1{%
+    \begingroup
+      % it seems we really need yet another set of dummies; have not
+      % 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
+      \makevalueexpandable
+      % do we want to go so far as to use \indexnofonts instead of just
+      % special-casing \var here?
+      \def\var##1{##1}%
+      %
+      \leavevmode\setcolor{\urlcolor}%
+      \startlink attr{/Border [0 0 0]}%
+        user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
+    \endgroup}
+  \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}}
+  \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+  \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks}
+  \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}}
+  \def\maketoks{%
+    \expandafter\poptoks\the\toksA|ENDTOKS|\relax
+    \ifx\first0\adn0
+    \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3
+    \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6
+    \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9
+    \else
+      \ifnum0=\countA\else\makelink\fi
+      \ifx\first.\let\next=\done\else
+        \let\next=\maketoks
+        \addtokens{\toksB}{\the\toksD}
+        \ifx\first,\addtokens{\toksB}{\space}\fi
+      \fi
+    \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+    \next}
+  \def\makelink{\addtokens{\toksB}%
+    {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
+  \def\pdflink#1{%
+    \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
+    \setcolor{\linkcolor}#1\endlink}
+  \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+\else
+  % non-pdf mode
+  \let\pdfmkdest = \gobble
+  \let\pdfurl = \gobble
+  \let\endlink = \relax
+  \let\setcolor = \gobble
+  \let\pdfsetcolor = \gobble
+  \let\pdfmakeoutlines = \relax
+\fi  % \ifx\pdfoutput
+
+
+\message{fonts,}
+
+% Change the current font style to #1, remembering it in \curfontstyle.
+% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in
+% italics, not bold italics.
+%
+\def\setfontstyle#1{%
+  \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd.
+  \csname ten#1\endcsname  % change the current font
+}
+
+% Select #1 fonts with the current style.
+%
+\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname}
+
+\def\rm{\fam=0 \setfontstyle{rm}}
+\def\it{\fam=\itfam \setfontstyle{it}}
+\def\sl{\fam=\slfam \setfontstyle{sl}}
+\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf}
+\def\tt{\fam=\ttfam \setfontstyle{tt}}
+
+% Unfortunately, we have to override this for titles and the like, since
+% in those cases "rm" is bold.  Sigh.
+\def\rmisbold{\rm\def\curfontstyle{bf}}
+
+% Texinfo sort of supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf.
+\newfam\sffam
+\def\sf{\fam=\sffam \setfontstyle{sf}}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+% We don't need math for this font style.
+\def\ttsl{\setfontstyle{ttsl}}
+
+
+% Default leading.
+\newdimen\textleading  \textleading = 13.2pt
+
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly.  There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}
+\def\strutheightpercent{.70833}
+\def\strutdepthpercent {.29167}
+%
+% can get a sort of poor man's double spacing by redefining this.
+\def\baselinefactor{1}
+%
+\def\setleading#1{%
+  \dimen0 = #1\relax
+  \normalbaselineskip = \baselinefactor\dimen0
+  \normallineskip = \lineskipfactor\normalbaselineskip
+  \normalbaselines
+  \setbox\strutbox =\hbox{%
+    \vrule width0pt height\strutheightpercent\baselineskip
+                    depth \strutdepthpercent \baselineskip
+  }%
+}
+
+% PDF CMaps.  See also LaTeX's t1.cmap.
+%
+% do nothing with this by default.
+\expandafter\let\csname cmapOT1\endcsname\gobble
+\expandafter\let\csname cmapOT1IT\endcsname\gobble
+\expandafter\let\csname cmapOT1TT\endcsname\gobble
+
+% if we are producing pdf, and we have \pdffontattr, then define cmaps.
+% (\pdffontattr was introduced many years ago, but people still run
+% older pdftex's; it's easy to conditionalize, so we do.)
+\ifpdf \ifx\pdffontattr\undefined \else
+  \begingroup
+    \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+    \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1-0)
+%%Title: (TeX-OT1-0 TeX OT1 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<23> <26> <0023>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+40 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+    }\endgroup
+  \expandafter\edef\csname cmapOT1\endcsname#1{%
+    \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+  }%
+%
+% \cmapOT1IT
+  \begingroup
+    \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+    \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1IT-0)
+%%Title: (TeX-OT1IT-0 TeX OT1IT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1IT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1IT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<25> <26> <0025>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+42 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<23> <0023>
+<24> <00A3>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+    }\endgroup
+  \expandafter\edef\csname cmapOT1IT\endcsname#1{%
+    \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+  }%
+%
+% \cmapOT1TT
+  \begingroup
+    \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+    \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1TT-0)
+%%Title: (TeX-OT1TT-0 TeX OT1TT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1TT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1TT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+5 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<21> <26> <0021>
+<28> <5F> <0028>
+<61> <7E> <0061>
+endbfrange
+32 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <2191>
+<0C> <2193>
+<0D> <0027>
+<0E> <00A1>
+<0F> <00BF>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<20> <2423>
+<27> <2019>
+<60> <2018>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+    }\endgroup
+  \expandafter\edef\csname cmapOT1TT\endcsname#1{%
+    \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+  }%
+\fi\fi
+
+
+% Set the font macro #1 to the font named #2, adding on the
+% specified font prefix (normally `cm').
+% #3 is the font's design size, #4 is a scale factor, #5 is the CMap
+% encoding (currently only OT1, OT1IT and OT1TT are allowed, pass
+% empty to omit).
+\def\setfont#1#2#3#4#5{%
+  \font#1=\fontprefix#2#3 scaled #4
+  \csname cmap#5\endcsname#1%
+}
+% This is what gets called when #5 of \setfont is empty.
+\let\cmap\gobble
+% emacs-page end of cmaps
+
+% Use cm as the default font prefix.
+% To specify the font prefix, you must define \fontprefix
+% before you read in texinfo.tex.
+\ifx\fontprefix\undefined
+\def\fontprefix{cm}
+\fi
+% Support font families that don't use the same naming scheme as CM.
+\def\rmshape{r}
+\def\rmbshape{bx}               %where the normal face is bold
+\def\bfshape{b}
+\def\bxshape{bx}
+\def\ttshape{tt}
+\def\ttbshape{tt}
+\def\ttslshape{sltt}
+\def\itshape{ti}
+\def\itbshape{bxti}
+\def\slshape{sl}
+\def\slbshape{bxsl}
+\def\sfshape{ss}
+\def\sfbshape{ss}
+\def\scshape{csc}
+\def\scbshape{csc}
+
+% Definitions for a main text size of 11pt.  This is the default in
+% Texinfo.
+%
+\def\definetextfontsizexi{%
+% Text fonts (11.2pt, magstep1).
+\def\textnominalsize{11pt}
+\edef\mainmagstep{\magstephalf}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+\def\textecsize{1095}
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstep1}{OT1}
+\setfont\deftt\ttshape{10}{\magstep1}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+\def\smallecsize{0900}
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+\def\smallerecsize{0800}
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\titleecsize{2074}
+
+% Chapter (and unnumbered) fonts (17.28pt).
+\def\chapnominalsize{17pt}
+\setfont\chaprm\rmbshape{12}{\magstep2}{OT1}
+\setfont\chapit\itbshape{10}{\magstep3}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep3}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT}
+\setfont\chapsf\sfbshape{17}{1000}{OT1}
+\let\chapbf=\chaprm
+\setfont\chapsc\scbshape{10}{\magstep3}{OT1}
+\font\chapi=cmmi12 scaled \magstep2
+\font\chapsy=cmsy10 scaled \magstep3
+\def\chapecsize{1728}
+
+% Section fonts (14.4pt).
+\def\secnominalsize{14pt}
+\setfont\secrm\rmbshape{12}{\magstep1}{OT1}
+\setfont\secit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep2}{OT1}
+\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\secsf\sfbshape{12}{\magstep1}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep2}{OT1}
+\font\seci=cmmi12 scaled \magstep1
+\font\secsy=cmsy10 scaled \magstep2
+\def\sececsize{1440}
+
+% Subsection fonts (13.15pt).
+\def\ssecnominalsize{13pt}
+\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1}
+\setfont\ssecit\itbshape{10}{1315}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1315}{OT1}
+\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1315}{OT1}
+\font\sseci=cmmi12 scaled \magstephalf
+\font\ssecsy=cmsy10 scaled 1315
+\def\ssececsize{1200}
+
+% Reduced fonts for @acro in text (10pt).
+\def\reducednominalsize{10pt}
+\setfont\reducedrm\rmshape{10}{1000}{OT1}
+\setfont\reducedtt\ttshape{10}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{1000}{OT1}
+\setfont\reducedit\itshape{10}{1000}{OT1IT}
+\setfont\reducedsl\slshape{10}{1000}{OT1}
+\setfont\reducedsf\sfshape{10}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{1000}{OT1}
+\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT}
+\font\reducedi=cmmi10
+\font\reducedsy=cmsy10
+\def\reducedecsize{1000}
+
+% reset the current fonts
+\textfonts
+\rm
+} % end of 11pt text font size definitions
+
+
+% Definitions to make the main text be 10pt Computer Modern, with
+% 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}
+\edef\mainmagstep{1000}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+\def\textecsize{1000}
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstephalf}{OT1}
+\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+\def\smallecsize{0900}
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+\def\smallerecsize{0800}
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\titleecsize{2074}
+
+% Chapter fonts (14.4pt).
+\def\chapnominalsize{14pt}
+\setfont\chaprm\rmbshape{12}{\magstep1}{OT1}
+\setfont\chapit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep2}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\chapsf\sfbshape{12}{\magstep1}{OT1}
+\let\chapbf\chaprm
+\setfont\chapsc\scbshape{10}{\magstep2}{OT1}
+\font\chapi=cmmi12 scaled \magstep1
+\font\chapsy=cmsy10 scaled \magstep2
+\def\chapecsize{1440}
+
+% Section fonts (12pt).
+\def\secnominalsize{12pt}
+\setfont\secrm\rmbshape{12}{1000}{OT1}
+\setfont\secit\itbshape{10}{\magstep1}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep1}{OT1}
+\setfont\sectt\ttbshape{12}{1000}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT}
+\setfont\secsf\sfbshape{12}{1000}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep1}{OT1}
+\font\seci=cmmi12
+\font\secsy=cmsy10 scaled \magstep1
+\def\sececsize{1200}
+
+% Subsection fonts (10pt).
+\def\ssecnominalsize{10pt}
+\setfont\ssecrm\rmbshape{10}{1000}{OT1}
+\setfont\ssecit\itbshape{10}{1000}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1000}{OT1}
+\setfont\ssectt\ttbshape{10}{1000}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT}
+\setfont\ssecsf\sfbshape{10}{1000}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1000}{OT1}
+\font\sseci=cmmi10
+\font\ssecsy=cmsy10
+\def\ssececsize{1000}
+
+% Reduced fonts for @acro in text (9pt).
+\def\reducednominalsize{9pt}
+\setfont\reducedrm\rmshape{9}{1000}{OT1}
+\setfont\reducedtt\ttshape{9}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{900}{OT1}
+\setfont\reducedit\itshape{9}{1000}{OT1IT}
+\setfont\reducedsl\slshape{9}{1000}{OT1}
+\setfont\reducedsf\sfshape{9}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{900}{OT1}
+\setfont\reducedttsl\ttslshape{10}{900}{OT1TT}
+\font\reducedi=cmmi9
+\font\reducedsy=cmsy9
+\def\reducedecsize{0900}
+
+% reduce space between paragraphs
+\divide\parskip by 2
+
+% reset the current fonts
+\textfonts
+\rm
+} % end of 10pt text font size definitions
+
+
+% 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}
+%
+\parseargdef\fonttextsize{%
+  \def\textsizearg{#1}%
+  \wlog{doing @fonttextsize \textsizearg}%
+  %
+  % 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
+  \else
+    \errhelp=\EMsimple
+    \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'}
+  \fi\fi
+ \endgroup
+}
+
+
+% In order for the font changes to affect most math symbols and letters,
+% we have to define the \textfont of the standard families.  Since
+% texinfo doesn't allow for producing subscripts and superscripts except
+% in the main text, we don't bother to reset \scriptfont and
+% \scriptscriptfont (which would also require loading a lot more fonts).
+%
+\def\resetmathfonts{%
+  \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy
+  \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf
+  \textfont\ttfam=\tentt \textfont\sffam=\tensf
+}
+
+% The font-changing commands redefine the meanings of \tenSTYLE, instead
+% of just \STYLE.  We do this because \STYLE needs to also set the
+% current \fam for math mode.  Our \STYLE (e.g., \rm) commands hardwire
+% \tenSTYLE to set the current font.
+%
+% Each font-changing command also sets the names \lsize (one size lower)
+% and \lllsize (three sizes lower).  These relative commands are used in
+% the LaTeX logo and acronyms.
+%
+% This all needs generalizing, badly.
+%
+\def\textfonts{%
+  \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+  \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+  \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
+  \let\tenttsl=\textttsl
+  \def\curfontsize{text}%
+  \def\lsize{reduced}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{\textleading}}
+\def\titlefonts{%
+  \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
+  \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
+  \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
+  \let\tenttsl=\titlettsl
+  \def\curfontsize{title}%
+  \def\lsize{chap}\def\lllsize{subsec}%
+  \resetmathfonts \setleading{25pt}}
+\def\titlefont#1{{\titlefonts\rmisbold #1}}
+\def\chapfonts{%
+  \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+  \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+  \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
+  \let\tenttsl=\chapttsl
+  \def\curfontsize{chap}%
+  \def\lsize{sec}\def\lllsize{text}%
+  \resetmathfonts \setleading{19pt}}
+\def\secfonts{%
+  \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+  \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+  \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
+  \let\tenttsl=\secttsl
+  \def\curfontsize{sec}%
+  \def\lsize{subsec}\def\lllsize{reduced}%
+  \resetmathfonts \setleading{16pt}}
+\def\subsecfonts{%
+  \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+  \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+  \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
+  \let\tenttsl=\ssecttsl
+  \def\curfontsize{ssec}%
+  \def\lsize{text}\def\lllsize{small}%
+  \resetmathfonts \setleading{15pt}}
+\let\subsubsecfonts = \subsecfonts
+\def\reducedfonts{%
+  \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl
+  \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc
+  \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy
+  \let\tenttsl=\reducedttsl
+  \def\curfontsize{reduced}%
+  \def\lsize{small}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{10.5pt}}
+\def\smallfonts{%
+  \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl
+  \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc
+  \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy
+  \let\tenttsl=\smallttsl
+  \def\curfontsize{small}%
+  \def\lsize{smaller}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{10.5pt}}
+\def\smallerfonts{%
+  \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl
+  \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc
+  \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy
+  \let\tenttsl=\smallerttsl
+  \def\curfontsize{smaller}%
+  \def\lsize{smaller}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{9.5pt}}
+
+% Fonts for short table of contents.
+\setfont\shortcontrm\rmshape{12}{1000}{OT1}
+\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1}  % no cmb12
+\setfont\shortcontsl\slshape{12}{1000}{OT1}
+\setfont\shortconttt\ttshape{12}{1000}{OT1TT}
+
+% Define these just so they can be easily changed for other fonts.
+\def\angleleft{$\langle$}
+\def\angleright{$\rangle$}
+
+% Set the fonts to use with the @small... environments.
+\let\smallexamplefonts = \smallfonts
+
+% About \smallexamplefonts.  If we use \smallfonts (9pt), @smallexample
+% can fit this many characters:
+%   8.5x11=86   smallbook=72  a4=90  a5=69
+% If we use \scriptfonts (8pt), then we can fit this many characters:
+%   8.5x11=90+  smallbook=80  a4=90+  a5=77
+% For me, subjectively, the few extra characters that fit aren't worth
+% the additional smallness of 8pt.  So I'm making the default 9pt.
+%
+% By the way, for comparison, here's what fits with @example (10pt):
+%   8.5x11=71  smallbook=60  a4=75  a5=58
+% --karl, 24jan03.
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\definetextfontsizexi
+
+
+\message{markup,}
+
+% Check if we are currently using a typewriter font.  Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+%
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+
+% Markup style infrastructure.  \defmarkupstylesetup\INITMACRO will
+% define and register \INITMACRO to be called on markup style changes.
+% \INITMACRO can check \currentmarkupstyle for the innermost
+% style and the set of \ifmarkupSTYLE switches for all styles
+% currently in effect.
+\newif\ifmarkupvar
+\newif\ifmarkupsamp
+\newif\ifmarkupkey
+%\newif\ifmarkupfile % @file == @samp.
+%\newif\ifmarkupoption % @option == @samp.
+\newif\ifmarkupcode
+\newif\ifmarkupkbd
+%\newif\ifmarkupenv % @env == @code.
+%\newif\ifmarkupcommand % @command == @code.
+\newif\ifmarkuptex % @tex (and part of @math, for now).
+\newif\ifmarkupexample
+\newif\ifmarkupverb
+\newif\ifmarkupverbatim
+
+\let\currentmarkupstyle\empty
+
+\def\setupmarkupstyle#1{%
+  \csname markup#1true\endcsname
+  \def\currentmarkupstyle{#1}%
+  \markupstylesetup
+}
+
+\let\markupstylesetup\empty
+
+\def\defmarkupstylesetup#1{%
+  \expandafter\def\expandafter\markupstylesetup
+    \expandafter{\markupstylesetup #1}%
+  \def#1%
+}
+
+% Markup style setup for left and right quotes.
+\defmarkupstylesetup\markupsetuplq{%
+  \expandafter\let\expandafter \temp \csname markupsetuplq\currentmarkupstyle\endcsname
+  \ifx\temp\relax \markupsetuplqdefault \else \temp \fi
+}
+
+\defmarkupstylesetup\markupsetuprq{%
+  \expandafter\let\expandafter \temp \csname markupsetuprq\currentmarkupstyle\endcsname
+  \ifx\temp\relax \markupsetuprqdefault \else \temp \fi
+}
+
+{
+\catcode`\'=\active
+\catcode`\`=\active
+
+\gdef\markupsetuplqdefault{\let`\lq}
+\gdef\markupsetuprqdefault{\let'\rq}
+
+\gdef\markupsetcodequoteleft{\let`\codequoteleft}
+\gdef\markupsetcodequoteright{\let'\codequoteright}
+
+\gdef\markupsetnoligaturesquoteleft{\let`\noligaturesquoteleft}
+}
+
+\let\markupsetuplqcode \markupsetcodequoteleft
+\let\markupsetuprqcode \markupsetcodequoteright
+\let\markupsetuplqexample \markupsetcodequoteleft
+\let\markupsetuprqexample \markupsetcodequoteright
+\let\markupsetuplqverb \markupsetcodequoteleft
+\let\markupsetuprqverb \markupsetcodequoteright
+\let\markupsetuplqverbatim \markupsetcodequoteleft
+\let\markupsetuprqverbatim \markupsetcodequoteright
+
+\let\markupsetuplqsamp \markupsetnoligaturesquoteleft
+\let\markupsetuplqkbd \markupsetnoligaturesquoteleft
+
+% Allow an option to not replace quotes with a regular directed right
+% quote/apostrophe (char 0x27), but instead use the undirected quote
+% 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.
+%
+\def\codequoteright{%
+  \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax
+    \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
+      '%
+    \else \char'15 \fi
+  \else \char'15 \fi
+}
+%
+% 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 SETtxicodequotebacktick\endcsname\relax
+    \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
+      % [Knuth] pp. 380,381,391
+      % \relax disables Spanish ligatures ?` and !` of \tt font.
+      \relax`%
+    \else \char'22 \fi
+  \else \char'22 \fi
+}
+
+% [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font.
+\def\noligaturesquoteleft{\relax\lq}
+
+% Count depth in font-changes, for error checks
+\newcount\fontdepth \fontdepth=0
+
+%% Add scribe-like font environments, plus @l for inline lisp (usually sans
+%% serif) and @ii for TeX italic
+
+% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
+% unless the following character is such as not to need one.
+\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else
+                    \ptexslash\fi\fi\fi}
+\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx}
+\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally uses \ttsl.
+% @var is set to this for defun arguments.
+\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx}
+
+% @cite is like \smartslanted except unconditionally use \sl.  We never want
+% ttsl for book titles, do we?
+\def\cite#1{{\sl #1}\futurelet\next\smartitalicx}
+
+\let\i=\smartitalic
+\let\slanted=\smartslanted
+\def\var#1{{\setupmarkupstyle{var}\smartslanted{#1}}}
+\let\dfn=\smartslanted
+\let\emph=\smartitalic
+
+% Explicit font changes: @r, @sc, undocumented @ii.
+\def\r#1{{\rm #1}}              % roman font
+\def\sc#1{{\smallcaps#1}}       % smallcaps font
+\def\ii#1{{\it #1}}             % italic font
+
+% @b, explicit bold.  Also @strong.
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% @sansserif, explicit sans.
+\def\sansserif#1{{\sf #1}}
+
+% We can't just use \exhyphenpenalty, because that only has effect at
+% the end of a paragraph.  Restore normal hyphenation at the end of the
+% group within which \nohyphenation is presumably called.
+%
+\def\nohyphenation{\hyphenchar\font = -1  \aftergroup\restorehyphenation}
+\def\restorehyphenation{\hyphenchar\font = `- }
+
+% Set sfcode to normal for the chars that usually have another value.
+% Can't use plain's \frenchspacing because it uses the `\x notation, and
+% sometimes \x has an active definition that messes things up.
+%
+\catcode`@=11
+  \def\plainfrenchspacing{%
+    \sfcode\dotChar  =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m
+    \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m
+    \def\endofsentencespacefactor{1000}% for @. and friends
+  }
+  \def\plainnonfrenchspacing{%
+    \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000
+    \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250
+    \def\endofsentencespacefactor{3000}% for @. and friends
+  }
+\catcode`@=\other
+\def\endofsentencespacefactor{3000}% default
+
+% @t, explicit typewriter.
+\def\t#1{%
+  {\tt \rawbackslash \plainfrenchspacing #1}%
+  \null
+}
+
+% @samp.
+\def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}}
+
+% definition of @key that produces a lozenge.  Doesn't adjust to text size.
+%\setfont\keyrm\rmshape{8}{1000}{OT1}
+%\font\keysy=cmsy9
+%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
+%  \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+%    \vbox{\hrule\kern-0.4pt
+%     \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+%    \kern-0.4pt\hrule}%
+%  \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+
+% definition of @key with no lozenge.  If the current font is already
+% monospace, don't change it; that way, we respect @kbdinputstyle.  But
+% if it isn't monospace, then use \tt.
+%
+\def\key#1{{\setupmarkupstyle{key}%
+  \nohyphenation
+  \ifmonospace\else\tt\fi
+  #1}\null}
+
+% ctrl is no longer a Texinfo command.
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+% @file, @option are the same as @samp.
+\let\file=\samp
+\let\option=\samp
+
+% @code is a modification of @t,
+% which makes spaces the same size as normal in the surrounding text.
+\def\tclose#1{%
+  {%
+    % Change normal interword space to be same as for the current font.
+    \spaceskip = \fontdimen2\font
+    %
+    % Switch to typewriter.
+    \tt
+    %
+    % But `\ ' produces the large typewriter interword space.
+    \def\ {{\spaceskip = 0pt{} }}%
+    %
+    % Turn off hyphenation.
+    \nohyphenation
+    %
+    \rawbackslash
+    \plainfrenchspacing
+    #1%
+  }%
+  \null
+}
+
+% We *must* turn on hyphenation at `-' and `_' in @code.
+% Otherwise, it is too hard to avoid overfull hboxes
+% in the Emacs manual, the Library manual, etc.
+
+% Unfortunately, TeX uses one parameter (\hyphenchar) to control
+% both hyphenation at - and hyphenation within words.
+% We must therefore turn them both off (\tclose does that)
+% and arrange explicitly to hyphenate at a dash.
+%  -- rms.
+{
+  \catcode`\-=\active \catcode`\_=\active
+  \catcode`\'=\active \catcode`\`=\active
+  \global\let'=\rq \global\let`=\lq  % default definitions
+  %
+  \global\def\code{\begingroup
+    \setupmarkupstyle{code}%
+    % The following should really be moved into \setupmarkupstyle handlers.
+    \catcode\dashChar=\active  \catcode\underChar=\active
+    \ifallowcodebreaks
+     \let-\codedash
+     \let_\codeunder
+    \else
+     \let-\realdash
+     \let_\realunder
+    \fi
+    \codex
+  }
+}
+
+\def\realdash{-}
+\def\codedash{-\discretionary{}{}{}}
+\def\codeunder{%
+  % this is all so @math{@code{var_name}+1} can work.  In math mode, _
+  % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.)
+  % will therefore expand the active definition of _, which is us
+  % (inside @code that is), therefore an endless loop.
+  \ifusingtt{\ifmmode
+               \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_.
+             \else\normalunderscore \fi
+             \discretionary{}{}{}}%
+            {\_}%
+}
+\def\codex #1{\tclose{#1}\endgroup}
+
+% An additional complication: the above will allow breaks after, e.g.,
+% 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}
+\def\keywordfalse{false}
+
+\parseargdef\allowcodebreaks{%
+  \def\txiarg{#1}%
+  \ifx\txiarg\keywordtrue
+    \allowcodebreakstrue
+  \else\ifx\txiarg\keywordfalse
+    \allowcodebreaksfalse
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @allowcodebreaks option `\txiarg'}%
+  \fi\fi
+}
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+\def\kbd#1{{\setupmarkupstyle{kbd}\def\look{#1}\expandafter\kbdfoo\look??\par}}
+
+% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+%   `example' (@kbd uses ttsl only inside of @example and friends),
+%   or `code' (@kbd uses normal tty font always).
+\parseargdef\kbdinputstyle{%
+  \def\txiarg{#1}%
+  \ifx\txiarg\worddistinct
+    \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+  \else\ifx\txiarg\wordexample
+    \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+  \else\ifx\txiarg\wordcode
+    \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @kbdinputstyle option `\txiarg'}%
+  \fi\fi\fi
+}
+\def\worddistinct{distinct}
+\def\wordexample{example}
+\def\wordcode{code}
+
+% Default is `distinct'.
+\kbdinputstyle distinct
+
+\def\xkey{\key}
+\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
+\ifx\one\xkey\ifx\threex\three \key{#2}%
+\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
+\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi}
+
+% For @indicateurl, @env, @command quotes seem unnecessary, so use \code.
+\let\indicateurl=\code
+\let\env=\code
+\let\command=\code
+
+% @clicksequence{File @click{} Open ...}
+\def\clicksequence#1{\begingroup #1\endgroup}
+
+% @clickstyle @arrow   (by default)
+\parseargdef\clickstyle{\def\click{#1}}
+\def\click{\arrow}
+
+% @uref (abbreviation for `urlref') takes an optional (comma-separated)
+% second argument specifying the text to display and an optional third
+% arg as text to display instead of (rather than in addition to) the url
+% itself.  First (mandatory) arg is the url.  Perhaps eventually put in
+% a hypertex \special here.
+%
+\def\uref#1{\douref #1,,,\finish}
+\def\douref#1,#2,#3,#4\finish{\begingroup
+  \unsepspaces
+  \pdfurl{#1}%
+  \setbox0 = \hbox{\ignorespaces #3}%
+  \ifdim\wd0 > 0pt
+    \unhbox0 % third arg given, show only that
+  \else
+    \setbox0 = \hbox{\ignorespaces #2}%
+    \ifdim\wd0 > 0pt
+      \ifpdf
+        \unhbox0             % PDF: 2nd arg given, show only it
+      \else
+        \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url
+      \fi
+    \else
+      \code{#1}% only url given, so show it
+    \fi
+  \fi
+  \endlink
+\endgroup}
+
+% @url synonym for @uref, since that's how everyone uses it.
+%
+\let\url=\uref
+
+% rms does not like angle brackets --karl, 17may97.
+% So now @email is just like @uref, unless we are pdf.
+%
+%\def\email#1{\angleleft{\tt #1}\angleright}
+\ifpdf
+  \def\email#1{\doemail#1,,\finish}
+  \def\doemail#1,#2,#3\finish{\begingroup
+    \unsepspaces
+    \pdfurl{mailto:#1}%
+    \setbox0 = \hbox{\ignorespaces #2}%
+    \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi
+    \endlink
+  \endgroup}
+\else
+  \let\email=\uref
+\fi
+
+% Typeset a dimension, e.g., `in' or `pt'.  The only reason for the
+% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
+%
+\def\dmn#1{\thinspace #1}
+
+% @l was never documented to mean ``switch to the Lisp font'',
+% and it is not used as such in any manual I can find.  We need it for
+% Polish suppressed-l.  --karl, 22sep96.
+%\def\l#1{{\li #1}\null}
+
+% @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}%
+  \def\temp{#2}%
+  \ifx\temp\empty \else
+    \space ({\unsepspaces \ignorespaces \temp \unskip})%
+  \fi
+}
+
+% @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}%
+  \def\temp{#2}%
+  \ifx\temp\empty \else
+    \space ({\unsepspaces \ignorespaces \temp \unskip})%
+  \fi
+}
+
+
+\message{glyphs,}
+
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+%
+% Since these characters are used in examples, they should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+%
+\def\point{$\star$}
+\def\arrow{\leavevmode\raise.05ex\hbox to 1em{\hfil$\rightarrow$\hfil}}
+\def\result{\leavevmode\raise.05ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+\def\equiv{\leavevmode\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% The @error{} command.
+% Adapted from the TeXbook's \boxit.
+%
+\newbox\errorbox
+%
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \reducedsf error\kern-1.5pt}
+%
+\setbox\errorbox=\hbox to \dimen0{\hfil
+   \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+   \advance\hsize by -2\dimen2 % Rules.
+   \vbox{%
+      \hrule height\dimen2
+      \hbox{\vrule width\dimen2 \kern3pt          % Space to left of text.
+         \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+         \kern3pt\vrule width\dimen2}% Space to right.
+      \hrule height\dimen2}
+    \hfil}
+%
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
+% @pounds{} is a sterling sign, which Knuth put in the CM italic font.
+%
+\def\pounds{{\it\$}}
+
+% @euro{} comes from a separate font, depending on the current style.
+% We use the free feym* fonts from the eurosym package by Henrik
+% 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
+    % bold:
+    \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
+  \else
+    % regular:
+    \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
+  \fi
+  \thiseurofont
+}
+
+% Glyphs from the EC fonts.  We don't use \let for the aliases, because
+% sometimes we redefine the original macro, and the alias should reflect
+% the redefinition.
+%
+% Use LaTeX names for the Icelandic letters.
+\def\DH{{\ecfont \char"D0}} % Eth
+\def\dh{{\ecfont \char"F0}} % eth
+\def\TH{{\ecfont \char"DE}} % Thorn
+\def\th{{\ecfont \char"FE}} % thorn
+%
+\def\guillemetleft{{\ecfont \char"13}}
+\def\guillemotleft{\guillemetleft}
+\def\guillemetright{{\ecfont \char"14}}
+\def\guillemotright{\guillemetright}
+\def\guilsinglleft{{\ecfont \char"0E}}
+\def\guilsinglright{{\ecfont \char"0F}}
+\def\quotedblbase{{\ecfont \char"12}}
+\def\quotesinglbase{{\ecfont \char"0D}}
+%
+% This positioning is not perfect (see the ogonek LaTeX package), but
+% we have the precomposed glyphs for the most common cases.  We put the
+% tests to use those glyphs in the single \ogonek macro so we have fewer
+% dummy definitions to worry about for index entries, etc.
+%
+% ogonek is also used with other letters in Lithuanian (IOU), but using
+% the precomposed glyphs for those is not so easy since they aren't in
+% the same EC font.
+\def\ogonek#1{{%
+  \def\temp{#1}%
+  \ifx\temp\macrocharA\Aogonek
+  \else\ifx\temp\macrochara\aogonek
+  \else\ifx\temp\macrocharE\Eogonek
+  \else\ifx\temp\macrochare\eogonek
+  \else
+    \ecfont \setbox0=\hbox{#1}%
+    \ifdim\ht0=1ex\accent"0C #1%
+    \else\ooalign{\unhbox0\crcr\hidewidth\char"0C \hidewidth}%
+    \fi
+  \fi\fi\fi\fi
+  }%
+}
+\def\Aogonek{{\ecfont \char"81}}\def\macrocharA{A}
+\def\aogonek{{\ecfont \char"A1}}\def\macrochara{a}
+\def\Eogonek{{\ecfont \char"86}}\def\macrocharE{E}
+\def\eogonek{{\ecfont \char"A6}}\def\macrochare{e}
+%
+% Use the ec* fonts (cm-super in outline format) for non-CM glyphs.
+\def\ecfont{%
+  % We can't distinguish serif/sans and italic/slanted, but this
+  % is used for crude hacks anyway (like adding French and German
+  % quotes to documents typeset with CM, where we lose kerning), so
+  % hopefully nobody will notice/care.
+  \edef\ecsize{\csname\curfontsize ecsize\endcsname}%
+  \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}%
+  \ifx\curfontstyle\bfstylename
+    % bold:
+    \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
+  \else
+    % regular:
+    \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
+  \fi
+  \thisecfont
+}
+
+% @registeredsymbol - R in a circle.  The font for the R should really
+% be smaller yet, but lllsize is the best we can do for now.
+% Adapted from the plain.tex definition of \copyright.
+%
+\def\registeredsymbol{%
+  $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}%
+               \hfil\crcr\Orb}}%
+    }$%
+}
+
+% @textdegree - the normal degrees sign.
+%
+\def\textdegree{$^\circ$}
+
+% 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
+
+% Quotes.
+\chardef\quotedblleft="5C
+\chardef\quotedblright=`\"
+\chardef\quoteleft=`\`
+\chardef\quoteright=`\'
+
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page.  Must do @settitle before @titlepage.
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+% Do an implicit @contents or @shortcontents after @end titlepage if the
+% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage.
+%
+\newif\ifsetcontentsaftertitlepage
+ \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue
+\newif\ifsetshortcontentsaftertitlepage
+ \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
+
+\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+        \endgroup\page\hbox{}\page}
+
+\envdef\titlepage{%
+  % Open one extra group, as we want to close it in the middle of \Etitlepage.
+  \begingroup
+    \parindent=0pt \textfonts
+    % Leave some space at the very top of the page.
+    \vglue\titlepagetopglue
+    % No rule at page bottom unless we print one at the top with @title.
+    \finishedtitlepagetrue
+    %
+    % Most title ``pages'' are actually two pages long, with space
+    % at the top of the second.  We don't want the ragged left on the second.
+    \let\oldpage = \page
+    \def\page{%
+      \iffinishedtitlepage\else
+        \finishtitlepage
+      \fi
+      \let\page = \oldpage
+      \page
+      \null
+    }%
+}
+
+\def\Etitlepage{%
+    \iffinishedtitlepage\else
+       \finishtitlepage
+    \fi
+    % It is important to do the page break before ending the group,
+    % because the headline and footline are only empty inside the group.
+    % If we use the new definition of \page, we always get a blank page
+    % after the title page, which we certainly don't want.
+    \oldpage
+  \endgroup
+  %
+  % Need this before the \...aftertitlepage checks so that if they are
+  % in effect the toc pages will come out with page numbers.
+  \HEADINGSon
+  %
+  % If they want short, they certainly want long too.
+  \ifsetshortcontentsaftertitlepage
+    \shortcontents
+    \contents
+    \global\let\shortcontents = \relax
+    \global\let\contents = \relax
+  \fi
+  %
+  \ifsetcontentsaftertitlepage
+    \contents
+    \global\let\contents = \relax
+    \global\let\shortcontents = \relax
+  \fi
+}
+
+\def\finishtitlepage{%
+  \vskip4pt \hrule height 2pt width \hsize
+  \vskip\titlepagebottomglue
+  \finishedtitlepagetrue
+}
+
+%%% Macros to be used within @titlepage:
+
+\let\subtitlerm=\tenrm
+\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
+
+\parseargdef\title{%
+  \checkenv\titlepage
+  \leftline{\titlefonts\rmisbold #1}
+  % print a rule at the page bottom also.
+  \finishedtitlepagefalse
+  \vskip4pt \hrule height 4pt width \hsize \vskip4pt
+}
+
+\parseargdef\subtitle{%
+  \checkenv\titlepage
+  {\subtitlefont \rightline{#1}}%
+}
+
+% @author should come last, but may come many times.
+% It can also be used inside @quotation.
+%
+\parseargdef\author{%
+  \def\temp{\quotation}%
+  \ifx\thisenv\temp
+    \def\quotationauthor{#1}% printed in \Equotation.
+  \else
+    \checkenv\titlepage
+    \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi
+    {\secfonts\rmisbold \leftline{#1}}%
+  \fi
+}
+
+
+%%% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks\evenheadline    % headline on even pages
+\newtoks\oddheadline     % headline on odd pages
+\newtoks\evenfootline    % footline on even pages
+\newtoks\oddfootline     % footline on odd pages
+
+% Now make TeX use those variables
+\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+                            \else \the\evenheadline \fi}}
+\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+                            \else \the\evenfootline \fi}\HEADINGShook}
+\let\HEADINGShook=\relax
+
+% Commands to set those variables.
+% For example, this is what  @headings on  does
+% @evenheading @thistitle|@thispage|@thischapter
+% @oddheading @thischapter|@thispage|@thistitle
+% @evenfooting @thisfile||
+% @oddfooting ||@thisfile
+
+
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish}
+\def\evenheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish}
+\def\oddheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
+
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish}
+\def\evenfootingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish}
+\def\oddfootingyyy #1\|#2\|#3\|#4\finish{%
+  \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
+  %
+  % Leave some space for the footline.  Hopefully ok to assume
+  % @evenfooting will not be used by itself.
+  \global\advance\pageheight by -12pt
+  \global\advance\vsize by -12pt
+}
+
+\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+
+% @evenheadingmarks top     \thischapter <- chapter at the top of a page
+% @evenheadingmarks bottom  \thischapter <- chapter at the bottom of a page
+%
+% The same set of arguments for:
+%
+% @oddheadingmarks
+% @evenfootingmarks
+% @oddfootingmarks
+% @everyheadingmarks
+% @everyfootingmarks
+
+\def\evenheadingmarks{\headingmarks{even}{heading}}
+\def\oddheadingmarks{\headingmarks{odd}{heading}}
+\def\evenfootingmarks{\headingmarks{even}{footing}}
+\def\oddfootingmarks{\headingmarks{odd}{footing}}
+\def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1}
+                          \headingmarks{odd}{heading}{#1} }
+\def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1}
+                          \headingmarks{odd}{footing}{#1} }
+% #1 = even/odd, #2 = heading/footing, #3 = top/bottom.
+\def\headingmarks#1#2#3 {%
+  \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname
+  \global\expandafter\let\csname get#1#2marks\endcsname \temp
+}
+
+\everyheadingmarks bottom
+\everyfootingmarks bottom
+
+% @headings double      turns headings on for double-sided printing.
+% @headings single      turns headings on for single-sided printing.
+% @headings off         turns them off.
+% @headings on          same as @headings double, retained for compatibility.
+% @headings after       turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
+% @headings singleafter turns on single-sided headings after this page.
+% By default, they are off at the start of a document,
+% and turned `on' after @end titlepage.
+
+\def\headings #1 {\csname HEADINGS#1\endcsname}
+
+\def\HEADINGSoff{%
+\global\evenheadline={\hfil} \global\evenfootline={\hfil}
+\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
+\HEADINGSoff
+% When we turn headings on, set the page number to 1.
+% For double-sided printing, put current file name in lower left corner,
+% chapter name on inside top of right hand pages, document
+% title on inside top of left hand pages, and page numbers on outside top
+% edge of all pages.
+\def\HEADINGSdouble{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+\let\contentsalignmacro = \chappager
+
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+\def\HEADINGSon{\HEADINGSdouble}
+
+\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+\let\HEADINGSdoubleafter=\HEADINGSafter
+\def\HEADINGSdoublex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+
+\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+\def\HEADINGSsinglex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+
+% Subroutines used in generating headings
+% This produces Day Month Year style of output.
+% Only define if not already defined, in case a txi-??.tex file has set
+% up a different format (e.g., txi-cs.tex does this).
+\ifx\today\undefined
+\def\today{%
+  \number\day\space
+  \ifcase\month
+  \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr
+  \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug
+  \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec
+  \fi
+  \space\number\year}
+\fi
+
+% @settitle line...  specifies the title of the document, for headings.
+% It generates no output of its own.
+\def\thistitle{\putwordNoTitle}
+\def\settitle{\parsearg{\gdef\thistitle}}
+
+
+\message{tables,}
+% Tables -- @table, @ftable, @vtable, @item(x).
+
+% default indentation of table text
+\newdimen\tableindent \tableindent=.8in
+% default indentation of @itemize and @enumerate text
+\newdimen\itemindent  \itemindent=.3in
+% margin between end of table item and start of table text.
+\newdimen\itemmargin  \itemmargin=.1in
+
+% used internally for \itemindent minus \itemmargin
+\newdimen\itemmax
+
+% Note @table, @ftable, and @vtable define @item, @itemx, etc., with
+% these defs.
+% They also define \itemindex
+% to index the item name in whatever manner is desired (perhaps none).
+
+\newif\ifitemxneedsnegativevskip
+
+\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
+
+\def\internalBitem{\smallbreak \parsearg\itemzzz}
+\def\internalBitemx{\itemxpar \parsearg\itemzzz}
+
+\def\itemzzz #1{\begingroup %
+  \advance\hsize by -\rightskip
+  \advance\hsize by -\tableindent
+  \setbox0=\hbox{\itemindicate{#1}}%
+  \itemindex{#1}%
+  \nobreak % This prevents a break before @itemx.
+  %
+  % If the item text does not fit in the space we have, put it on a line
+  % by itself, and do not allow a page break either before or after that
+  % line.  We do not start a paragraph here because then if the next
+  % command is, e.g., @kindex, the whatsit would get put into the
+  % horizontal list on a line by itself, resulting in extra blank space.
+  \ifdim \wd0>\itemmax
+    %
+    % Make this a paragraph so we get the \parskip glue and wrapping,
+    % but leave it ragged-right.
+    \begingroup
+      \advance\leftskip by-\tableindent
+      \advance\hsize by\tableindent
+      \advance\rightskip by0pt plus1fil
+      \leavevmode\unhbox0\par
+    \endgroup
+    %
+    % We're going to be starting a paragraph, but we don't want the
+    % \parskip glue -- logically it's part of the @item we just started.
+    \nobreak \vskip-\parskip
+    %
+    % Stop a page break at the \parskip glue coming up.  However, if
+    % what follows is an environment such as @example, there will be no
+    % \parskip glue; then the negative vskip we just inserted would
+    % 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
+  \else
+    % The item text fits into the space.  Start a paragraph, so that the
+    % following text (if any) will end up on the same line.
+    \noindent
+    % Do this with kerns and \unhbox so that if there is a footnote in
+    % the item text, it can migrate to the main vertical list and
+    % eventually be printed.
+    \nobreak\kern-\tableindent
+    \dimen0 = \itemmax  \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0
+    \unhbox0
+    \nobreak\kern\dimen0
+    \endgroup
+    \itemxneedsnegativevskiptrue
+  \fi
+}
+
+\def\item{\errmessage{@item while not in a list environment}}
+\def\itemx{\errmessage{@itemx while not in a list environment}}
+
+% @table, @ftable, @vtable.
+\envdef\table{%
+  \let\itemindex\gobble
+  \tablecheck{table}%
+}
+\envdef\ftable{%
+  \def\itemindex ##1{\doind {fn}{\code{##1}}}%
+  \tablecheck{ftable}%
+}
+\envdef\vtable{%
+  \def\itemindex ##1{\doind {vr}{\code{##1}}}%
+  \tablecheck{vtable}%
+}
+\def\tablecheck#1{%
+  \ifnum \the\catcode`\^^M=\active
+    \endgroup
+    \errmessage{This command won't work in this context; perhaps the problem is
+      that we are \inenvironment\thisenv}%
+    \def\next{\doignore{#1}}%
+  \else
+    \let\next\tablex
+  \fi
+  \next
+}
+\def\tablex#1{%
+  \def\itemindicate{#1}%
+  \parsearg\tabley
+}
+\def\tabley#1{%
+  {%
+    \makevalueexpandable
+    \edef\temp{\noexpand\tablez #1\space\space\space}%
+    \expandafter
+  }\temp \endtablez
+}
+\def\tablez #1 #2 #3 #4\endtablez{%
+  \aboveenvbreak
+  \ifnum 0#1>0 \advance \leftskip by #1\mil \fi
+  \ifnum 0#2>0 \tableindent=#2\mil \fi
+  \ifnum 0#3>0 \advance \rightskip by #3\mil \fi
+  \itemmax=\tableindent
+  \advance \itemmax by -\itemmargin
+  \advance \leftskip by \tableindent
+  \exdentamount=\tableindent
+  \parindent = 0pt
+  \parskip = \smallskipamount
+  \ifdim \parskip=0pt \parskip=2pt \fi
+  \let\item = \internalBitem
+  \let\itemx = \internalBitemx
+}
+\def\Etable{\endgraf\afterenvbreak}
+\let\Eftable\Etable
+\let\Evtable\Etable
+\let\Eitemize\Etable
+\let\Eenumerate\Etable
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\envdef\itemize{\parsearg\doitemize}
+
+\def\doitemize#1{%
+  \aboveenvbreak
+  \itemmax=\itemindent
+  \advance\itemmax by -\itemmargin
+  \advance\leftskip by \itemindent
+  \exdentamount=\itemindent
+  \parindent=0pt
+  \parskip=\smallskipamount
+  \ifdim\parskip=0pt \parskip=2pt \fi
+  %
+  % Try typesetting the item mark that if the document erroneously says
+  % something like @itemize @samp (intending @table), there's an error
+  % right away at the @itemize.  It's not the best error message in the
+  % world, but it's better than leaving it to the @item.  This means if
+  % the user wants an empty mark, they have to say @w{} not just @w.
+  \def\itemcontents{#1}%
+  \setbox0 = \hbox{\itemcontents}%
+  %
+  % @itemize with no arg is equivalent to @itemize @bullet.
+  \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
+  %
+  \let\item=\itemizeitem
+}
+
+% Definition of @item while inside @itemize and @enumerate.
+%
+\def\itemizeitem{%
+  \advance\itemno by 1  % for enumerations
+  {\let\par=\endgraf \smallbreak}% reasonable place to break
+  {%
+   % If the document has an @itemize directly after a section title, a
+   % \nobreak will be last on the list, and \sectionheading will have
+   % done a \vskip-\parskip.  In that case, we don't want to zero
+   % parskip, or the item text will crash with the heading.  On the
+   % other hand, when there is normal text preceding the item (as there
+   % usually is), we do want to zero parskip, or there would be too much
+   % space.  In that case, we won't have a \nobreak before.  At least
+   % that's the theory.
+   \ifnum\lastpenalty<10000 \parskip=0in \fi
+   \noindent
+   \hbox to 0pt{\hss \itemcontents \kern\itemmargin}%
+   %
+   \vadjust{\penalty 1200}}% not good to break after first line of item.
+  \flushcr
+}
+
+% \splitoff TOKENS\endmark defines \first to be the first token in
+% TOKENS, and \rest to be the remainder.
+%
+\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+
+% Allow an optional argument of an uppercase letter, lowercase letter,
+% or number, to specify the first label in the enumerated list.  No
+% argument is the same as `1'.
+%
+\envparseargdef\enumerate{\enumeratey #1  \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+  % If we were given no argument, pretend we were given `1'.
+  \def\thearg{#1}%
+  \ifx\thearg\empty \def\thearg{1}\fi
+  %
+  % Detect if the argument is a single token.  If so, it might be a
+  % letter.  Otherwise, the only valid thing it can be is a number.
+  % (We will always have one token, because of the test we just made.
+  % This is a good thing, since \splitoff doesn't work given nothing at
+  % all -- the first parameter is undelimited.)
+  \expandafter\splitoff\thearg\endmark
+  \ifx\rest\empty
+    % Only one token in the argument.  It could still be anything.
+    % A ``lowercase letter'' is one whose \lccode is nonzero.
+    % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+    %   not equal to itself.
+    % Otherwise, we assume it's a number.
+    %
+    % We need the \relax at the end of the \ifnum lines to stop TeX from
+    % continuing to look for a <number>.
+    %
+    \ifnum\lccode\expandafter`\thearg=0\relax
+      \numericenumerate % a number (we hope)
+    \else
+      % It's a letter.
+      \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+        \lowercaseenumerate % lowercase letter
+      \else
+        \uppercaseenumerate % uppercase letter
+      \fi
+    \fi
+  \else
+    % Multiple tokens in the argument.  We hope it's a number.
+    \numericenumerate
+  \fi
+}
+
+% An @enumerate whose labels are integers.  The starting integer is
+% given in \thearg.
+%
+\def\numericenumerate{%
+  \itemno = \thearg
+  \startenumeration{\the\itemno}%
+}
+
+% The starting (lowercase) letter is in \thearg.
+\def\lowercaseenumerate{%
+  \itemno = \expandafter`\thearg
+  \startenumeration{%
+    % Be sure we're not beyond the end of the alphabet.
+    \ifnum\itemno=0
+      \errmessage{No more lowercase letters in @enumerate; get a bigger
+                  alphabet}%
+    \fi
+    \char\lccode\itemno
+  }%
+}
+
+% The starting (uppercase) letter is in \thearg.
+\def\uppercaseenumerate{%
+  \itemno = \expandafter`\thearg
+  \startenumeration{%
+    % Be sure we're not beyond the end of the alphabet.
+    \ifnum\itemno=0
+      \errmessage{No more uppercase letters in @enumerate; get a bigger
+                  alphabet}
+    \fi
+    \char\uccode\itemno
+  }%
+}
+
+% Call \doitemize, adding a period to the first argument and supplying the
+% common last two arguments.  Also subtract one from the initial value in
+% \itemno, since @item increments \itemno.
+%
+\def\startenumeration#1{%
+  \advance\itemno by -1
+  \doitemize{#1.}\flushcr
+}
+
+% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+% to @enumerate.
+%
+\def\alphaenumerate{\enumerate{a}}
+\def\capsenumerate{\enumerate{A}}
+\def\Ealphaenumerate{\Eenumerate}
+\def\Ecapsenumerate{\Eenumerate}
+
+
+% @multitable macros
+% Amy Hendrickson, 8/18/94, 3/6/96
+%
+% @multitable ... @end multitable will make as many columns as desired.
+% Contents of each column will wrap at width given in preamble.  Width
+% can be specified either with sample text given in a template line,
+% or in percent of \hsize, the current width of text on page.
+
+% Table can continue over pages but will only break between lines.
+
+% To make preamble:
+%
+% Either define widths of columns in terms of percent of \hsize:
+%   @multitable @columnfractions .25 .3 .45
+%   @item ...
+%
+%   Numbers following @columnfractions are the percent of the total
+%   current hsize to be used for each column. You may use as many
+%   columns as desired.
+
+
+% Or use a template:
+%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+%   @item ...
+%   using the widest term desired in each column.
+
+% Each new table line starts with @item, each subsequent new column
+% starts with @tab. Empty columns may be produced by supplying @tab's
+% with nothing between them for as many times as empty columns are needed,
+% ie, @tab@tab@tab will produce two empty columns.
+
+% @item, @tab do not need to be on their own lines, but it will not hurt
+% if they are.
+
+% Sample multitable:
+
+%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+%   @item first col stuff @tab second col stuff @tab third col
+%   @item
+%   first col stuff
+%   @tab
+%   second col stuff
+%   @tab
+%   third col
+%   @item first col stuff @tab second col stuff
+%   @tab Many paragraphs of text may be used in any column.
+%
+%         They will wrap at the width determined by the template.
+%   @item@tab@tab This will be in third column.
+%   @end multitable
+
+% Default dimensions may be reset by user.
+% @multitableparskip is vertical space between paragraphs in table.
+% @multitableparindent is paragraph indent in table.
+% @multitablecolmargin is horizontal space to be left between columns.
+% @multitablelinespace is space to leave between table items, baseline
+%                                                            to baseline.
+%   0pt means it depends on current normal line spacing.
+%
+\newskip\multitableparskip
+\newskip\multitableparindent
+\newdimen\multitablecolspace
+\newskip\multitablelinespace
+\multitableparskip=0pt
+\multitableparindent=6pt
+\multitablecolspace=12pt
+\multitablelinespace=0pt
+
+% Macros used to set up halign preamble:
+%
+\let\endsetuptable\relax
+\def\xendsetuptable{\endsetuptable}
+\let\columnfractions\relax
+\def\xcolumnfractions{\columnfractions}
+\newif\ifsetpercent
+
+% #1 is the @columnfraction, usually a decimal number like .5, but might
+% be just 1.  We just use it, whatever it is.
+%
+\def\pickupwholefraction#1 {%
+  \global\advance\colcount by 1
+  \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}%
+  \setuptable
+}
+
+\newcount\colcount
+\def\setuptable#1{%
+  \def\firstarg{#1}%
+  \ifx\firstarg\xendsetuptable
+    \let\go = \relax
+  \else
+    \ifx\firstarg\xcolumnfractions
+      \global\setpercenttrue
+    \else
+      \ifsetpercent
+         \let\go\pickupwholefraction
+      \else
+         \global\advance\colcount by 1
+         \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a
+                   % separator; typically that is always in the input, anyway.
+         \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+      \fi
+    \fi
+    \ifx\go\pickupwholefraction
+      % Put the argument back for the \pickupwholefraction call, so
+      % we'll always have a period there to be parsed.
+      \def\go{\pickupwholefraction#1}%
+    \else
+      \let\go = \setuptable
+    \fi%
+  \fi
+  \go
+}
+
+% multitable-only commands.
+%
+% @headitem starts a heading row, which we typeset in bold.
+% Assignments have to be global since we are inside the implicit group
+% of an alignment entry.  \everycr resets \everytab so we don't have to
+% undo it ourselves.
+\def\headitemfont{\b}% for people to use in the template row; not changeable
+\def\headitem{%
+  \checkenv\multitable
+  \crcr
+  \global\everytab={\bf}% can't use \headitemfont since the parsing differs
+  \the\everytab % for the first item
+}%
+%
+% A \tab used to include \hskip1sp.  But then the space in a template
+% line is not enough.  That is bad.  So let's go back to just `&' until
+% we again encounter the problem the 1sp was intended to solve.
+%                                      --karl, nathan@acm.org, 20apr99.
+\def\tab{\checkenv\multitable &\the\everytab}%
+
+% @multitable ... @end multitable definitions:
+%
+\newtoks\everytab  % insert after every tab.
+%
+\envdef\multitable{%
+  \vskip\parskip
+  \startsavinginserts
+  %
+  % @item within a multitable starts a normal row.
+  % We use \def instead of \let so that if one of the multitable entries
+  % contains an @itemize, we don't choke on the \item (seen as \crcr aka
+  % \endtemplate) expanding \doitemize.
+  \def\item{\crcr}%
+  %
+  \tolerance=9500
+  \hbadness=9500
+  \setmultitablespacing
+  \parskip=\multitableparskip
+  \parindent=\multitableparindent
+  \overfullrule=0pt
+  \global\colcount=0
+  %
+  \everycr = {%
+    \noalign{%
+      \global\everytab={}%
+      \global\colcount=0 % Reset the column counter.
+      % Check for saved footnotes, etc.
+      \checkinserts
+      % Keeps underfull box messages off when table breaks over pages.
+      %\filbreak
+       % Maybe so, but it also creates really weird page breaks when the
+       % table breaks over pages. Wouldn't \vfil be better?  Wait until the
+       % problem manifests itself, so it can be fixed for real --karl.
+    }%
+  }%
+  %
+  \parsearg\domultitable
+}
+\def\domultitable#1{%
+  % To parse everything between @multitable and @item:
+  \setuptable#1 \endsetuptable
+  %
+  % This preamble sets up a generic column definition, which will
+  % be used as many times as user calls for columns.
+  % \vtop will set a single line and will also let text wrap and
+  % continue for many paragraphs if desired.
+  \halign\bgroup &%
+    \global\advance\colcount by 1
+    \multistrut
+    \vtop{%
+      % Use the current \colcount to find the correct column width:
+      \hsize=\expandafter\csname col\the\colcount\endcsname
+      %
+      % In order to keep entries from bumping into each other
+      % we will add a \leftskip of \multitablecolspace to all columns after
+      % the first one.
+      %
+      % If a template has been used, we will add \multitablecolspace
+      % to the width of each template entry.
+      %
+      % If the user has set preamble in terms of percent of \hsize we will
+      % use that dimension as the width of the column, and the \leftskip
+      % will keep entries from bumping into each other.  Table will start at
+      % left margin and final column will justify at right margin.
+      %
+      % Make sure we don't inherit \rightskip from the outer environment.
+      \rightskip=0pt
+      \ifnum\colcount=1
+       % The first column will be indented with the surrounding text.
+       \advance\hsize by\leftskip
+      \else
+       \ifsetpercent \else
+         % If user has not set preamble in terms of percent of \hsize
+         % we will advance \hsize by \multitablecolspace.
+         \advance\hsize by \multitablecolspace
+       \fi
+       % In either case we will make \leftskip=\multitablecolspace:
+      \leftskip=\multitablecolspace
+      \fi
+      % Ignoring space at the beginning and end avoids an occasional spurious
+      % blank line, when TeX decides to break the line at the space before the
+      % box from the multistrut, so the strut ends up on a line by itself.
+      % For example:
+      % @multitable @columnfractions .11 .89
+      % @item @code{#}
+      % @tab Legal holiday which is valid in major parts of the whole country.
+      % Is automatically provided with highlighting sequences respectively
+      % marking characters.
+      \noindent\ignorespaces##\unskip\multistrut
+    }\cr
+}
+\def\Emultitable{%
+  \crcr
+  \egroup % end the \halign
+  \global\setpercentfalse
+}
+
+\def\setmultitablespacing{%
+  \def\multistrut{\strut}% just use the standard line spacing
+  %
+  % Compute \multitablelinespace (if not defined by user) for use in
+  % \multitableparskip calculation.  We used define \multistrut based on
+  % this, but (ironically) that caused the spacing to be off.
+  % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
+\ifdim\multitablelinespace=0pt
+\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
+\global\advance\multitablelinespace by-\ht0
+\fi
+%% Test to see if parskip is larger than space between lines of
+%% table. If not, do nothing.
+%%        If so, set to same dimension as multitablelinespace.
+\ifdim\multitableparskip>\multitablelinespace
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+                                      %% than skip between lines in the table.
+\fi%
+\ifdim\multitableparskip=0pt
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+                                      %% than skip between lines in the table.
+\fi}
+
+
+\message{conditionals,}
+
+% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext,
+% @ifnotxml always succeed.  They currently do nothing; we don't
+% attempt to check whether the conditionals are properly nested.  But we
+% have to remember that they are conditionals, so that @end doesn't
+% attempt to close an environment group.
+%
+\def\makecond#1{%
+  \expandafter\let\csname #1\endcsname = \relax
+  \expandafter\let\csname iscond.#1\endcsname = 1
+}
+\makecond{iftex}
+\makecond{ifnotdocbook}
+\makecond{ifnothtml}
+\makecond{ifnotinfo}
+\makecond{ifnotplaintext}
+\makecond{ifnotxml}
+
+% Ignore @ignore, @ifhtml, @ifinfo, and the like.
+%
+\def\direntry{\doignore{direntry}}
+\def\documentdescription{\doignore{documentdescription}}
+\def\docbook{\doignore{docbook}}
+\def\html{\doignore{html}}
+\def\ifdocbook{\doignore{ifdocbook}}
+\def\ifhtml{\doignore{ifhtml}}
+\def\ifinfo{\doignore{ifinfo}}
+\def\ifnottex{\doignore{ifnottex}}
+\def\ifplaintext{\doignore{ifplaintext}}
+\def\ifxml{\doignore{ifxml}}
+\def\ignore{\doignore{ignore}}
+\def\menu{\doignore{menu}}
+\def\xml{\doignore{xml}}
+
+% Ignore text until a line `@end #1', keeping track of nested conditionals.
+%
+% A count to remember the depth of nesting.
+\newcount\doignorecount
+
+\def\doignore#1{\begingroup
+  % Scan in ``verbatim'' mode:
+  \obeylines
+  \catcode`\@ = \other
+  \catcode`\{ = \other
+  \catcode`\} = \other
+  %
+  % Make sure that spaces turn into tokens that match what \doignoretext wants.
+  \spaceisspace
+  %
+  % Count number of #1's that we've seen.
+  \doignorecount = 0
+  %
+  % Swallow text until we reach the matching `@end #1'.
+  \dodoignore{#1}%
+}
+
+{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source.
+  \obeylines %
+  %
+  \gdef\dodoignore#1{%
+    % #1 contains the command name as a string, e.g., `ifinfo'.
+    %
+    % Define a command to find the next `@end #1'.
+    \long\def\doignoretext##1^^M@end #1{%
+      \doignoretextyyy##1^^M@#1\_STOP_}%
+    %
+    % And this command to find another #1 command, at the beginning of a
+    % line.  (Otherwise, we would consider a line `@c @ifset', for
+    % example, to count as an @ifset for nesting.)
+    \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}%
+    %
+    % And now expand that command.
+    \doignoretext ^^M%
+  }%
+}
+
+\def\doignoreyyy#1{%
+  \def\temp{#1}%
+  \ifx\temp\empty                      % Nothing found.
+    \let\next\doignoretextzzz
+  \else                                        % Found a nested condition, ...
+    \advance\doignorecount by 1
+    \let\next\doignoretextyyy          % ..., look for another.
+    % If we're here, #1 ends with ^^M\ifinfo (for example).
+  \fi
+  \next #1% the token \_STOP_ is present just after this macro.
+}
+
+% We have to swallow the remaining "\_STOP_".
+%
+\def\doignoretextzzz#1{%
+  \ifnum\doignorecount = 0     % We have just found the outermost @end.
+    \let\next\enddoignore
+  \else                                % Still inside a nested condition.
+    \advance\doignorecount by -1
+    \let\next\doignoretext      % Look for the next @end.
+  \fi
+  \next
+}
+
+% Finish off ignored text.
+{ \obeylines%
+  % Ignore anything after the last `@end #1'; this matters in verbatim
+  % environments, where otherwise the newline after an ignored conditional
+  % would result in a blank line in the output.
+  \gdef\enddoignore#1^^M{\endgroup\ignorespaces}%
+}
+
+
+% @set VAR sets the variable VAR to an empty value.
+% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+%
+% Since we want to separate VAR from REST-OF-LINE (which might be
+% empty), we can't just use \parsearg; we have to insert a space of our
+% own to delimit the rest of the line, and then take it out again if we
+% didn't need it.
+% We rely on the fact that \parsearg sets \catcode`\ =10.
+%
+\parseargdef\set{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+  {%
+    \makevalueexpandable
+    \def\temp{#2}%
+    \edef\next{\gdef\makecsname{SET#1}}%
+    \ifx\temp\empty
+      \next{}%
+    \else
+      \setzzz#2\endsetzzz
+    \fi
+  }%
+}
+% Remove the trailing space \setxxx inserted.
+\def\setzzz#1 \endsetzzz{\next{#1}}
+
+% @clear VAR clears (i.e., unsets) the variable VAR.
+%
+\parseargdef\clear{%
+  {%
+    \makevalueexpandable
+    \global\expandafter\let\csname SET#1\endcsname=\relax
+  }%
+}
+
+% @value{foo} gets the text saved in variable foo.
+\def\value{\begingroup\makevalueexpandable\valuexxx}
+\def\valuexxx#1{\expandablevalue{#1}\endgroup}
+{
+  \catcode`\- = \active \catcode`\_ = \active
+  %
+  \gdef\makevalueexpandable{%
+    \let\value = \expandablevalue
+    % We don't want these characters active, ...
+    \catcode`\-=\other \catcode`\_=\other
+    % ..., but we might end up with active ones in the argument if
+    % we're called from @code, as @code{@value{foo-bar_}}, though.
+    % So \let them to their normal equivalents.
+    \let-\realdash \let_\normalunderscore
+  }
+}
+
+% We have this subroutine so that we can handle at least some @value's
+% properly in indexes (we call \makevalueexpandable in \indexdummies).
+% The command has to be fully expandable (if the variable is set), since
+% the result winds up in the index file.  This means that if the
+% variable's value contains other Texinfo commands, it's almost certain
+% it will fail (although perhaps we could fix that with sufficient work
+% to do a one-level expansion on the result, instead of complete).
+%
+\def\expandablevalue#1{%
+  \expandafter\ifx\csname SET#1\endcsname\relax
+    {[No value for ``#1'']}%
+    \message{Variable `#1', used in @value, is not set.}%
+  \else
+    \csname SET#1\endcsname
+  \fi
+}
+
+% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+% with @set.
+%
+% To get special treatment of `@end ifset,' call \makeond and the redefine.
+%
+\makecond{ifset}
+\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
+\def\doifset#1#2{%
+  {%
+    \makevalueexpandable
+    \let\next=\empty
+    \expandafter\ifx\csname SET#2\endcsname\relax
+      #1% If not set, redefine \next.
+    \fi
+    \expandafter
+  }\next
+}
+\def\ifsetfail{\doignore{ifset}}
+
+% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+% The `\else' inside the `\doifset' parameter is a trick to reuse the
+% above code: if the variable is not set, do nothing, if it is set,
+% then redefine \next to \ifclearfail.
+%
+\makecond{ifclear}
+\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
+\def\ifclearfail{\doignore{ifclear}}
+
+% @dircategory CATEGORY  -- specify a category of the dir file
+% which this file should belong to.  Ignore this in TeX.
+\let\dircategory=\comment
+
+% @defininfoenclose.
+\let\definfoenclose=\comment
+
+
+\message{indexing,}
+% Index generation facilities
+
+% Define \newwrite to be identical to plain tex's \newwrite
+% except not \outer, so it can be used within macros and \if's.
+\edef\newwrite{\makecsname{ptexnewwrite}}
+
+% \newindex {foo} defines an index named foo.
+% It automatically defines \fooindex such that
+% \fooindex ...rest of line... puts an entry in the index foo.
+% It also defines \fooindfile to be the number of the output channel for
+% the file that accumulates this index.  The file's extension is foo.
+% The name of an index should be no more than 2 characters long
+% for the sake of vms.
+%
+\def\newindex#1{%
+  \iflinks
+    \expandafter\newwrite \csname#1indfile\endcsname
+    \openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+  \fi
+  \expandafter\xdef\csname#1index\endcsname{%     % Define @#1index
+    \noexpand\doindex{#1}}
+}
+
+% @defindex foo  ==  \newindex{foo}
+%
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+%
+\def\defcodeindex{\parsearg\newcodeindex}
+%
+\def\newcodeindex#1{%
+  \iflinks
+    \expandafter\newwrite \csname#1indfile\endcsname
+    \openout \csname#1indfile\endcsname \jobname.#1
+  \fi
+  \expandafter\xdef\csname#1index\endcsname{%
+    \noexpand\docodeindex{#1}}%
+}
+
+
+% @synindex foo bar    makes index foo feed into index bar.
+% Do this instead of @defindex foo if you don't want it as a separate index.
+%
+% @syncodeindex foo bar   similar, but put all entries made for index foo
+% inside @code.
+%
+\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}}
+\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}}
+
+% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo),
+% #3 the target index (bar).
+\def\dosynindex#1#2#3{%
+  % Only do \closeout if we haven't already done it, else we'll end up
+  % closing the target index.
+  \expandafter \ifx\csname donesynindex#2\endcsname \relax
+    % The \closeout helps reduce unnecessary open files; the limit on the
+    % Acorn RISC OS is a mere 16 files.
+    \expandafter\closeout\csname#2indfile\endcsname
+    \expandafter\let\csname donesynindex#2\endcsname = 1
+  \fi
+  % redefine \fooindfile:
+  \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname
+  \expandafter\let\csname#2indfile\endcsname=\temp
+  % redefine \fooindex:
+  \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}%
+}
+
+% Define \doindex, the driver for all \fooindex macros.
+% Argument #1 is generated by the calling \fooindex macro,
+%  and it is "foo", the name of the index.
+
+% \doindex just uses \parsearg; it calls \doind for the actual work.
+% This is because \doind is more useful to call from other macros.
+
+% There is also \dosubind {index}{topic}{subtopic}
+% which makes an entry in a two-level index such as the operation index.
+
+\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+\def\singleindexer #1{\doind{\indexname}{#1}}
+
+% like the previous two, but they put @code around the argument.
+\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+
+% Take care of Texinfo commands that can appear in an index entry.
+% Since there are some commands we want to expand, and others we don't,
+% we have to laboriously prevent expansion for those that we don't.
+%
+\def\indexdummies{%
+  \escapechar = `\\     % use backslash in output files.
+  \def\@{@}% change to @@ when we switch to @ as escape char in index files.
+  \def\ {\realbackslash\space }%
+  %
+  % Need these in case \tex is in effect and \{ is a \delimiter again.
+  % But can't use \lbracecmd and \rbracecmd because texindex assumes
+  % braces and backslashes are used only as delimiters.
+  \let\{ = \mylbrace
+  \let\} = \myrbrace
+  %
+  % I don't entirely understand this, but when an index entry is
+  % generated from a macro call, the \endinput which \scanmacro inserts
+  % causes processing to be prematurely terminated.  This is,
+  % apparently, because \indexsorttmp is fully expanded, and \endinput
+  % is an expandable command.  The redefinition below makes \endinput
+  % disappear altogether for that purpose -- although logging shows that
+  % 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}
+  % @findex xyz
+  % @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
+  %
+  % Do the redefinitions.
+  \commondummies
+}
+
+% For the aux and toc files, @ is the escape character.  So we want to
+% redefine everything using @ as the escape character (instead of
+% \realbackslash, still used for index files).  When everything uses @,
+% this will be simpler.
+%
+\def\atdummies{%
+  \def\@{@@}%
+  \def\ {@ }%
+  \let\{ = \lbraceatcmd
+  \let\} = \rbraceatcmd
+  %
+  % Do the redefinitions.
+  \commondummies
+  \otherbackslash
+}
+
+% Called from \indexdummies and \atdummies.
+%
+\def\commondummies{%
+  %
+  % \definedummyword defines \#1 as \string\#1\space, thus effectively
+  % preventing its expansion.  This is used only for control% words,
+  % not control letters, because the \space would be incorrect for
+  % control characters, but is needed to separate the control word
+  % from whatever follows.
+  %
+  % For control letters, we have \definedummyletter, which omits the
+  % space.
+  %
+  % These can be used both for control words that take an argument and
+  % those that do not.  If it is followed by {arg} in the input, then
+  % that will dutifully get written to the index (or wherever).
+  %
+  \def\definedummyword  ##1{\def##1{\string##1\space}}%
+  \def\definedummyletter##1{\def##1{\string##1}}%
+  \let\definedummyaccent\definedummyletter
+  %
+  \commondummiesnofonts
+  %
+  \definedummyletter\_%
+  %
+  % Non-English letters.
+  \definedummyword\AA
+  \definedummyword\AE
+  \definedummyword\DH
+  \definedummyword\L
+  \definedummyword\O
+  \definedummyword\OE
+  \definedummyword\TH
+  \definedummyword\aa
+  \definedummyword\ae
+  \definedummyword\dh
+  \definedummyword\exclamdown
+  \definedummyword\l
+  \definedummyword\o
+  \definedummyword\oe
+  \definedummyword\ordf
+  \definedummyword\ordm
+  \definedummyword\questiondown
+  \definedummyword\ss
+  \definedummyword\th
+  %
+  % Although these internal commands shouldn't show up, sometimes they do.
+  \definedummyword\bf
+  \definedummyword\gtr
+  \definedummyword\hat
+  \definedummyword\less
+  \definedummyword\sf
+  \definedummyword\sl
+  \definedummyword\tclose
+  \definedummyword\tt
+  %
+  \definedummyword\LaTeX
+  \definedummyword\TeX
+  %
+  % Assorted special characters.
+  \definedummyword\bullet
+  \definedummyword\comma
+  \definedummyword\copyright
+  \definedummyword\registeredsymbol
+  \definedummyword\dots
+  \definedummyword\enddots
+  \definedummyword\equiv
+  \definedummyword\error
+  \definedummyword\euro
+  \definedummyword\guillemetleft
+  \definedummyword\guillemetright
+  \definedummyword\guilsinglleft
+  \definedummyword\guilsinglright
+  \definedummyword\expansion
+  \definedummyword\minus
+  \definedummyword\ogonek
+  \definedummyword\pounds
+  \definedummyword\point
+  \definedummyword\print
+  \definedummyword\quotedblbase
+  \definedummyword\quotedblleft
+  \definedummyword\quotedblright
+  \definedummyword\quoteleft
+  \definedummyword\quoteright
+  \definedummyword\quotesinglbase
+  \definedummyword\result
+  \definedummyword\textdegree
+  %
+  % We want to disable all macros so that they are not expanded by \write.
+  \macrolist
+  %
+  \normalturnoffactive
+  %
+  % Handle some cases of @value -- where it does not contain any
+  % (non-fully-expandable) commands.
+  \makevalueexpandable
+}
+
+% \commondummiesnofonts: common to \commondummies and \indexnofonts.
+%
+\def\commondummiesnofonts{%
+  % Control letters and accents.
+  \definedummyletter\!%
+  \definedummyaccent\"%
+  \definedummyaccent\'%
+  \definedummyletter\*%
+  \definedummyaccent\,%
+  \definedummyletter\.%
+  \definedummyletter\/%
+  \definedummyletter\:%
+  \definedummyaccent\=%
+  \definedummyletter\?%
+  \definedummyaccent\^%
+  \definedummyaccent\`%
+  \definedummyaccent\~%
+  \definedummyword\u
+  \definedummyword\v
+  \definedummyword\H
+  \definedummyword\dotaccent
+  \definedummyword\ogonek
+  \definedummyword\ringaccent
+  \definedummyword\tieaccent
+  \definedummyword\ubaraccent
+  \definedummyword\udotaccent
+  \definedummyword\dotless
+  %
+  % Texinfo font commands.
+  \definedummyword\b
+  \definedummyword\i
+  \definedummyword\r
+  \definedummyword\sc
+  \definedummyword\t
+  %
+  % Commands that take arguments.
+  \definedummyword\acronym
+  \definedummyword\cite
+  \definedummyword\code
+  \definedummyword\command
+  \definedummyword\dfn
+  \definedummyword\emph
+  \definedummyword\env
+  \definedummyword\file
+  \definedummyword\kbd
+  \definedummyword\key
+  \definedummyword\math
+  \definedummyword\option
+  \definedummyword\pxref
+  \definedummyword\ref
+  \definedummyword\samp
+  \definedummyword\strong
+  \definedummyword\tie
+  \definedummyword\uref
+  \definedummyword\url
+  \definedummyword\var
+  \definedummyword\verb
+  \definedummyword\w
+  \definedummyword\xref
+}
+
+% \indexnofonts is used when outputting the strings to sort the index
+% by, and when constructing control sequence names.  It eliminates all
+% control sequences and just writes whatever the best ASCII sort string
+% would be for a given command (usually its argument).
+%
+\def\indexnofonts{%
+  % Accent commands should become @asis.
+  \def\definedummyaccent##1{\let##1\asis}%
+  % We can just ignore other control letters.
+  \def\definedummyletter##1{\let##1\empty}%
+  % Hopefully, all control words can become @asis.
+  \let\definedummyword\definedummyaccent
+  %
+  \commondummiesnofonts
+  %
+  % Don't no-op \tt, since it isn't a user-level command
+  % and is used in the definitions of the active chars like <, >, |, etc.
+  % Likewise with the other plain tex font commands.
+  %\let\tt=\asis
+  %
+  \def\ { }%
+  \def\@{@}%
+  % how to handle braces?
+  \def\_{\normalunderscore}%
+  %
+  % Non-English letters.
+  \def\AA{AA}%
+  \def\AE{AE}%
+  \def\DH{DZZ}%
+  \def\L{L}%
+  \def\OE{OE}%
+  \def\O{O}%
+  \def\TH{ZZZ}%
+  \def\aa{aa}%
+  \def\ae{ae}%
+  \def\dh{dzz}%
+  \def\exclamdown{!}%
+  \def\l{l}%
+  \def\oe{oe}%
+  \def\ordf{a}%
+  \def\ordm{o}%
+  \def\o{o}%
+  \def\questiondown{?}%
+  \def\ss{ss}%
+  \def\th{zzz}%
+  %
+  \def\LaTeX{LaTeX}%
+  \def\TeX{TeX}%
+  %
+  % Assorted special characters.
+  % (The following {} will end up in the sort string, but that's ok.)
+  \def\bullet{bullet}%
+  \def\comma{,}%
+  \def\copyright{copyright}%
+  \def\registeredsymbol{R}%
+  \def\dots{...}%
+  \def\enddots{...}%
+  \def\equiv{==}%
+  \def\error{error}%
+  \def\euro{euro}%
+  \def\guillemetleft{<<}%
+  \def\guillemetright{>>}%
+  \def\guilsinglleft{<}%
+  \def\guilsinglright{>}%
+  \def\expansion{==>}%
+  \def\minus{-}%
+  \def\pounds{pounds}%
+  \def\point{.}%
+  \def\print{-|}%
+  \def\quotedblbase{"}%
+  \def\quotedblleft{"}%
+  \def\quotedblright{"}%
+  \def\quoteleft{`}%
+  \def\quoteright{'}%
+  \def\quotesinglbase{,}%
+  \def\result{=>}%
+  \def\textdegree{degrees}%
+  %
+  % We need to get rid of all macros, leaving only the arguments (if present).
+  % Of course this is not nearly correct, but it is the best we can do for now.
+  % 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
+}
+
+\let\indexbackslash=0  %overridden during \printindex.
+\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
+
+% Most index entries go through here, but \dosubind is the general case.
+% #1 is the index name, #2 is the entry text.
+\def\doind#1#2{\dosubind{#1}{#2}{}}
+
+% Workhorse for all \fooindexes.
+% #1 is name of index, #2 is stuff to put there, #3 is subentry --
+% empty if called from \doind, as we usually are (the main exception
+% is with most defuns, which call us directly).
+%
+\def\dosubind#1#2#3{%
+  \iflinks
+  {%
+    % Store the main index entry text (including the third arg).
+    \toks0 = {#2}%
+    % If third arg is present, precede it with a space.
+    \def\thirdarg{#3}%
+    \ifx\thirdarg\empty \else
+      \toks0 = \expandafter{\the\toks0 \space #3}%
+    \fi
+    %
+    \edef\writeto{\csname#1indfile\endcsname}%
+    %
+    \safewhatsit\dosubindwrite
+  }%
+  \fi
+}
+
+% Write the entry in \toks0 to the index file:
+%
+\def\dosubindwrite{%
+  % Put the index entry in the margin if desired.
+  \ifx\SETmarginindex\relax\else
+    \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}%
+  \fi
+  %
+  % Remember, we are within a group.
+  \indexdummies % Must do this here, since \bf, etc expand at this stage
+  \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now
+      % so it will be output as is; and it will print as backslash.
+  %
+  % Process the index entry with all font commands turned off, to
+  % get the string to sort by.
+  {\indexnofonts
+   \edef\temp{\the\toks0}% need full expansion
+   \xdef\indexsorttmp{\temp}%
+  }%
+  %
+  % Set up the complete index entry, with both the sort key and
+  % the original text, including any font commands.  We write
+  % three arguments to \entry to the .?? file (four in the
+  % subentry case), texindex reduces to two when writing the .??s
+  % sorted result.
+  \edef\temp{%
+    \write\writeto{%
+      \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}%
+  }%
+  \temp
+}
+
+% Take care of unwanted page breaks/skips around a whatsit:
+%
+% If a skip is the last thing on the list now, preserve it
+% by backing up by \lastskip, doing the \write, then inserting
+% the skip again.  Otherwise, the whatsit generated by the
+% \write or \pdfdest will make \lastskip zero.  The result is that
+% sequences like this:
+% @end defun
+% @tindex whatever
+% @defun ...
+% will have extra space inserted, because the \medbreak in the
+% start of the @defun won't see the skip inserted by the @end of
+% the previous defun.
+%
+% But don't do any of this if we're not in vertical mode.  We
+% don't want to do a \vskip and prematurely end a paragraph.
+%
+% Avoid page breaks due to these extra skips, too.
+%
+% But wait, there is a catch there:
+% We'll have to check whether \lastskip is zero skip.  \ifdim is not
+% sufficient for this purpose, as it ignores stretch and shrink parts
+% of the skip.  The only way seems to be to check the textual
+% representation of the skip.
+%
+% The following is almost like \def\zeroskipmacro{0.0pt} except that
+% the ``p'' and ``t'' characters have catcode \other, not 11 (letter).
+%
+\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname}
+%
+\newskip\whatsitskip
+\newcount\whatsitpenalty
+%
+% ..., ready, GO:
+%
+\def\safewhatsit#1{%
+\ifhmode
+  #1%
+\else
+  % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
+  \whatsitskip = \lastskip
+  \edef\lastskipmacro{\the\lastskip}%
+  \whatsitpenalty = \lastpenalty
+  %
+  % If \lastskip is nonzero, that means the last item was a
+  % skip.  And since a skip is discardable, that means this
+  % -\whatsitskip glue we're inserting is preceded by a
+  % non-discardable item, therefore it is not a potential
+  % breakpoint, therefore no \nobreak needed.
+  \ifx\lastskipmacro\zeroskipmacro
+  \else
+    \vskip-\whatsitskip
+  \fi
+  %
+  #1%
+  %
+  \ifx\lastskipmacro\zeroskipmacro
+    % If \lastskip was zero, perhaps the last item was a penalty, and
+    % perhaps it was >=10000, e.g., a \nobreak.  In that case, we want
+    % 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.
+    % would allow a break between the index-whatever whatsit
+    % and the "Description." paragraph.
+    \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi
+  \else
+    % On the other hand, if we had a nonzero \lastskip,
+    % this make-up glue would be preceded by a non-discardable item
+    % (the whatsit from the \write), so we must insert a \nobreak.
+    \nobreak\vskip\whatsitskip
+  \fi
+\fi
+}
+
+% The index entry written in the file actually looks like
+%  \entry {sortstring}{page}{topic}
+% or
+%  \entry {sortstring}{page}{topic}{subtopic}
+% The texindex program reads in these files and writes files
+% containing these kinds of lines:
+%  \initial {c}
+%     before the first topic whose initial is c
+%  \entry {topic}{pagelist}
+%     for a topic that is used without subtopics
+%  \primary {topic}
+%     for the beginning of a topic that is used with subtopics
+%  \secondary {subtopic}{pagelist}
+%     for each subtopic.
+
+% Define the user-accessible indexing commands
+% @findex, @vindex, @kindex, @cindex.
+
+\def\findex {\fnindex}
+\def\kindex {\kyindex}
+\def\cindex {\cpindex}
+\def\vindex {\vrindex}
+\def\tindex {\tpindex}
+\def\pindex {\pgindex}
+
+\def\cindexsub {\begingroup\obeylines\cindexsub}
+{\obeylines %
+\gdef\cindexsub "#1" #2^^M{\endgroup %
+\dosubind{cp}{#2}{#1}}}
+
+% Define the macros used in formatting output of the sorted index material.
+
+% @printindex causes a particular index (the ??s file) to get printed.
+% It does not print any chapter heading (usually an @unnumbered).
+%
+\parseargdef\printindex{\begingroup
+  \dobreak \chapheadingskip{10000}%
+  %
+  \smallfonts \rm
+  \tolerance = 9500
+  \plainfrenchspacing
+  \everypar = {}% don't want the \kern\-parindent from indentation suppression.
+  %
+  % See if the index file exists and is nonempty.
+  % Change catcode of @ here so that if the index file contains
+  % \initial {@}
+  % as its first line, TeX doesn't complain about mismatched braces
+  % (because it thinks @} is a control sequence).
+  \catcode`\@ = 11
+  \openin 1 \jobname.#1s
+  \ifeof 1
+    % \enddoublecolumns gets confused if there is no text in the index,
+    % and it loses the chapter title and the aux file entries for the
+    % index.  The easiest way to prevent this problem is to make sure
+    % there is some text.
+    \putwordIndexNonexistent
+  \else
+    %
+    % If the index file exists but is empty, then \openin leaves \ifeof
+    % false.  We have to make TeX try to read something from the file, so
+    % it can discover if there is anything in it.
+    \read 1 to \temp
+    \ifeof 1
+      \putwordIndexIsEmpty
+    \else
+      % Index files are almost Texinfo source, but we use \ as the escape
+      % character.  It would be better to use @, but that's too big a change
+      % to make right now.
+      \def\indexbackslash{\backslashcurfont}%
+      \catcode`\\ = 0
+      \escapechar = `\\
+      \begindoublecolumns
+      \input \jobname.#1s
+      \enddoublecolumns
+    \fi
+  \fi
+  \closein 1
+\endgroup}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+\def\initial#1{{%
+  % Some minor font changes for the special characters.
+  \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+  %
+  % Remove any glue we may have, we'll be inserting our own.
+  \removelastskip
+  %
+  % We like breaks before the index initials, so insert a bonus.
+  \nobreak
+  \vskip 0pt plus 3\baselineskip
+  \penalty 0
+  \vskip 0pt plus -3\baselineskip
+  %
+  % Typeset the initial.  Making this add up to a whole number of
+  % baselineskips increases the chance of the dots lining up from column
+  % to column.  It still won't often be perfect, because of the stretch
+  % we need before each entry, but it's better.
+  %
+  % No shrink because it confuses \balancecolumns.
+  \vskip 1.67\baselineskip plus .5\baselineskip
+  \leftline{\secbf #1}%
+  % Do our best not to break after the initial.
+  \nobreak
+  \vskip .33\baselineskip plus .1\baselineskip
+}}
+
+% \entry typesets a paragraph consisting of the text (#1), dot leaders, and
+% then page number (#2) flushed to the right margin.  It is used for index
+% and table of contents entries.  The paragraph is indented by \leftskip.
+%
+% A straightforward implementation would start like this:
+%      \def\entry#1#2{...
+% But this freezes the catcodes in the argument, and can cause problems to
+% @code, which sets - active.  This problem was fixed by a kludge---
+% ``-'' was active throughout whole index, but this isn't really right.
+%
+% The right solution is to prevent \entry from swallowing the whole text.
+%                                 --kasal, 21nov03
+\def\entry{%
+  \begingroup
+    %
+    % Start a new paragraph if necessary, so our assignments below can't
+    % affect previous text.
+    \par
+    %
+    % Do not fill out the last line with white space.
+    \parfillskip = 0in
+    %
+    % No extra space above this paragraph.
+    \parskip = 0in
+    %
+    % Do not prefer a separate line ending with a hyphen to fewer lines.
+    \finalhyphendemerits = 0
+    %
+    % \hangindent is only relevant when the entry text and page number
+    % don't both fit on one line.  In that case, bob suggests starting the
+    % dots pretty far over on the line.  Unfortunately, a large
+    % indentation looks wrong when the entry text itself is broken across
+    % lines.  So we use a small indentation and put up with long leaders.
+    %
+    % \hangafter is reset to 1 (which is the value we want) at the start
+    % of each paragraph, so we need not do anything with that.
+    \hangindent = 2em
+    %
+    % When the entry text needs to be broken, just fill out the first line
+    % with blank space.
+    \rightskip = 0pt plus1fil
+    %
+    % A bit of stretch before each entry for the benefit of balancing
+    % columns.
+    \vskip 0pt plus1pt
+    %
+    % Swallow the left brace of the text (first parameter):
+    \afterassignment\doentry
+    \let\temp =
+}
+\def\doentry{%
+    \bgroup % Instead of the swallowed brace.
+      \noindent
+      \aftergroup\finishentry
+      % And now comes the text of the entry.
+}
+\def\finishentry#1{%
+    % #1 is the page number.
+    %
+    % The following is kludged to not output a line of dots in the index if
+    % there are no page numbers.  The next person who breaks this will be
+    % cursed by a Unix daemon.
+    \setbox\boxA = \hbox{#1}%
+    \ifdim\wd\boxA = 0pt
+      \ %
+    \else
+      %
+      % If we must, put the page number on a line of its own, and fill out
+      % this line with blank space.  (The \hfil is overwhelmed with the
+      % fill leaders glue in \indexdotfill if the page number does fit.)
+      \hfil\penalty50
+      \null\nobreak\indexdotfill % Have leaders before the page number.
+      %
+      % The `\ ' here is removed by the implicit \unskip that TeX does as
+      % part of (the primitive) \par.  Without it, a spurious underfull
+      % \hbox ensues.
+      \ifpdf
+       \pdfgettoks#1.%
+       \ \the\toksA
+      \else
+       \ #1%
+      \fi
+    \fi
+    \par
+  \endgroup
+}
+
+% Like plain.tex's \dotfill, except uses up at least 1 em.
+\def\indexdotfill{\cleaders
+  \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill}
+
+\def\primary #1{\line{#1\hfil}}
+
+\newskip\secondaryindent \secondaryindent=0.5cm
+\def\secondary#1#2{{%
+  \parfillskip=0in
+  \parskip=0in
+  \hangindent=1in
+  \hangafter=1
+  \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill
+  \ifpdf
+    \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph.
+  \else
+    #2
+  \fi
+  \par
+}}
+
+% Define two-column mode, which we use to typeset indexes.
+% Adapted from the TeXbook, page 416, which is to say,
+% the manmac.tex format used to print the TeXbook itself.
+\catcode`\@=11
+
+\newbox\partialpage
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
+  % Grab any single-column material above us.
+  \output = {%
+    %
+    % Here is a possibility not foreseen in manmac: if we accumulate a
+    % whole lot of material, we might end up calling this \output
+    % routine twice in a row (see the doublecol-lose test, which is
+    % essentially a couple of indexes with @setchapternewpage off).  In
+    % that case we just ship out what is in \partialpage with the normal
+    % output routine.  Generally, \partialpage will be empty when this
+    % runs and this will be a no-op.  See the indexspread.tex test case.
+    \ifvoid\partialpage \else
+      \onepageout{\pagecontents\partialpage}%
+    \fi
+    %
+    \global\setbox\partialpage = \vbox{%
+      % Unvbox the main output page.
+      \unvbox\PAGE
+      \kern-\topskip \kern\baselineskip
+    }%
+  }%
+  \eject % run that output routine to set \partialpage
+  %
+  % Use the double-column output routine for subsequent pages.
+  \output = {\doublecolumnout}%
+  %
+  % Change the page size parameters.  We could do this once outside this
+  % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+  % format, but then we repeat the same computation.  Repeating a couple
+  % of assignments once per index is clearly meaningless for the
+  % execution time, so we may as well do it in one place.
+  %
+  % First we halve the line length, less a little for the gutter between
+  % the columns.  We compute the gutter based on the line length, so it
+  % changes automatically with the paper format.  The magic constant
+  % below is chosen so that the gutter has the same value (well, +-<1pt)
+  % as it did when we hard-coded it.
+  %
+  % We put the result in a separate register, \doublecolumhsize, so we
+  % can restore it in \pagesofar, after \hsize itself has (potentially)
+  % been clobbered.
+  %
+  \doublecolumnhsize = \hsize
+    \advance\doublecolumnhsize by -.04154\hsize
+    \divide\doublecolumnhsize by 2
+  \hsize = \doublecolumnhsize
+  %
+  % Double the \vsize as well.  (We don't need a separate register here,
+  % since nobody clobbers \vsize.)
+  \vsize = 2\vsize
+}
+
+% The double-column output routine for all double-column pages except
+% the last.
+%
+\def\doublecolumnout{%
+  \splittopskip=\topskip \splitmaxdepth=\maxdepth
+  % Get the available space for the double columns -- the normal
+  % (undoubled) page height minus any material left over from the
+  % previous page.
+  \dimen@ = \vsize
+  \divide\dimen@ by 2
+  \advance\dimen@ by -\ht\partialpage
+  %
+  % box0 will be the left-hand column, box2 the right.
+  \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
+  \onepageout\pagesofar
+  \unvbox255
+  \penalty\outputpenalty
+}
+%
+% Re-output the contents of the output page -- any previous material,
+% followed by the two boxes we just split, in box0 and box2.
+\def\pagesofar{%
+  \unvbox\partialpage
+  %
+  \hsize = \doublecolumnhsize
+  \wd0=\hsize \wd2=\hsize
+  \hbox to\pagewidth{\box0\hfil\box2}%
+}
+%
+% All done with double columns.
+\def\enddoublecolumns{%
+  % The following penalty ensures that the page builder is exercised
+  % _before_ we change the output routine.  This is necessary in the
+  % following situation:
+  %
+  % The last section of the index consists only of a single entry.
+  % Before this section, \pagetotal is less than \pagegoal, so no
+  % break occurs before the last section starts.  However, the last
+  % section, consisting of \initial and the single \entry, does not
+  % fit on the page and has to be broken off.  Without the following
+  % penalty the page builder will not be exercised until \eject
+  % below, and by that time we'll already have changed the output
+  % routine to the \balancecolumns version, so the next-to-last
+  % double-column page will be processed with \balancecolumns, which
+  % is wrong:  The two columns will go to the main vertical list, with
+  % the broken-off section in the recent contributions.  As soon as
+  % the output routine finishes, TeX starts reconsidering the page
+  % break.  The two columns and the broken-off section both fit on the
+  % page, because the two columns now take up only half of the page
+  % goal.  When TeX sees \eject from below which follows the final
+  % section, it invokes the new output routine that we've set after
+  % \balancecolumns below; \onepageout will try to fit the two columns
+  % and the final section into the vbox of \pageheight (see
+  % \pagebody), causing an overfull box.
+  %
+  % Note that glue won't work here, because glue does not exercise the
+  % page builder, unlike penalties (see The TeXbook, pp. 280-281).
+  \penalty0
+  %
+  \output = {%
+    % Split the last of the double-column material.  Leave it on the
+    % current page, no automatic page break.
+    \balancecolumns
+    %
+    % If we end up splitting too much material for the current page,
+    % though, there will be another page break right after this \output
+    % invocation ends.  Having called \balancecolumns once, we do not
+    % want to call it again.  Therefore, reset \output to its normal
+    % definition right away.  (We hope \balancecolumns will never be
+    % called on to balance too much material, but if it is, this makes
+    % the output somewhat more palatable.)
+    \global\output = {\onepageout{\pagecontents\PAGE}}%
+  }%
+  \eject
+  \endgroup % started in \begindoublecolumns
+  %
+  % \pagegoal was set to the doubled \vsize above, since we restarted
+  % the current page.  We're now back to normal single-column
+  % typesetting, so reset \pagegoal to the normal \vsize (after the
+  % \endgroup where \vsize got restored).
+  \pagegoal = \vsize
+}
+%
+% Called at the end of the double column material.
+\def\balancecolumns{%
+  \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120.
+  \dimen@ = \ht0
+  \advance\dimen@ by \topskip
+  \advance\dimen@ by-\baselineskip
+  \divide\dimen@ by 2 % target to split to
+  %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}%
+  \splittopskip = \topskip
+  % Loop until we get a decent breakpoint.
+  {%
+    \vbadness = 10000
+    \loop
+      \global\setbox3 = \copy0
+      \global\setbox1 = \vsplit3 to \dimen@
+    \ifdim\ht3>\dimen@
+      \global\advance\dimen@ by 1pt
+    \repeat
+  }%
+  %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}%
+  \setbox0=\vbox to\dimen@{\unvbox1}%
+  \setbox2=\vbox to\dimen@{\unvbox3}%
+  %
+  \pagesofar
+}
+\catcode`\@ = \other
+
+
+\message{sectioning,}
+% Chapters, sections, etc.
+
+% \unnumberedno is an oxymoron, of course.  But we count the unnumbered
+% sections so that we can refer to them unambiguously in the pdf
+% outlines by their "section number".  We avoid collisions with chapter
+% numbers by starting them at 10000.  (If a document ever has 10000
+% chapters, we're in trouble anyway, I'm sure.)
+\newcount\unnumberedno \unnumberedno = 10000
+\newcount\chapno
+\newcount\secno        \secno=0
+\newcount\subsecno     \subsecno=0
+\newcount\subsubsecno  \subsubsecno=0
+
+% This counter is funny since it counts through charcodes of letters A, B, ...
+\newcount\appendixno  \appendixno = `\@
+%
+% \def\appendixletter{\char\the\appendixno}
+% We do the following ugly conditional instead of the above simple
+% construct for the sake of pdftex, which needs the actual
+% letter in the expansion, not just typeset.
+%
+\def\appendixletter{%
+  \ifnum\appendixno=`A A%
+  \else\ifnum\appendixno=`B B%
+  \else\ifnum\appendixno=`C C%
+  \else\ifnum\appendixno=`D D%
+  \else\ifnum\appendixno=`E E%
+  \else\ifnum\appendixno=`F F%
+  \else\ifnum\appendixno=`G G%
+  \else\ifnum\appendixno=`H H%
+  \else\ifnum\appendixno=`I I%
+  \else\ifnum\appendixno=`J J%
+  \else\ifnum\appendixno=`K K%
+  \else\ifnum\appendixno=`L L%
+  \else\ifnum\appendixno=`M M%
+  \else\ifnum\appendixno=`N N%
+  \else\ifnum\appendixno=`O O%
+  \else\ifnum\appendixno=`P P%
+  \else\ifnum\appendixno=`Q Q%
+  \else\ifnum\appendixno=`R R%
+  \else\ifnum\appendixno=`S S%
+  \else\ifnum\appendixno=`T T%
+  \else\ifnum\appendixno=`U U%
+  \else\ifnum\appendixno=`V V%
+  \else\ifnum\appendixno=`W W%
+  \else\ifnum\appendixno=`X X%
+  \else\ifnum\appendixno=`Y Y%
+  \else\ifnum\appendixno=`Z Z%
+  % The \the is necessary, despite appearances, because \appendixletter is
+  % expanded while writing the .toc file.  \char\appendixno is not
+  % expandable, thus it is written literally, thus all appendixes come out
+  % with the same letter (or @) in the toc without it.
+  \else\char\the\appendixno
+  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
+
+% Each @chapter defines these (using marks) as the number+name, number
+% and name of the chapter.  Page headings and footings can use
+% these.  @section does likewise.
+\def\thischapter{}
+\def\thischapternum{}
+\def\thischaptername{}
+\def\thissection{}
+\def\thissectionnum{}
+\def\thissectionname{}
+
+\newcount\absseclevel % used to calculate proper heading level
+\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
+
+% @raisesections: treat @section as chapter, @subsection as section, etc.
+\def\raisesections{\global\advance\secbase by -1}
+\let\up=\raisesections % original BFox name
+
+% @lowersections: treat @chapter as section, @section as subsection, etc.
+\def\lowersections{\global\advance\secbase by 1}
+\let\down=\lowersections % original BFox name
+
+% we only have subsub.
+\chardef\maxseclevel = 3
+%
+% A numbered section within an unnumbered changes to unnumbered too.
+% To achive this, remember the "biggest" unnum. sec. we are currently in:
+\chardef\unmlevel = \maxseclevel
+%
+% Trace whether the current chapter is an appendix or not:
+% \chapheadtype is "N" or "A", unnumbered chapters are ignored.
+\def\chapheadtype{N}
+
+% Choose a heading macro
+% #1 is heading type
+% #2 is heading level
+% #3 is text for heading
+\def\genhead#1#2#3{%
+  % Compute the abs. sec. level:
+  \absseclevel=#2
+  \advance\absseclevel by \secbase
+  % Make sure \absseclevel doesn't fall outside the range:
+  \ifnum \absseclevel < 0
+    \absseclevel = 0
+  \else
+    \ifnum \absseclevel > 3
+      \absseclevel = 3
+    \fi
+  \fi
+  % The heading type:
+  \def\headtype{#1}%
+  \if \headtype U%
+    \ifnum \absseclevel < \unmlevel
+      \chardef\unmlevel = \absseclevel
+    \fi
+  \else
+    % Check for appendix sections:
+    \ifnum \absseclevel = 0
+      \edef\chapheadtype{\headtype}%
+    \else
+      \if \headtype A\if \chapheadtype N%
+       \errmessage{@appendix... within a non-appendix chapter}%
+      \fi\fi
+    \fi
+    % Check for numbered within unnumbered:
+    \ifnum \absseclevel > \unmlevel
+      \def\headtype{U}%
+    \else
+      \chardef\unmlevel = 3
+    \fi
+  \fi
+  % Now print the heading:
+  \if \headtype U%
+    \ifcase\absseclevel
+       \unnumberedzzz{#3}%
+    \or \unnumberedseczzz{#3}%
+    \or \unnumberedsubseczzz{#3}%
+    \or \unnumberedsubsubseczzz{#3}%
+    \fi
+  \else
+    \if \headtype A%
+      \ifcase\absseclevel
+         \appendixzzz{#3}%
+      \or \appendixsectionzzz{#3}%
+      \or \appendixsubseczzz{#3}%
+      \or \appendixsubsubseczzz{#3}%
+      \fi
+    \else
+      \ifcase\absseclevel
+         \chapterzzz{#3}%
+      \or \seczzz{#3}%
+      \or \numberedsubseczzz{#3}%
+      \or \numberedsubsubseczzz{#3}%
+      \fi
+    \fi
+  \fi
+  \suppressfirstparagraphindent
+}
+
+% an interface:
+\def\numhead{\genhead N}
+\def\apphead{\genhead A}
+\def\unnmhead{\genhead U}
+
+% @chapter, @appendix, @unnumbered.  Increment top-level counter, reset
+% all lower-level sectioning counters to zero.
+%
+% Also set \chaplevelprefix, which we prepend to @float sequence numbers
+% (e.g., figures), q.v.  By default (before any chapter), that is empty.
+\let\chaplevelprefix = \empty
+%
+\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz#1{%
+  % section resetting is \global in case the chapter is in a group, such
+  % as an @include file.
+  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+    \global\advance\chapno by 1
+  %
+  % Used for \float.
+  \gdef\chaplevelprefix{\the\chapno.}%
+  \resetallfloatnos
+  %
+  % \putwordChapter can contain complex things in translations.
+  \toks0=\expandafter{\putwordChapter}%
+  \message{\the\toks0 \space \the\chapno}%
+  %
+  % Write the actual heading.
+  \chapmacro{#1}{Ynumbered}{\the\chapno}%
+  %
+  % So @section and the like are numbered underneath this chapter.
+  \global\let\section = \numberedsec
+  \global\let\subsection = \numberedsubsec
+  \global\let\subsubsection = \numberedsubsubsec
+}
+
+\outer\parseargdef\appendix{\apphead0{#1}} % normally calls appendixzzz
+%
+\def\appendixzzz#1{%
+  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+    \global\advance\appendixno by 1
+  \gdef\chaplevelprefix{\appendixletter.}%
+  \resetallfloatnos
+  %
+  % \putwordAppendix can contain complex things in translations.
+  \toks0=\expandafter{\putwordAppendix}%
+  \message{\the\toks0 \space \appendixletter}%
+  %
+  \chapmacro{#1}{Yappendix}{\appendixletter}%
+  %
+  \global\let\section = \appendixsec
+  \global\let\subsection = \appendixsubsec
+  \global\let\subsubsection = \appendixsubsubsec
+}
+
+\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+\def\unnumberedzzz#1{%
+  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+    \global\advance\unnumberedno by 1
+  %
+  % Since an unnumbered has no number, no prefix for figures.
+  \global\let\chaplevelprefix = \empty
+  \resetallfloatnos
+  %
+  % This used to be simply \message{#1}, but TeX fully expands the
+  % argument to \message.  Therefore, if #1 contained @-commands, TeX
+  % expanded them.  For example, in `@unnumbered The @cite{Book}', TeX
+  % expanded @cite (which turns out to cause errors because \cite is meant
+  % to be executed, not expanded).
+  %
+  % Anyway, we don't want the fully-expanded definition of @cite to appear
+  % as a result of the \message, we just want `@cite' itself.  We use
+  % \the<toks register> to achieve this: TeX expands \the<toks> only once,
+  % simply yielding the contents of <toks register>.  (We also do this for
+  % the toc entries.)
+  \toks0 = {#1}%
+  \message{(\the\toks0)}%
+  %
+  \chapmacro{#1}{Ynothing}{\the\unnumberedno}%
+  %
+  \global\let\section = \unnumberedsec
+  \global\let\subsection = \unnumberedsubsec
+  \global\let\subsubsection = \unnumberedsubsubsec
+}
+
+% @centerchap is like @unnumbered, but the heading is centered.
+\outer\parseargdef\centerchap{%
+  % Well, we could do the following in a group, but that would break
+  % an assumption that \chapmacro is called at the outermost level.
+  % Thus we are safer this way:                --kasal, 24feb04
+  \let\centerparametersmaybe = \centerparameters
+  \unnmhead0{#1}%
+  \let\centerparametersmaybe = \relax
+}
+
+% @top is like @unnumbered.
+\let\top\unnumbered
+
+% Sections.
+\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz
+\def\seczzz#1{%
+  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
+  \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%
+}
+
+\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz
+\def\appendixsectionzzz#1{%
+  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
+  \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%
+}
+\let\appendixsec\appendixsection
+
+\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz
+\def\unnumberedseczzz#1{%
+  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
+  \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%
+}
+
+% Subsections.
+\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz
+\def\numberedsubseczzz#1{%
+  \global\subsubsecno=0  \global\advance\subsecno by 1
+  \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%
+}
+
+\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz
+\def\appendixsubseczzz#1{%
+  \global\subsubsecno=0  \global\advance\subsecno by 1
+  \sectionheading{#1}{subsec}{Yappendix}%
+                 {\appendixletter.\the\secno.\the\subsecno}%
+}
+
+\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+\def\unnumberedsubseczzz#1{%
+  \global\subsubsecno=0  \global\advance\subsecno by 1
+  \sectionheading{#1}{subsec}{Ynothing}%
+                 {\the\unnumberedno.\the\secno.\the\subsecno}%
+}
+
+% Subsubsections.
+\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz
+\def\numberedsubsubseczzz#1{%
+  \global\advance\subsubsecno by 1
+  \sectionheading{#1}{subsubsec}{Ynumbered}%
+                 {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz
+\def\appendixsubsubseczzz#1{%
+  \global\advance\subsubsecno by 1
+  \sectionheading{#1}{subsubsec}{Yappendix}%
+                 {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+\def\unnumberedsubsubseczzz#1{%
+  \global\advance\subsubsecno by 1
+  \sectionheading{#1}{subsubsec}{Ynothing}%
+                 {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% These macros control what the section commands do, according
+% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+% Define them by default for a numbered chapter.
+\let\section = \numberedsec
+\let\subsection = \numberedsubsec
+\let\subsubsection = \numberedsubsubsec
+
+% Define @majorheading, @heading and @subheading
+
+% NOTE on use of \vbox for chapter headings, section headings, and such:
+%       1) We use \vbox rather than the earlier \line to permit
+%          overlong headings to fold.
+%       2) \hyphenpenalty is set to 10000 because hyphenation in a
+%          heading is obnoxious; this forbids it.
+%       3) Likewise, headings look best if no \parindent is used, and
+%          if justification is not attempted.  Hence \raggedright.
+
+\def\majorheading{%
+  {\advance\chapheadingskip by 10pt \chapbreak }%
+  \parsearg\chapheadingzzz
+}
+
+\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
+\def\chapheadingzzz#1{%
+  {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                    \parindent=0pt\ptexraggedright
+                    \rmisbold #1\hfill}}%
+  \bigskip \par\penalty 200\relax
+  \suppressfirstparagraphindent
+}
+
+% @heading, @subheading, @subsubheading.
+\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{}
+  \suppressfirstparagraphindent}
+\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{}
+  \suppressfirstparagraphindent}
+\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{}
+  \suppressfirstparagraphindent}
+
+% These macros generate a chapter, section, etc. heading only
+% (including whitespace, linebreaking, etc. around it),
+% given all the information in convenient, parsed form.
+
+%%% Args are the skip and penalty (usually negative)
+\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+
+%%% Define plain chapter starts, and page on/off switching for it
+% Parameter controlling skip before chapter headings (if needed)
+
+\newskip\chapheadingskip
+
+\def\chapbreak{\dobreak \chapheadingskip {-4000}}
+\def\chappager{\par\vfill\supereject}
+% Because \domark is called before \chapoddpage, the filler page will
+% get the headings for the next chapter, which is wrong.  But we don't
+% care -- we just disable all headings on the filler page.
+\def\chapoddpage{%
+  \chappager
+  \ifodd\pageno \else
+    \begingroup
+      \evenheadline={\hfil}\evenfootline={\hfil}%
+      \oddheadline={\hfil}\oddfootline={\hfil}%
+      \hbox to 0pt{}%
+      \chappager
+    \endgroup
+  \fi
+}
+
+\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+
+\def\CHAPPAGoff{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{%
+\global\let\contentsalignmacro = \chapoddpage
+\global\let\pchapsepmacro=\chapoddpage
+\global\let\pagealignmacro=\chapoddpage
+\global\def\HEADINGSon{\HEADINGSdouble}}
+
+\CHAPPAGon
+
+% Chapter opening.
+%
+% #1 is the text, #2 is the section type (Ynumbered, Ynothing,
+% Yappendix, Yomitfromtoc), #3 the chapter number.
+%
+% To test against our argument.
+\def\Ynothingkeyword{Ynothing}
+\def\Yomitfromtockeyword{Yomitfromtoc}
+\def\Yappendixkeyword{Yappendix}
+%
+\def\chapmacro#1#2#3{%
+  % Insert the first mark before the heading break (see notes for \domark).
+  \let\prevchapterdefs=\lastchapterdefs
+  \let\prevsectiondefs=\lastsectiondefs
+  \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}%
+                        \gdef\thissection{}}%
+  %
+  \def\temptype{#2}%
+  \ifx\temptype\Ynothingkeyword
+    \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
+                          \gdef\thischapter{\thischaptername}}%
+  \else\ifx\temptype\Yomitfromtockeyword
+    \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
+                          \gdef\thischapter{}}%
+  \else\ifx\temptype\Yappendixkeyword
+    \toks0={#1}%
+    \xdef\lastchapterdefs{%
+      \gdef\noexpand\thischaptername{\the\toks0}%
+      \gdef\noexpand\thischapternum{\appendixletter}%
+      % \noexpand\putwordAppendix avoids expanding indigestible
+      % commands in some of the translations.
+      \gdef\noexpand\thischapter{\noexpand\putwordAppendix{}
+                                 \noexpand\thischapternum:
+                                 \noexpand\thischaptername}%
+    }%
+  \else
+    \toks0={#1}%
+    \xdef\lastchapterdefs{%
+      \gdef\noexpand\thischaptername{\the\toks0}%
+      \gdef\noexpand\thischapternum{\the\chapno}%
+      % \noexpand\putwordChapter avoids expanding indigestible
+      % commands in some of the translations.
+      \gdef\noexpand\thischapter{\noexpand\putwordChapter{}
+                                 \noexpand\thischapternum:
+                                 \noexpand\thischaptername}%
+    }%
+  \fi\fi\fi
+  %
+  % Output the mark.  Pass it through \safewhatsit, to take care of
+  % the preceding space.
+  \safewhatsit\domark
+  %
+  % Insert the chapter heading break.
+  \pchapsepmacro
+  %
+  % Now the second mark, after the heading break.  No break points
+  % between here and the heading.
+  \let\prevchapterdefs=\lastchapterdefs
+  \let\prevsectiondefs=\lastsectiondefs
+  \domark
+  %
+  {%
+    \chapfonts \rmisbold
+    %
+    % Have to define \lastsection before calling \donoderef, because the
+    % xref code eventually uses it.  On the other hand, it has to be called
+    % after \pchapsepmacro, or the headline will change too soon.
+    \gdef\lastsection{#1}%
+    %
+    % Only insert the separating space if we have a chapter/appendix
+    % number, and don't print the unnumbered ``number''.
+    \ifx\temptype\Ynothingkeyword
+      \setbox0 = \hbox{}%
+      \def\toctype{unnchap}%
+    \else\ifx\temptype\Yomitfromtockeyword
+      \setbox0 = \hbox{}% contents like unnumbered, but no toc entry
+      \def\toctype{omit}%
+    \else\ifx\temptype\Yappendixkeyword
+      \setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
+      \def\toctype{app}%
+    \else
+      \setbox0 = \hbox{#3\enspace}%
+      \def\toctype{numchap}%
+    \fi\fi\fi
+    %
+    % Write the toc entry for this chapter.  Must come before the
+    % \donoderef, because we include the current node name in the toc
+    % entry, and \donoderef resets it to empty.
+    \writetocentry{\toctype}{#1}{#3}%
+    %
+    % For pdftex, we have to write out the node definition (aka, make
+    % the pdfdest) after any page break, but before the actual text has
+    % been typeset.  If the destination for the pdf outline is after the
+    % text, then jumping from the outline may wind up with the text not
+    % being visible, for instance under high magnification.
+    \donoderef{#2}%
+    %
+    % Typeset the actual heading.
+    \nobreak % Avoid page breaks at the interline glue.
+    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright
+          \hangindent=\wd0 \centerparametersmaybe
+          \unhbox0 #1\par}%
+  }%
+  \nobreak\bigskip % no page break after a chapter title
+  \nobreak
+}
+
+% @centerchap -- centered and unnumbered.
+\let\centerparametersmaybe = \relax
+\def\centerparameters{%
+  \advance\rightskip by 3\rightskip
+  \leftskip = \rightskip
+  \parfillskip = 0pt
+}
+
+
+% I don't think this chapter style is supported any more, so I'm not
+% updating it with the new noderef stuff.  We'll see.  --karl, 11aug03.
+%
+\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+%
+\def\unnchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                       \parindent=0pt\ptexraggedright
+                       \rmisbold #1\hfill}}\bigskip \par\nobreak
+}
+\def\chfopen #1#2{\chapoddpage {\chapfonts
+\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+\par\penalty 5000 %
+}
+\def\centerchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                       \parindent=0pt
+                       \hfill {\rmisbold #1}\hfill}}\bigskip \par\nobreak
+}
+\def\CHAPFopen{%
+  \global\let\chapmacro=\chfopen
+  \global\let\centerchapmacro=\centerchfopen}
+
+
+% Section titles.  These macros combine the section number parts and
+% call the generic \sectionheading to do the printing.
+%
+\newskip\secheadingskip
+\def\secheadingbreak{\dobreak \secheadingskip{-1000}}
+
+% Subsection titles.
+\newskip\subsecheadingskip
+\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}}
+
+% Subsubsection titles.
+\def\subsubsecheadingskip{\subsecheadingskip}
+\def\subsubsecheadingbreak{\subsecheadingbreak}
+
+
+% Print any size, any type, section title.
+%
+% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is
+% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
+% section number.
+%
+\def\seckeyword{sec}
+%
+\def\sectionheading#1#2#3#4{%
+  {%
+    % Switch to the right set of fonts.
+    \csname #2fonts\endcsname \rmisbold
+    %
+    \def\sectionlevel{#2}%
+    \def\temptype{#3}%
+    %
+    % Insert first mark before the heading break (see notes for \domark).
+    \let\prevsectiondefs=\lastsectiondefs
+    \ifx\temptype\Ynothingkeyword
+      \ifx\sectionlevel\seckeyword
+        \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}%
+                              \gdef\thissection{\thissectionname}}%
+      \fi
+    \else\ifx\temptype\Yomitfromtockeyword
+      % Don't redefine \thissection.
+    \else\ifx\temptype\Yappendixkeyword
+      \ifx\sectionlevel\seckeyword
+        \toks0={#1}%
+        \xdef\lastsectiondefs{%
+          \gdef\noexpand\thissectionname{\the\toks0}%
+          \gdef\noexpand\thissectionnum{#4}%
+          % \noexpand\putwordSection avoids expanding indigestible
+          % commands in some of the translations.
+          \gdef\noexpand\thissection{\noexpand\putwordSection{}
+                                     \noexpand\thissectionnum:
+                                     \noexpand\thissectionname}%
+        }%
+      \fi
+    \else
+      \ifx\sectionlevel\seckeyword
+        \toks0={#1}%
+        \xdef\lastsectiondefs{%
+          \gdef\noexpand\thissectionname{\the\toks0}%
+          \gdef\noexpand\thissectionnum{#4}%
+          % \noexpand\putwordSection avoids expanding indigestible
+          % commands in some of the translations.
+          \gdef\noexpand\thissection{\noexpand\putwordSection{}
+                                     \noexpand\thissectionnum:
+                                     \noexpand\thissectionname}%
+        }%
+      \fi
+    \fi\fi\fi
+    %
+    % Go into vertical mode.  Usually we'll already be there, but we
+    % don't want the following whatsit to end up in a preceding paragraph
+    % if the document didn't happen to have a blank line.
+    \par
+    %
+    % Output the mark.  Pass it through \safewhatsit, to take care of
+    % the preceding space.
+    \safewhatsit\domark
+    %
+    % Insert space above the heading.
+    \csname #2headingbreak\endcsname
+    %
+    % Now the second mark, after the heading break.  No break points
+    % between here and the heading.
+    \let\prevsectiondefs=\lastsectiondefs
+    \domark
+    %
+    % Only insert the space after the number if we have a section number.
+    \ifx\temptype\Ynothingkeyword
+      \setbox0 = \hbox{}%
+      \def\toctype{unn}%
+      \gdef\lastsection{#1}%
+    \else\ifx\temptype\Yomitfromtockeyword
+      % for @headings -- no section number, don't include in toc,
+      % and don't redefine \lastsection.
+      \setbox0 = \hbox{}%
+      \def\toctype{omit}%
+      \let\sectionlevel=\empty
+    \else\ifx\temptype\Yappendixkeyword
+      \setbox0 = \hbox{#4\enspace}%
+      \def\toctype{app}%
+      \gdef\lastsection{#1}%
+    \else
+      \setbox0 = \hbox{#4\enspace}%
+      \def\toctype{num}%
+      \gdef\lastsection{#1}%
+    \fi\fi\fi
+    %
+    % Write the toc entry (before \donoderef).  See comments in \chapmacro.
+    \writetocentry{\toctype\sectionlevel}{#1}{#4}%
+    %
+    % Write the node reference (= pdf destination for pdftex).
+    % Again, see comments in \chapmacro.
+    \donoderef{#3}%
+    %
+    % Interline glue will be inserted when the vbox is completed.
+    % That glue will be a valid breakpoint for the page, since it'll be
+    % preceded by a whatsit (usually from the \donoderef, or from the
+    % \writetocentry if there was no node).  We don't want to allow that
+    % break, since then the whatsits could end up on page n while the
+    % section is on page n+1, thus toc/etc. are wrong.  Debian bug 276000.
+    \nobreak
+    %
+    % Output the actual section heading.
+    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright
+          \hangindent=\wd0  % zero if no section number
+          \unhbox0 #1}%
+  }%
+  % Add extra space after the heading -- half of whatever came above it.
+  % Don't allow stretch, though.
+  \kern .5 \csname #2headingskip\endcsname
+  %
+  % Do not let the kern be a potential breakpoint, as it would be if it
+  % was followed by glue.
+  \nobreak
+  %
+  % We'll almost certainly start a paragraph next, so don't let that
+  % 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
+}
+
+
+\message{toc,}
+% Table of contents.
+\newwrite\tocfile
+
+% Write an entry to the toc file, opening it if necessary.
+% Called from @chapter, etc.
+%
+% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno}
+% We append the current node name (if any) and page number as additional
+% arguments for the \{chap,sec,...}entry macros which will eventually
+% read this.  The node name is used in the pdf outlines as the
+% destination to jump to.
+%
+% We open the .toc file for writing here instead of at @setfilename (or
+% any other fixed time) so that @contents can be anywhere in the document.
+% But if #1 is `omit', then we don't do anything.  This is used for the
+% table of contents chapter openings themselves.
+%
+\newif\iftocfileopened
+\def\omitkeyword{omit}%
+%
+\def\writetocentry#1#2#3{%
+  \edef\writetoctype{#1}%
+  \ifx\writetoctype\omitkeyword \else
+    \iftocfileopened\else
+      \immediate\openout\tocfile = \jobname.toc
+      \global\tocfileopenedtrue
+    \fi
+    %
+    \iflinks
+      {\atdummies
+       \edef\temp{%
+         \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}%
+       \temp
+      }%
+    \fi
+  \fi
+  %
+  % Tell \shipout to create a pdf destination on each page, if we're
+  % writing pdf.  These are used in the table of contents.  We can't
+  % just write one on every page because the title pages are numbered
+  % 1 and 2 (the page numbers aren't printed), and so are the first
+  % two pages of the document.  Thus, we'd have two destinations named
+  % `1', and two named `2'.
+  \ifpdf \global\pdfmakepagedesttrue \fi
+}
+
+
+% 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
+  \catcode`\<=\active
+  \catcode`\>=\active
+  \catcode`\\=\active
+  \catcode`\^=\active
+  \catcode`\_=\active
+  \catcode`\|=\active
+  \catcode`\~=\active
+}
+
+
+% Read the toc file, which is essentially Texinfo input.
+\def\readtocfile{%
+  \setupdatafile
+  \activecatcodes
+  \input \tocreadfilename
+}
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\newcount\savepageno
+\newcount\lastnegativepageno \lastnegativepageno = -1
+
+% Prepare to read what we've written to \tocfile.
+%
+\def\startcontents#1{%
+  % If @setchapternewpage on, and @headings double, the contents should
+  % start on an odd page, unlike chapters.  Thus, we maintain
+  % \contentsalignmacro in parallel with \pagealignmacro.
+  % From: Torbjorn Granlund <tege@matematik.su.se>
+  \contentsalignmacro
+  \immediate\closeout\tocfile
+  %
+  % Don't need to put `Contents' or `Short Contents' in the headline.
+  % It is abundantly clear what they are.
+  \chapmacro{#1}{Yomitfromtoc}{}%
+  %
+  \savepageno = \pageno
+  \begingroup                  % Set up to handle contents files properly.
+    \raggedbottom              % Worry more about breakpoints than the bottom.
+    \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+    %
+    % Roman numerals for page numbers.
+    \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
+}
+
+% redefined for the two-volume lispref.  We always output on
+% \jobname.toc even if this is redefined.
+%
+\def\tocreadfilename{\jobname.toc}
+
+% Normal (long) toc.
+%
+\def\contents{%
+  \startcontents{\putwordTOC}%
+    \openin 1 \tocreadfilename\space
+    \ifeof 1 \else
+      \readtocfile
+    \fi
+    \vfill \eject
+    \contentsalignmacro % in case @setchapternewpage odd is in effect
+    \ifeof 1 \else
+      \pdfmakeoutlines
+    \fi
+    \closein 1
+  \endgroup
+  \lastnegativepageno = \pageno
+  \global\pageno = \savepageno
+}
+
+% And just the chapters.
+\def\summarycontents{%
+  \startcontents{\putwordShortTOC}%
+    %
+    \let\numchapentry = \shortchapentry
+    \let\appentry = \shortchapentry
+    \let\unnchapentry = \shortunnchapentry
+    % We want a true roman here for the page numbers.
+    \secfonts
+    \let\rm=\shortcontrm \let\bf=\shortcontbf
+    \let\sl=\shortcontsl \let\tt=\shortconttt
+    \rm
+    \hyphenpenalty = 10000
+    \advance\baselineskip by 1pt % Open it up a little.
+    \def\numsecentry##1##2##3##4{}
+    \let\appsecentry = \numsecentry
+    \let\unnsecentry = \numsecentry
+    \let\numsubsecentry = \numsecentry
+    \let\appsubsecentry = \numsecentry
+    \let\unnsubsecentry = \numsecentry
+    \let\numsubsubsecentry = \numsecentry
+    \let\appsubsubsecentry = \numsecentry
+    \let\unnsubsubsecentry = \numsecentry
+    \openin 1 \tocreadfilename\space
+    \ifeof 1 \else
+      \readtocfile
+    \fi
+    \closein 1
+    \vfill \eject
+    \contentsalignmacro % in case @setchapternewpage odd is in effect
+  \endgroup
+  \lastnegativepageno = \pageno
+  \global\pageno = \savepageno
+}
+\let\shortcontents = \summarycontents
+
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g., `A' for an appendix, or `3' for a chapter.
+%
+\def\shortchaplabel#1{%
+  % This space should be enough, since a single number is .5em, and the
+  % widest letter (M) is 1em, at least in the Computer Modern fonts.
+  % But use \hss just in case.
+  % (This space doesn't include the extra space that gets added after
+  % the label; that gets put in by \shortchapentry above.)
+  %
+  % We'd like to right-justify chapter numbers, but that looks strange
+  % with appendix letters.  And right-justifying numbers and
+  % left-justifying letters looks strange when there is less than 10
+  % chapters.  Have to read the whole toc once to know how many chapters
+  % there are before deciding ...
+  \hbox to 1em{#1\hss}%
+}
+
+% These macros generate individual entries in the table of contents.
+% The first argument is the chapter or section name.
+% The last argument is the page number.
+% The arguments in between are the chapter number, section number, ...
+
+% Chapters, in the main contents.
+\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
+%
+% Chapters, in the short toc.
+% See comments in \dochapentry re vbox and related settings.
+\def\shortchapentry#1#2#3#4{%
+  \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}%
+}
+
+% Appendices, in the main contents.
+% Need the word Appendix, and a fixed-size box.
+%
+\def\appendixbox#1{%
+  % We use M since it's probably the widest letter.
+  \setbox0 = \hbox{\putwordAppendix{} M}%
+  \hbox to \wd0{\putwordAppendix{} #1\hss}}
+%
+\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}}
+
+% Unnumbered chapters.
+\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}}
+\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}}
+
+% Sections.
+\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}}
+\let\appsecentry=\numsecentry
+\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}}
+
+% Subsections.
+\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsecentry=\numsubsecentry
+\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}}
+
+% And subsubsections.
+\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsubsecentry=\numsubsubsecentry
+\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}}
+
+% This parameter controls the indentation of the various levels.
+% Same as \defaultparindent.
+\newdimen\tocindent \tocindent = 15pt
+
+% Now for the actual typesetting. In all these, #1 is the text and #2 is the
+% page number.
+%
+% If the toc has to be broken over pages, we want it to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+   \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
+   \begingroup
+     \chapentryfonts
+     \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+   \endgroup
+   \nobreak\vskip .25\baselineskip plus.1\baselineskip
+}
+
+\def\dosecentry#1#2{\begingroup
+  \secentryfonts \leftskip=\tocindent
+  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsecentry#1#2{\begingroup
+  \subsecentryfonts \leftskip=2\tocindent
+  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsubsecentry#1#2{\begingroup
+  \subsubsecentryfonts \leftskip=3\tocindent
+  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+% We use the same \entry macro as for the index entries.
+\let\tocentry = \entry
+
+% Space between chapter (or whatever) number and the title.
+\def\labelspace{\hskip1em \relax}
+
+\def\dopageno#1{{\rm #1}}
+\def\doshortpageno#1{{\rm #1}}
+
+\def\chapentryfonts{\secfonts \rm}
+\def\secentryfonts{\textfonts}
+\def\subsecentryfonts{\textfonts}
+\def\subsubsecentryfonts{\textfonts}
+
+
+\message{environments,}
+% @foo ... @end foo.
+
+% @tex ... @end tex    escapes into raw Tex temporarily.
+% One exception: @ is still an escape character, so that @end tex works.
+% But \@ or @@ will get a plain tex @ character.
+
+\envdef\tex{%
+  \setupmarkupstyle{tex}%
+  \catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+  \catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+  \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
+  \catcode `\%=14
+  \catcode `\+=\other
+  \catcode `\"=\other
+  \catcode `\|=\other
+  \catcode `\<=\other
+  \catcode `\>=\other
+  \catcode`\`=\other
+  \catcode`\'=\other
+  \escapechar=`\\
+  %
+  \let\b=\ptexb
+  \let\bullet=\ptexbullet
+  \let\c=\ptexc
+  \let\,=\ptexcomma
+  \let\.=\ptexdot
+  \let\dots=\ptexdots
+  \let\equiv=\ptexequiv
+  \let\!=\ptexexclam
+  \let\i=\ptexi
+  \let\indent=\ptexindent
+  \let\noindent=\ptexnoindent
+  \let\{=\ptexlbrace
+  \let\+=\tabalign
+  \let\}=\ptexrbrace
+  \let\/=\ptexslash
+  \let\*=\ptexstar
+  \let\t=\ptext
+  \expandafter \let\csname top\endcsname=\ptextop  % outer
+  \let\frenchspacing=\plainfrenchspacing
+  %
+  \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
+  \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
+  \def\@{@}%
+}
+% There is no need to define \Etex.
+
+% Define @lisp ... @end lisp.
+% @lisp environment forms a group so it can rebind things,
+% including the definition of @end lisp (which normally is erroneous).
+
+% Amount to narrow the margins by for @lisp.
+\newskip\lispnarrowing \lispnarrowing=0.4in
+
+% This is the definition that ^^M gets inside @lisp, @example, and other
+% such environments.  \null is better than a space, since it doesn't
+% have any width.
+\def\lisppar{\null\endgraf}
+
+% This space is always present above and below environments.
+\newskip\envskipamount \envskipamount = 0pt
+
+% Make spacing and below environment symmetrical.  We use \parskip here
+% to help in doing that, since in @example-like environments \parskip
+% is reset to zero; thus the \afterenvbreak inserts no space -- but the
+% start of the next paragraph will insert \parskip.
+%
+\def\aboveenvbreak{{%
+  % =10000 instead of <10000 because of a special case in \itemzzz and
+  % \sectionheading, q.v.
+  \ifnum \lastpenalty=10000 \else
+    \advance\envskipamount by \parskip
+    \endgraf
+    \ifdim\lastskip<\envskipamount
+      \removelastskip
+      % it's not a good place to break if the last penalty was \nobreak
+      % or better ...
+      \ifnum\lastpenalty<10000 \penalty-50 \fi
+      \vskip\envskipamount
+    \fi
+  \fi
+}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag.  If "set", @lisp etc don't narrow margins; it will
+% also clear it, so that its embedded environments do the narrowing again.
+\let\nonarrowing=\relax
+
+% @cartouche ... @end cartouche: draw rectangle w/rounded corners around
+% environment contents.
+\font\circle=lcircle10
+\newdimen\circthick
+\newdimen\cartouter\newdimen\cartinner
+\newskip\normbskip\newskip\normpskip\newskip\normlskip
+\circthick=\fontdimen8\circle
+%
+\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+\def\ctr{{\hskip 6pt\circle\char'010}}
+\def\cbl{{\circle\char'012\hskip -6pt}}
+\def\cbr{{\hskip 6pt\circle\char'011}}
+\def\carttop{\hbox to \cartouter{\hskip\lskip
+        \ctl\leaders\hrule height\circthick\hfil\ctr
+        \hskip\rskip}}
+\def\cartbot{\hbox to \cartouter{\hskip\lskip
+        \cbl\leaders\hrule height\circthick\hfil\cbr
+        \hskip\rskip}}
+%
+\newskip\lskip\newskip\rskip
+
+\envdef\cartouche{%
+  \ifhmode\par\fi  % can't be in the midst of a paragraph.
+  \startsavinginserts
+  \lskip=\leftskip \rskip=\rightskip
+  \leftskip=0pt\rightskip=0pt % we want these *outside*.
+  \cartinner=\hsize \advance\cartinner by-\lskip
+  \advance\cartinner by-\rskip
+  \cartouter=\hsize
+  \advance\cartouter by 18.4pt % allow for 3pt kerns on either
+                               % side, and for 6pt waste from
+                               % each corner char, and rule thickness
+  \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+  % Flag to tell @lisp, etc., not to narrow margin.
+  \let\nonarrowing = t%
+  \vbox\bgroup
+      \baselineskip=0pt\parskip=0pt\lineskip=0pt
+      \carttop
+      \hbox\bgroup
+         \hskip\lskip
+         \vrule\kern3pt
+         \vbox\bgroup
+             \kern3pt
+             \hsize=\cartinner
+             \baselineskip=\normbskip
+             \lineskip=\normlskip
+             \parskip=\normpskip
+             \vskip -\parskip
+             \comment % For explanation, see the end of \def\group.
+}
+\def\Ecartouche{%
+              \ifhmode\par\fi
+             \kern3pt
+         \egroup
+         \kern3pt\vrule
+         \hskip\rskip
+      \egroup
+      \cartbot
+  \egroup
+  \checkinserts
+}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\newdimen\nonfillparindent
+\def\nonfillstart{%
+  \aboveenvbreak
+  \hfuzz = 12pt % Don't be fussy
+  \sepspaces % Make spaces be word-separators rather than space tokens.
+  \let\par = \lisppar % don't ignore blank lines
+  \obeylines % each line of input is a line of output
+  \parskip = 0pt
+  % Turn off paragraph indentation but redefine \indent to emulate
+  % the normal \indent.
+  \nonfillparindent=\parindent
+  \parindent = 0pt
+  \let\indent\nonfillindent
+  %
+  \emergencystretch = 0pt % don't try to avoid overfull boxes
+  \ifx\nonarrowing\relax
+    \advance \leftskip by \lispnarrowing
+    \exdentamount=\lispnarrowing
+  \else
+    \let\nonarrowing = \relax
+  \fi
+  \let\exdent=\nofillexdent
+}
+
+\begingroup
+\obeyspaces
+% We want to swallow spaces (but not other tokens) after the fake
+% @indent in our nonfill-environments, where spaces are normally
+% active and set to @tie, resulting in them not being ignored after
+% @indent.
+\gdef\nonfillindent{\futurelet\temp\nonfillindentcheck}%
+\gdef\nonfillindentcheck{%
+\ifx\temp %
+\expandafter\nonfillindentgobble%
+\else%
+\leavevmode\nonfillindentbox%
+\fi%
+}%
+\endgroup
+\def\nonfillindentgobble#1{\nonfillindent}
+\def\nonfillindentbox{\hbox to \nonfillparindent{\hss}}
+
+% If you want all examples etc. small: @set dispenvsize small.
+% If you want even small examples the full size: @set dispenvsize nosmall.
+% This affects the following displayed environments:
+%    @example, @display, @format, @lisp
+%
+\def\smallword{small}
+\def\nosmallword{nosmall}
+\let\SETdispenvsize\relax
+\def\setnormaldispenv{%
+  \ifx\SETdispenvsize\smallword
+    % end paragraph for sake of leading, in case document has no blank
+    % line.  This is redundant with what happens in \aboveenvbreak, but
+    % we need to do it before changing the fonts, and it's inconvenient
+    % to change the fonts afterward.
+    \ifnum \lastpenalty=10000 \else \endgraf \fi
+    \smallexamplefonts \rm
+  \fi
+}
+\def\setsmalldispenv{%
+  \ifx\SETdispenvsize\nosmallword
+  \else
+    \ifnum \lastpenalty=10000 \else \endgraf \fi
+    \smallexamplefonts \rm
+  \fi
+}
+
+% We often define two environments, @foo and @smallfoo.
+% Let's do it by one command:
+\def\makedispenv #1#2{
+  \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}
+  \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}
+  \expandafter\let\csname E#1\endcsname \afterenvbreak
+  \expandafter\let\csname Esmall#1\endcsname \afterenvbreak
+}
+
+% Define two synonyms:
+\def\maketwodispenvs #1#2#3{
+  \makedispenv{#1}{#3}
+  \makedispenv{#2}{#3}
+}
+
+% @lisp: indented, narrowed, typewriter font; @example: same as @lisp.
+%
+% @smallexample and @smalllisp: use smaller fonts.
+% Originally contributed by Pavel@xerox.
+%
+\maketwodispenvs {lisp}{example}{%
+  \nonfillstart
+  \tt\setupmarkupstyle{example}%
+  \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
+  \gobble       % eat return
+}
+% @display/@smalldisplay: same as @lisp except keep current font.
+%
+\makedispenv {display}{%
+  \nonfillstart
+  \gobble
+}
+
+% @format/@smallformat: same as @display except don't narrow margins.
+%
+\makedispenv{format}{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  \gobble
+}
+
+% @flushleft: same as @format, but doesn't obey \SETdispenvsize.
+\envdef\flushleft{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  \gobble
+}
+\let\Eflushleft = \afterenvbreak
+
+% @flushright.
+%
+\envdef\flushright{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  \advance\leftskip by 0pt plus 1fill
+  \gobble
+}
+\let\Eflushright = \afterenvbreak
+
+
+% @raggedright does more-or-less normal line breaking but no right
+% justification.  From plain.tex.
+\envdef\raggedright{%
+  \rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax
+}
+\let\Eraggedright\par
+
+\envdef\raggedleft{%
+  \parindent=0pt \leftskip0pt plus2em
+  \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt
+  \hbadness=10000 % Last line will usually be underfull, so turn off
+                  % badness reporting.
+}
+\let\Eraggedleft\par
+
+\envdef\raggedcenter{%
+  \parindent=0pt \rightskip0pt plus1em \leftskip0pt plus1em
+  \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt
+  \hbadness=10000 % Last line will usually be underfull, so turn off
+                  % badness reporting.
+}
+\let\Eraggedcenter\par
+
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins.  We keep \parskip nonzero in general, since
+% we're doing normal filling.  So, when using \aboveenvbreak and
+% \afterenvbreak, temporarily make \parskip 0.
+%
+\def\quotationstart{%
+  {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+  \parindent=0pt
+  %
+  % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+  \ifx\nonarrowing\relax
+    \advance\leftskip by \lispnarrowing
+    \advance\rightskip by \lispnarrowing
+    \exdentamount = \lispnarrowing
+  \else
+    \let\nonarrowing = \relax
+  \fi
+  \parsearg\quotationlabel
+}
+
+\envdef\quotation{%
+  \setnormaldispenv
+  \quotationstart
+}
+
+\envdef\smallquotation{%
+  \setsmalldispenv
+  \quotationstart
+}
+\let\Esmallquotation = \Equotation
+
+% We have retained a nonzero parskip for the environment, since we're
+% doing normal filling.
+%
+\def\Equotation{%
+  \par
+  \ifx\quotationauthor\undefined\else
+    % indent a bit.
+    \leftline{\kern 2\leftskip \sl ---\quotationauthor}%
+  \fi
+  {\parskip=0pt \afterenvbreak}%
+}
+
+% If we're given an argument, typeset it in bold with a colon after.
+\def\quotationlabel#1{%
+  \def\temp{#1}%
+  \ifx\temp\empty \else
+    {\bf #1: }%
+  \fi
+}
+
+
+% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
+% If we want to allow any <char> as delimiter,
+% we need the curly braces so that makeinfo sees the @verb command, eg:
+% `@verbx...x' would look like the '@verbx' command.  --janneke@gnu.org
+%
+% [Knuth]: Donald Ervin Knuth, 1996.  The TeXbook.
+%
+% [Knuth] p.344; only we need to do the other characters Texinfo sets
+% active too.  Otherwise, they get lost as the first character on a
+% verbatim line.
+\def\dospecials{%
+  \do\ \do\\\do\{\do\}\do\$\do\&%
+  \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~%
+  \do\<\do\>\do\|\do\@\do+\do\"%
+  % Don't do the quotes -- if we do, @set txicodequoteundirected and
+  % @set txicodequotebacktick will not have effect on @verb and
+  % @verbatim, and ?` and !` ligatures won't get disabled.
+  %\do\`\do\'%
+}
+%
+% [Knuth] p. 380
+\def\uncatcodespecials{%
+  \def\do##1{\catcode`##1=\other}\dospecials}
+%
+% Setup for the @verb command.
+%
+% Eight spaces for a tab
+\begingroup
+  \catcode`\^^I=\active
+  \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }}
+\endgroup
+%
+\def\setupverb{%
+  \tt  % easiest (and conventionally used) font for verbatim
+  \def\par{\leavevmode\endgraf}%
+  \setupmarkupstyle{verb}%
+  \tabeightspaces
+  % Respect line breaks,
+  % print special symbols as themselves, and
+  % make each space count
+  % must do in this order:
+  \obeylines \uncatcodespecials \sepspaces
+}
+
+% Setup for the @verbatim environment
+%
+% Real tab expansion
+\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
+%
+\def\starttabbox{\setbox0=\hbox\bgroup}
+%
+\begingroup
+  \catcode`\^^I=\active
+  \gdef\tabexpand{%
+    \catcode`\^^I=\active
+    \def^^I{\leavevmode\egroup
+      \dimen0=\wd0 % the width so far, or since the previous tab
+      \divide\dimen0 by\tabw
+      \multiply\dimen0 by\tabw % compute previous multiple of \tabw
+      \advance\dimen0 by\tabw  % advance to next multiple of \tabw
+      \wd0=\dimen0 \box0 \starttabbox
+    }%
+  }
+\endgroup
+
+% start the verbatim environment.
+\def\setupverbatim{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  % Easiest (and conventionally used) font for verbatim
+  \tt
+  \def\par{\leavevmode\egroup\box0\endgraf}%
+  \tabexpand
+  \setupmarkupstyle{verbatim}%
+  % Respect line breaks,
+  % print special symbols as themselves, and
+  % make each space count
+  % must do in this order:
+  \obeylines \uncatcodespecials \sepspaces
+  \everypar{\starttabbox}%
+}
+
+% Do the @verb magic: verbatim text is quoted by unique
+% delimiter characters.  Before first delimiter expect a
+% right brace, after last delimiter expect closing brace:
+%
+%    \def\doverb'{'<char>#1<char>'}'{#1}
+%
+% [Knuth] p. 382; only eat outer {}
+\begingroup
+  \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other
+  \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
+\endgroup
+%
+\def\verb{\begingroup\setupverb\doverb}
+%
+%
+% Do the @verbatim magic: define the macro \doverbatim so that
+% the (first) argument ends when '@end verbatim' is reached, ie:
+%
+%     \def\doverbatim#1@end verbatim{#1}
+%
+% For Texinfo it's a lot easier than for LaTeX,
+% because texinfo's \verbatim doesn't stop at '\end{verbatim}':
+% we need not redefine '\', '{' and '}'.
+%
+% Inspired by LaTeX's verbatim command set [latex.ltx]
+%
+\begingroup
+  \catcode`\ =\active
+  \obeylines %
+  % ignore everything up to the first ^^M, that's the newline at the end
+  % of the @verbatim input line itself.  Otherwise we get an extra blank
+  % line in the output.
+  \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}%
+  % We really want {...\end verbatim} in the body of the macro, but
+  % without the active space; thus we have to use \xdef and \gobble.
+\endgroup
+%
+\envdef\verbatim{%
+    \setupverbatim\doverbatim
+}
+\let\Everbatim = \afterenvbreak
+
+
+% @verbatiminclude FILE - insert text of file in verbatim environment.
+%
+\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude}
+%
+\def\doverbatiminclude#1{%
+  {%
+    \makevalueexpandable
+    \setupverbatim
+    \indexnofonts       % Allow `@@' and other weird things in file names.
+    \input #1
+    \afterenvbreak
+  }%
+}
+
+% @copying ... @end copying.
+% Save the text away for @insertcopying later.
+%
+% We save the uninterpreted tokens, rather than creating a box.
+% Saving the text in a box would be much easier, but then all the
+% typesetting commands (@smallbook, font changes, etc.) have to be done
+% beforehand -- and a) we want @copying to be done first in the source
+% file; b) letting users define the frontmatter in as flexible order as
+% possible is very desirable.
+%
+\def\copying{\checkenv{}\begingroup\scanargctxt\docopying}
+\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}}
+%
+\def\insertcopying{%
+  \begingroup
+    \parindent = 0pt  % paragraph indentation looks wrong on title page
+    \scanexp\copyingtext
+  \endgroup
+}
+
+
+\message{defuns,}
+% @defun etc.
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+\newcount\defunpenalty
+
+% Start the processing of @deffn:
+\def\startdefun{%
+  \ifnum\lastpenalty<10000
+    \medbreak
+    \defunpenalty=10003 % Will keep this @deffn together with the
+                        % following @def command, see below.
+  \else
+    % If there are two @def commands in a row, we'll have a \nobreak,
+    % which is there to keep the function description together with its
+    % header.  But if there's nothing but headers, we need to allow a
+    % break somewhere.  Check specifically for penalty 10002, inserted
+    % by \printdefunline, instead of 10000, since the sectioning
+    % commands also insert a nobreak penalty, and we don't want to allow
+    % a break between a section heading and a defun.
+    %
+    % As a minor refinement, we avoid "club" headers by signalling
+    % with penalty of 10003 after the very first @deffn in the
+    % sequence (see above), and penalty of 10002 after any following
+    % @def command.
+    \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi
+    %
+    % Similarly, after a section heading, do not allow a break.
+    % But do insert the glue.
+    \medskip  % preceded by discardable penalty, so not a breakpoint
+  \fi
+  %
+  \parindent=0in
+  \advance\leftskip by \defbodyindent
+  \exdentamount=\defbodyindent
+}
+
+\def\dodefunx#1{%
+  % First, check whether we are in the right environment:
+  \checkenv#1%
+  %
+  % As above, allow line break if we have multiple x headers in a row.
+  % It's not a great place, though.
+  \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi
+  %
+  % And now, it's time to reuse the body of the original defun:
+  \expandafter\gobbledefun#1%
+}
+\def\gobbledefun#1\startdefun{}
+
+% \printdefunline \deffnheader{text}
+%
+\def\printdefunline#1#2{%
+  \begingroup
+    % call \deffnheader:
+    #1#2 \endheader
+    % common ending:
+    \interlinepenalty = 10000
+    \advance\rightskip by 0pt plus 1fil
+    \endgraf
+    \nobreak\vskip -\parskip
+    \penalty\defunpenalty  % signal to \startdefun and \dodefunx
+    % Some of the @defun-type tags do not enable magic parentheses,
+    % rendering the following check redundant.  But we don't optimize.
+    \checkparencounts
+  \endgroup
+}
+
+\def\Edefun{\endgraf\medbreak}
+
+% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn;
+% the only thing remaining is to define \deffnheader.
+%
+\def\makedefun#1{%
+  \expandafter\let\csname E#1\endcsname = \Edefun
+  \edef\temp{\noexpand\domakedefun
+    \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}%
+  \temp
+}
+
+% \domakedefun \deffn \deffnx \deffnheader
+%
+% Define \deffn and \deffnx, without parameters.
+% \deffnheader has to be defined explicitly.
+%
+\def\domakedefun#1#2#3{%
+  \envdef#1{%
+    \startdefun
+    \parseargusing\activeparens{\printdefunline#3}%
+  }%
+  \def#2{\dodefunx#1}%
+  \def#3%
+}
+
+%%% Untyped functions:
+
+% @deffn category name args
+\makedefun{deffn}{\deffngeneral{}}
+
+% @deffn category class name args
+\makedefun{defop}#1 {\defopon{#1\ \putwordon}}
+
+% \defopon {category on}class name args
+\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deffngeneral {subind}category name args
+%
+\def\deffngeneral#1#2 #3 #4\endheader{%
+  % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}.
+  \dosubind{fn}{\code{#3}}{#1}%
+  \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
+}
+
+%%% Typed functions:
+
+% @deftypefn category type name args
+\makedefun{deftypefn}{\deftypefngeneral{}}
+
+% @deftypeop category class type name args
+\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}}
+
+% \deftypeopon {category on}class type name args
+\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypefngeneral {subind}category type name args
+%
+\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
+  \dosubind{fn}{\code{#4}}{#1}%
+  \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+%%% Typed variables:
+
+% @deftypevr category type var args
+\makedefun{deftypevr}{\deftypecvgeneral{}}
+
+% @deftypecv category class type var args
+\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}}
+
+% \deftypecvof {category of}class type var args
+\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypecvgeneral {subind}category type var args
+%
+\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{%
+  \dosubind{vr}{\code{#4}}{#1}%
+  \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+%%% Untyped variables:
+
+% @defvr category var args
+\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
+
+% @defcv category class var args
+\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}}
+
+% \defcvof {category of}class var args
+\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
+
+%%% Type:
+% @deftp category name args
+\makedefun{deftp}#1 #2 #3\endheader{%
+  \doind{tp}{\code{#2}}%
+  \defname{#1}{}{#2}\defunargs{#3\unskip}%
+}
+
+% Remaining @defun-like shortcuts:
+\makedefun{defun}{\deffnheader{\putwordDeffunc} }
+\makedefun{defmac}{\deffnheader{\putwordDefmac} }
+\makedefun{defspec}{\deffnheader{\putwordDefspec} }
+\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} }
+\makedefun{defvar}{\defvrheader{\putwordDefvar} }
+\makedefun{defopt}{\defvrheader{\putwordDefopt} }
+\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} }
+\makedefun{defmethod}{\defopon\putwordMethodon}
+\makedefun{deftypemethod}{\deftypeopon\putwordMethodon}
+\makedefun{defivar}{\defcvof\putwordInstanceVariableof}
+\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof}
+
+% \defname, which formats the name of the @def (not the args).
+% #1 is the category, such as "Function".
+% #2 is the return type, if any.
+% #3 is the function name.
+%
+% We are followed by (but not passed) the arguments, if any.
+%
+\def\defname#1#2#3{%
+  % Get the values of \leftskip and \rightskip as they were outside the @def...
+  \advance\leftskip by -\defbodyindent
+  %
+  % How we'll format the type name.  Putting it in brackets helps
+  % distinguish it from the body text that may end up on the next line
+  % just below it.
+  \def\temp{#1}%
+  \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi}
+  %
+  % Figure out line sizes for the paragraph shape.
+  % The first line needs space for \box0; but if \rightskip is nonzero,
+  % we need only space for the part of \box0 which exceeds it:
+  \dimen0=\hsize  \advance\dimen0 by -\wd0  \advance\dimen0 by \rightskip
+  % The continuations:
+  \dimen2=\hsize  \advance\dimen2 by -\defargsindent
+  % (plain.tex says that \dimen1 should be used only as global.)
+  \parshape 2 0in \dimen0 \defargsindent \dimen2
+  %
+  % Put the type name to the right margin.
+  \noindent
+  \hbox to 0pt{%
+    \hfil\box0 \kern-\hsize
+    % \hsize has to be shortened this way:
+    \kern\leftskip
+    % Intentionally do not respect \rightskip, since we need the space.
+  }%
+  %
+  % Allow all lines to be underfull without complaint:
+  \tolerance=10000 \hbadness=10000
+  \exdentamount=\defbodyindent
+  {%
+    % defun fonts. We use typewriter by default (used to be bold) because:
+    % . we're printing identifiers, they should be in tt in principle.
+    % . in languages with many accents, such as Czech or French, it's
+    %   common to leave accents off identifiers.  The result looks ok in
+    %   tt, but exceedingly strange in rm.
+    % . we don't want -- and --- to be treated as ligatures.
+    % . this still does not fix the ?` and !` ligatures, but so far no
+    %   one has made identifiers using them :).
+    \df \tt
+    \def\temp{#2}% return value type
+    \ifx\temp\empty\else \tclose{\temp} \fi
+    #3% output function name
+  }%
+  {\rm\enskip}% hskip 0.5 em of \tenrm
+  %
+  \boldbrax
+  % arguments will be output next, if any.
+}
+
+% Print arguments in slanted roman (not ttsl), inconsistently with using
+% tt for the name.  This is because literal text is sometimes needed in
+% the argument list (groff manual), and ttsl and tt are not very
+% distinguishable.  Prevent hyphenation at `-' chars.
+%
+\def\defunargs#1{%
+  % use sl by default (not ttsl),
+  % tt for the names.
+  \df \sl \hyphenchar\font=0
+  %
+  % On the other hand, if an argument has two dashes (for instance), we
+  % want a way to get ttsl.  Let's try @var for that.
+  \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}%
+  #1%
+  \sl\hyphenchar\font=45
+}
+
+% We want ()&[] to print specially on the defun line.
+%
+\def\activeparens{%
+  \catcode`\(=\active \catcode`\)=\active
+  \catcode`\[=\active \catcode`\]=\active
+  \catcode`\&=\active
+}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+% Be sure that we always have a definition for `(', etc.  For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+{
+  \activeparens
+  \global\let(=\lparen \global\let)=\rparen
+  \global\let[=\lbrack \global\let]=\rbrack
+  \global\let& = \&
+
+  \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+  \gdef\magicamp{\let&=\amprm}
+}
+
+\newcount\parencount
+
+% If we encounter &foo, then turn on ()-hacking afterwards
+\newif\ifampseen
+\def\amprm#1 {\ampseentrue{\bf\&#1 }}
+
+\def\parenfont{%
+  \ifampseen
+    % At the first level, print parens in roman,
+    % otherwise use the default font.
+    \ifnum \parencount=1 \rm \fi
+  \else
+    % The \sf parens (in \boldbrax) actually are a little bolder than
+    % the contained text.  This is especially needed for [ and ] .
+    \sf
+  \fi
+}
+\def\infirstlevel#1{%
+  \ifampseen
+    \ifnum\parencount=1
+      #1%
+    \fi
+  \fi
+}
+\def\bfafterword#1 {#1 \bf}
+
+\def\opnr{%
+  \global\advance\parencount by 1
+  {\parenfont(}%
+  \infirstlevel \bfafterword
+}
+\def\clnr{%
+  {\parenfont)}%
+  \infirstlevel \sl
+  \global\advance\parencount by -1
+}
+
+\newcount\brackcount
+\def\lbrb{%
+  \global\advance\brackcount by 1
+  {\bf[}%
+}
+\def\rbrb{%
+  {\bf]}%
+  \global\advance\brackcount by -1
+}
+
+\def\checkparencounts{%
+  \ifnum\parencount=0 \else \badparencount \fi
+  \ifnum\brackcount=0 \else \badbrackcount \fi
+}
+% these should not use \errmessage; the glibc manual, at least, actually
+% has such constructs (when documenting function pointers).
+\def\badparencount{%
+  \message{Warning: unbalanced parentheses in @def...}%
+  \global\parencount=0
+}
+\def\badbrackcount{%
+  \message{Warning: unbalanced square brackets in @def...}%
+  \global\brackcount=0
+}
+
+
+\message{macros,}
+% @macro.
+
+% To do this right we need a feature of e-TeX, \scantokens,
+% which we arrange to emulate with a temporary file in ordinary TeX.
+\ifx\eTeXversion\undefined
+  \newwrite\macscribble
+  \def\scantokens#1{%
+    \toks0={#1}%
+    \immediate\openout\macscribble=\jobname.tmp
+    \immediate\write\macscribble{\the\toks0}%
+    \immediate\closeout\macscribble
+    \input \jobname.tmp
+  }
+\fi
+
+\def\scanmacro#1{%
+  \begingroup
+    \newlinechar`\^^M
+    \let\xeatspaces\eatspaces
+    % Undo catcode changes of \startcontents and \doprintindex
+    % When called from @insertcopying or (short)caption, we need active
+    % backslash to get it printed correctly.  Previously, we had
+    % \catcode`\\=\other instead.  We'll see whether a problem appears
+    % with macro expansion.                            --kasal, 19aug04
+    \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
+    % ... and \example
+    \spaceisspace
+    %
+    % Append \endinput to make sure that TeX does not see the ending newline.
+    % I've verified that it is necessary both for e-TeX and for ordinary TeX
+    %                                                  --kasal, 29nov03
+    \scantokens{#1\endinput}%
+  \endgroup
+}
+
+\def\scanexp#1{%
+  \edef\temp{\noexpand\scanmacro{#1}}%
+  \temp
+}
+
+\newcount\paramno   % Count of parameters
+\newtoks\macname    % Macro name
+\newif\ifrecursive  % Is it recursive?
+
+% List of all defined macros in the form
+%    \definedummyword\macro1\definedummyword\macro2...
+% Currently is also contains all @aliases; the list can be split
+% if there is a need.
+\def\macrolist{}
+
+% Add the macro to \macrolist
+\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname}
+\def\addtomacrolistxxx#1{%
+     \toks0 = \expandafter{\macrolist\definedummyword#1}%
+     \xdef\macrolist{\the\toks0}%
+}
+
+% Utility routines.
+% 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
+  \csname#2\endcsname
+}
+
+% Trim leading and trailing spaces off a string.
+% Concepts from aro-bend problem 15 (see CTAN).
+{\catcode`\@=11
+\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }}
+\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@}
+\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @}
+\def\unbrace#1{#1}
+\unbrace{\gdef\trim@@@ #1 } #2@{#1}
+}
+
+% Trim a single trailing ^^M off a string.
+{\catcode`\^^M=\other \catcode`\Q=3%
+\gdef\eatcr #1{\eatcra #1Q^^MQ}%
+\gdef\eatcra#1^^MQ{\eatcrb#1Q}%
+\gdef\eatcrb#1Q#2Q{#1}%
+}
+
+% Macro bodies are absorbed as an argument in a context where
+% all characters are catcode 10, 11 or 12, except \ which is active
+% (as in normal texinfo). It is necessary to change the definition of \.
+
+% Non-ASCII encodings make 8-bit characters active, so un-activate
+% them to avoid their expansion.  Must do this non-globally, to
+% confine the change to the current group.
+
+% It's necessary to have hard CRs when the macro is executed. This is
+% done by  making ^^M (\endlinechar) catcode 12 when reading the macro
+% body, and then making it the \newlinechar in \scanmacro.
+
+\def\scanctxt{%
+  \catcode`\"=\other
+  \catcode`\+=\other
+  \catcode`\<=\other
+  \catcode`\>=\other
+  \catcode`\@=\other
+  \catcode`\^=\other
+  \catcode`\_=\other
+  \catcode`\|=\other
+  \catcode`\~=\other
+  \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi
+}
+
+\def\scanargctxt{%
+  \scanctxt
+  \catcode`\\=\other
+  \catcode`\^^M=\other
+}
+
+\def\macrobodyctxt{%
+  \scanctxt
+  \catcode`\{=\other
+  \catcode`\}=\other
+  \catcode`\^^M=\other
+  \usembodybackslash
+}
+
+\def\macroargctxt{%
+  \scanctxt
+  \catcode`\\=\other
+}
+
+% \mbodybackslash is the definition of \ in @macro bodies.
+% It maps \foo\ => \csname macarg.foo\endcsname => #N
+% where N is the macro parameter number.
+% We define \csname macarg.\endcsname to be \realbackslash, so
+% \\ in macro replacement text gets you a backslash.
+
+{\catcode`@=0 @catcode`@\=@active
+ @gdef@usembodybackslash{@let\=@mbodybackslash}
+ @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname}
+}
+\expandafter\def\csname macarg.\endcsname{\realbackslash}
+
+\def\macro{\recursivefalse\parsearg\macroxxx}
+\def\rmacro{\recursivetrue\parsearg\macroxxx}
+
+\def\macroxxx#1{%
+  \getargs{#1}%           now \macname is the macname and \argl the arglist
+  \ifx\argl\empty       % no arguments
+     \paramno=0%
+  \else
+     \expandafter\parsemargdef \argl;%
+  \fi
+  \if1\csname ismacro.\the\macname\endcsname
+     \message{Warning: redefining \the\macname}%
+  \else
+     \expandafter\ifx\csname \the\macname\endcsname \relax
+     \else \errmessage{Macro name \the\macname\space already defined}\fi
+     \global\cslet{macsave.\the\macname}{\the\macname}%
+     \global\expandafter\let\csname ismacro.\the\macname\endcsname=1%
+     \addtomacrolist{\the\macname}%
+  \fi
+  \begingroup \macrobodyctxt
+  \ifrecursive \expandafter\parsermacbody
+  \else \expandafter\parsemacbody
+  \fi}
+
+\parseargdef\unmacro{%
+  \if1\csname ismacro.#1\endcsname
+    \global\cslet{#1}{macsave.#1}%
+    \global\expandafter\let \csname ismacro.#1\endcsname=0%
+    % Remove the macro name from \macrolist:
+    \begingroup
+      \expandafter\let\csname#1\endcsname \relax
+      \let\definedummyword\unmacrodo
+      \xdef\macrolist{\macrolist}%
+    \endgroup
+  \else
+    \errmessage{Macro #1 not defined}%
+  \fi
+}
+
+% Called by \do from \dounmacro on each macro.  The idea is to omit any
+% macro definitions that have been changed to \relax.
+%
+\def\unmacrodo#1{%
+  \ifx #1\relax
+    % remove this
+  \else
+    \noexpand\definedummyword \noexpand#1%
+  \fi
+}
+
+% This makes use of the obscure feature that if the last token of a
+% <parameter list> is #, then the preceding argument is delimited by
+% an opening brace, and that opening brace is not consumed.
+\def\getargs#1{\getargsxxx#1{}}
+\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
+\def\getmacname #1 #2\relax{\macname={#1}}
+\def\getmacargs#1{\def\argl{#1}}
+
+% Parse the optional {params} list.  Set up \paramno and \paramlist
+% so \defmacro knows what to do.  Define \macarg.blah for each blah
+% in the params list, to be ##N where N is the position in that list.
+% That gets used by \mbodybackslash (above).
+
+% We need to get `macro parameter char #' into several definitions.
+% The technique used is stolen from LaTeX:  let \hash be something
+% unexpandable, insert that wherever you need a #, and then redefine
+% it to # just before using the token list produced.
+%
+% The same technique is used to protect \eatspaces till just before
+% the macro is used.
+
+\def\parsemargdef#1;{\paramno=0\def\paramlist{}%
+        \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,}
+\def\parsemargdefxxx#1,{%
+  \if#1;\let\next=\relax
+  \else \let\next=\parsemargdefxxx
+    \advance\paramno by 1%
+    \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
+        {\xeatspaces{\hash\the\paramno}}%
+    \edef\paramlist{\paramlist\hash\the\paramno,}%
+  \fi\next}
+
+% These two commands read recursive and nonrecursive macro bodies.
+% (They're different since rec and nonrec macros end differently.)
+
+\long\def\parsemacbody#1@end macro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\long\def\parsermacbody#1@end rmacro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+
+% This defines the macro itself. There are six cases: recursive and
+% nonrecursive macros of zero, one, and many arguments.
+% Much magic with \expandafter here.
+% \xdef is used so that macro definitions will survive the file
+% they're defined in; @include reads the file inside a group.
+\def\defmacro{%
+  \let\hash=##% convert placeholders to macro parameter chars
+  \ifrecursive
+    \ifcase\paramno
+    % 0
+      \expandafter\xdef\csname\the\macname\endcsname{%
+        \noexpand\scanmacro{\temp}}%
+    \or % 1
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \noexpand\braceorline
+         \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+      \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+         \egroup\noexpand\scanmacro{\temp}}%
+    \else % many
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \noexpand\csname\the\macname xx\endcsname}%
+      \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+          \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+      \expandafter\expandafter
+      \expandafter\xdef
+      \expandafter\expandafter
+        \csname\the\macname xxx\endcsname
+          \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+    \fi
+  \else
+    \ifcase\paramno
+    % 0
+      \expandafter\xdef\csname\the\macname\endcsname{%
+        \noexpand\norecurse{\the\macname}%
+        \noexpand\scanmacro{\temp}\egroup}%
+    \or % 1
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \noexpand\braceorline
+         \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+      \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+        \egroup
+        \noexpand\norecurse{\the\macname}%
+        \noexpand\scanmacro{\temp}\egroup}%
+    \else % many
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \expandafter\noexpand\csname\the\macname xx\endcsname}%
+      \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+          \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+      \expandafter\expandafter
+      \expandafter\xdef
+      \expandafter\expandafter
+      \csname\the\macname xxx\endcsname
+      \paramlist{%
+          \egroup
+          \noexpand\norecurse{\the\macname}%
+          \noexpand\scanmacro{\temp}\egroup}%
+    \fi
+  \fi}
+
+\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
+
+% \braceorline decides whether the next nonwhitespace character is a
+% {.  If so it reads up to the closing }, if not, it reads the whole
+% line.  Whatever was read is then fed to the next control sequence
+% as an argument (by \parsebrace or \parsearg)
+\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx}
+\def\braceorlinexxx{%
+  \ifx\nchar\bgroup\else
+    \expandafter\parsearg
+  \fi \macnamexxx}
+
+
+% @alias.
+% We need some trickery to remove the optional spaces around the equal
+% sign.  Just make them active and then expand them all to nothing.
+\def\alias{\parseargusing\obeyspaces\aliasxxx}
+\def\aliasxxx #1{\aliasyyy#1\relax}
+\def\aliasyyy #1=#2\relax{%
+  {%
+    \expandafter\let\obeyedspace=\empty
+    \addtomacrolist{#1}%
+    \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}%
+  }%
+  \next
+}
+
+
+\message{cross references,}
+
+\newwrite\auxfile
+\newif\ifhavexrefs    % True if xref values are known.
+\newif\ifwarnedxrefs  % True if we warned once that they aren't known.
+
+% @inforef is relatively simple.
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+  node \samp{\ignorespaces#1{}}}
+
+% @node's only job in TeX is to define \lastnode, which is used in
+% cross-references.  The @node line might or might not have commas, and
+% might or might not have spaces before the first comma, like:
+% @node foo , bar , ...
+% We don't want such trailing spaces in the node name.
+%
+\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse}
+%
+% also remove a trailing comma, in case of something like this:
+% @node Help-Cross,  ,  , Cross-refs
+\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse}
+\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}}
+
+\let\nwnode=\node
+\let\lastnode=\empty
+
+% Write a cross-reference definition for the current node.  #1 is the
+% type (Ynumbered, Yappendix, Ynothing).
+%
+\def\donoderef#1{%
+  \ifx\lastnode\empty\else
+    \setref{\lastnode}{#1}%
+    \global\let\lastnode=\empty
+  \fi
+}
+
+% @anchor{NAME} -- define xref target at arbitrary point.
+%
+\newcount\savesfregister
+%
+\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
+\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
+\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
+
+% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
+% anchor), which consists of three parts:
+% 1) NAME-title - the current sectioning name taken from \lastsection,
+%                 or the anchor name.
+% 2) NAME-snt   - section number and type, passed as the SNT arg, or
+%                 empty for anchors.
+% 3) NAME-pg    - the page number.
+%
+% This is called from \donoderef, \anchor, and \dofloat.  In the case of
+% floats, there is an additional part, which is not written here:
+% 4) NAME-lof   - the text as it should appear in a @listoffloats.
+%
+\def\setref#1#2{%
+  \pdfmkdest{#1}%
+  \iflinks
+    {%
+      \atdummies  % preserve commands, but don't expand them
+      \edef\writexrdef##1##2{%
+       \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
+         ##1}{##2}}% these are parameters of \writexrdef
+      }%
+      \toks0 = \expandafter{\lastsection}%
+      \immediate \writexrdef{title}{\the\toks0 }%
+      \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
+      \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, during \shipout
+    }%
+  \fi
+}
+
+% @xref, @pxref, and @ref generate cross-references.  For \xrefX, #1 is
+% the node name, #2 the name of the Info cross-reference, #3 the printed
+% node name, #4 the name of the Info file, #5 the name of the printed
+% manual.  All but the node name can be omitted.
+%
+\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+\def\ref#1{\xrefX[#1,,,,,,,]}
+\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+  \unsepspaces
+  \def\printedmanual{\ignorespaces #5}%
+  \def\printedrefname{\ignorespaces #3}%
+  \setbox1=\hbox{\printedmanual\unskip}%
+  \setbox0=\hbox{\printedrefname\unskip}%
+  \ifdim \wd0 = 0pt
+    % No printed node name was explicitly given.
+    \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax
+      % Use the node name inside the square brackets.
+      \def\printedrefname{\ignorespaces #1}%
+    \else
+      % Use the actual chapter/section title appear inside
+      % the square brackets.  Use the real section title if we have it.
+      \ifdim \wd1 > 0pt
+        % It is in another manual, so we don't have it.
+        \def\printedrefname{\ignorespaces #1}%
+      \else
+        \ifhavexrefs
+          % We know the real title if we have the xref values.
+          \def\printedrefname{\refx{#1-title}{}}%
+        \else
+          % Otherwise just copy the Info node name.
+          \def\printedrefname{\ignorespaces #1}%
+        \fi%
+      \fi
+    \fi
+  \fi
+  %
+  % Make link in pdf output.
+  \ifpdf
+    {\indexnofonts
+     \turnoffactive
+     % This expands tokens, so do it after making catcode changes, so _
+     % etc. don't get their TeX definitions.
+     \getfilename{#4}%
+     %
+     % See comments at \activebackslashdouble.
+     {\activebackslashdouble \xdef\pdfxrefdest{#1}%
+      \backslashparens\pdfxrefdest}%
+     %
+     \leavevmode
+     \startlink attr{/Border [0 0 0]}%
+     \ifnum\filenamelength>0
+       goto file{\the\filename.pdf} name{\pdfxrefdest}%
+     \else
+       goto name{\pdfmkpgn{\pdfxrefdest}}%
+     \fi
+    }%
+    \setcolor{\linkcolor}%
+  \fi
+  %
+  % Float references are printed completely differently: "Figure 1.2"
+  % instead of "[somenode], p.3".  We distinguish them by the
+  % LABEL-title being set to a magic string.
+  {%
+    % Have to otherify everything special to allow the \csname to
+    % include an _ in the xref name, etc.
+    \indexnofonts
+    \turnoffactive
+    \expandafter\global\expandafter\let\expandafter\Xthisreftitle
+      \csname XR#1-title\endcsname
+  }%
+  \iffloat\Xthisreftitle
+    % If the user specified the print name (third arg) to the ref,
+    % print it instead of our usual "Figure 1.2".
+    \ifdim\wd0 = 0pt
+      \refx{#1-snt}{}%
+    \else
+      \printedrefname
+    \fi
+    %
+    % if the user also gave the printed manual name (fifth arg), append
+    % "in MANUALNAME".
+    \ifdim \wd1 > 0pt
+      \space \putwordin{} \cite{\printedmanual}%
+    \fi
+  \else
+    % node/anchor (non-float) references.
+    %
+    % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
+    % insert empty discretionaries after hyphens, which means that it will
+    % not find a line break at a hyphen in a node names.  Since some manuals
+    % are best written with fairly long node names, containing hyphens, this
+    % is a loss.  Therefore, we give the text of the node name again, so it
+    % is as if TeX is seeing it for the first time.
+    \ifdim \wd1 > 0pt
+      \putwordSection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}%
+    \else
+      % _ (for example) has to be the character _ for the purposes of the
+      % control sequence corresponding to the node, but it has to expand
+      % into the usual \leavevmode...\vrule stuff for purposes of
+      % printing. So we \turnoffactive for the \refx-snt, back on for the
+      % printing, back off for the \refx-pg.
+      {\turnoffactive
+       % Only output a following space if the -snt ref is nonempty; for
+       % @unnumbered and @anchor, it won't be.
+       \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
+       \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
+      }%
+      % output the `[mynode]' via a macro so it can be overridden.
+      \xrefprintnodename\printedrefname
+      %
+      % But we always want a comma and a space:
+      ,\space
+      %
+      % output the `page 3'.
+      \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+    \fi
+  \fi
+  \endlink
+\endgroup}
+
+% This macro is called from \xrefX for the `[nodename]' part of xref
+% output.  It's a separate macro only so it can be changed more easily,
+% since square brackets don't work well in some documents.  Particularly
+% one that Bob is working on :).
+%
+\def\xrefprintnodename#1{[#1]}
+
+% Things referred to by \setref.
+%
+\def\Ynothing{}
+\def\Yomitfromtoc{}
+\def\Ynumbered{%
+  \ifnum\secno=0
+    \putwordChapter@tie \the\chapno
+  \else \ifnum\subsecno=0
+    \putwordSection@tie \the\chapno.\the\secno
+  \else \ifnum\subsubsecno=0
+    \putwordSection@tie \the\chapno.\the\secno.\the\subsecno
+  \else
+    \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno
+  \fi\fi\fi
+}
+\def\Yappendix{%
+  \ifnum\secno=0
+     \putwordAppendix@tie @char\the\appendixno{}%
+  \else \ifnum\subsecno=0
+     \putwordSection@tie @char\the\appendixno.\the\secno
+  \else \ifnum\subsubsecno=0
+    \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno
+  \else
+    \putwordSection@tie
+      @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno
+  \fi\fi\fi
+}
+
+% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+% If its value is nonempty, SUFFIX is output afterward.
+%
+\def\refx#1#2{%
+  {%
+    \indexnofonts
+    \otherbackslash
+    \expandafter\global\expandafter\let\expandafter\thisrefX
+      \csname XR#1\endcsname
+  }%
+  \ifx\thisrefX\relax
+    % If not defined, say something at least.
+    \angleleft un\-de\-fined\angleright
+    \iflinks
+      \ifhavexrefs
+        \message{\linenumber Undefined cross reference `#1'.}%
+      \else
+        \ifwarnedxrefs\else
+          \global\warnedxrefstrue
+          \message{Cross reference values unknown; you must run TeX again.}%
+        \fi
+      \fi
+    \fi
+  \else
+    % It's defined, so just use it.
+    \thisrefX
+  \fi
+  #2% Output the suffix in any case.
+}
+
+% This is the macro invoked by entries in the aux file.  Usually it's
+% just a \def (we prepend XR to the control sequence name to avoid
+% collisions).  But if this is a float type, we have more work to do.
+%
+\def\xrdef#1#2{%
+  {% The node name might contain 8-bit characters, which in our current
+   % implementation are changed to commands like @'e.  Don't let these
+   % mess up the control sequence name.
+    \indexnofonts
+    \turnoffactive
+    \xdef\safexrefname{#1}%
+  }%
+  %
+  \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref
+  %
+  % Was that xref control sequence that we just defined for a float?
+  \expandafter\iffloat\csname XR\safexrefname\endcsname
+    % it was a float, and we have the (safe) float type in \iffloattype.
+    \expandafter\let\expandafter\floatlist
+      \csname floatlist\iffloattype\endcsname
+    %
+    % Is this the first time we've seen this float type?
+    \expandafter\ifx\floatlist\relax
+      \toks0 = {\do}% yes, so just \do
+    \else
+      % had it before, so preserve previous elements in list.
+      \toks0 = \expandafter{\floatlist\do}%
+    \fi
+    %
+    % Remember this xref in the control sequence \floatlistFLOATTYPE,
+    % for later use in \listoffloats.
+    \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0
+      {\safexrefname}}%
+  \fi
+}
+
+% Read the last existing aux file, if any.  No error if none exists.
+%
+\def\tryauxfile{%
+  \openin 1 \jobname.aux
+  \ifeof 1 \else
+    \readdatafile{aux}%
+    \global\havexrefstrue
+  \fi
+  \closein 1
+}
+
+\def\setupdatafile{%
+  \catcode`\^^@=\other
+  \catcode`\^^A=\other
+  \catcode`\^^B=\other
+  \catcode`\^^C=\other
+  \catcode`\^^D=\other
+  \catcode`\^^E=\other
+  \catcode`\^^F=\other
+  \catcode`\^^G=\other
+  \catcode`\^^H=\other
+  \catcode`\^^K=\other
+  \catcode`\^^L=\other
+  \catcode`\^^N=\other
+  \catcode`\^^P=\other
+  \catcode`\^^Q=\other
+  \catcode`\^^R=\other
+  \catcode`\^^S=\other
+  \catcode`\^^T=\other
+  \catcode`\^^U=\other
+  \catcode`\^^V=\other
+  \catcode`\^^W=\other
+  \catcode`\^^X=\other
+  \catcode`\^^Z=\other
+  \catcode`\^^[=\other
+  \catcode`\^^\=\other
+  \catcode`\^^]=\other
+  \catcode`\^^^=\other
+  \catcode`\^^_=\other
+  % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc.
+  % in xref tags, i.e., node names.  But since ^^e4 notation isn't
+  % supported in the main text, it doesn't seem desirable.  Furthermore,
+  % that is not enough: for node names that actually contain a ^
+  % character, we would end up writing a line like this: 'xrdef {'hat
+  % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
+  % argument, and \hat is not an expandable control sequence.  It could
+  % all be worked out, but why?  Either we support ^^ or we don't.
+  %
+  % The other change necessary for this was to define \auxhat:
+  % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
+  % and then to call \auxhat in \setq.
+  %
+  \catcode`\^=\other
+  %
+  % Special characters.  Should be turned off anyway, but...
+  \catcode`\~=\other
+  \catcode`\[=\other
+  \catcode`\]=\other
+  \catcode`\"=\other
+  \catcode`\_=\other
+  \catcode`\|=\other
+  \catcode`\<=\other
+  \catcode`\>=\other
+  \catcode`\$=\other
+  \catcode`\#=\other
+  \catcode`\&=\other
+  \catcode`\%=\other
+  \catcode`+=\other % avoid \+ for paranoia even though we've turned it off
+  %
+  % This is to support \ in node names and titles, since the \
+  % characters end up in a \csname.  It's easier than
+  % leaving it active and making its active definition an actual \
+  % character.  What I don't understand is why it works in the *value*
+  % of the xrdef.  Seems like it should be a catcode12 \, and that
+  % should not typeset properly.  But it works, so I'm moving on for
+  % now.  --karl, 15jan04.
+  \catcode`\\=\other
+  %
+  % Make the characters 128-255 be printing characters.
+  {%
+    \count1=128
+    \def\loop{%
+      \catcode\count1=\other
+      \advance\count1 by 1
+      \ifnum \count1<256 \loop \fi
+    }%
+  }%
+  %
+  % @ is our escape character in .aux files, and we need braces.
+  \catcode`\{=1
+  \catcode`\}=2
+  \catcode`\@=0
+}
+
+\def\readdatafile#1{%
+\begingroup
+  \setupdatafile
+  \input\jobname.#1
+\endgroup}
+
+
+\message{insertions,}
+% including footnotes.
+
+\newcount \footnoteno
+
+% The trailing space in the following definition for supereject is
+% vital for proper filling; pages come out unaligned when you do a
+% pagealignmacro call if that space before the closing brace is
+% removed. (Generally, numeric constants should always be followed by a
+% space to prevent strange expansion errors.)
+\def\supereject{\par\penalty -20000\footnoteno =0 }
+
+% @footnotestyle is meaningful for info output only.
+\let\footnotestyle=\comment
+
+{\catcode `\@=11
+%
+% Auto-number footnotes.  Otherwise like plain.
+\gdef\footnote{%
+  \let\indent=\ptexindent
+  \let\noindent=\ptexnoindent
+  \global\advance\footnoteno by \@ne
+  \edef\thisfootno{$^{\the\footnoteno}$}%
+  %
+  % In case the footnote comes at the end of a sentence, preserve the
+  % extra spacing after we do the footnote number.
+  \let\@sf\empty
+  \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi
+  %
+  % Remove inadvertent blank space before typesetting the footnote number.
+  \unskip
+  \thisfootno\@sf
+  \dofootnote
+}%
+
+% Don't bother with the trickery in plain.tex to not require the
+% footnote text as a parameter.  Our footnotes don't need to be so general.
+%
+% Oh yes, they do; otherwise, @ifset (and anything else that uses
+% \parseargline) fails inside footnotes because the tokens are fixed when
+% the footnote is read.  --karl, 16nov96.
+%
+\gdef\dofootnote{%
+  \insert\footins\bgroup
+  % We want to typeset this text as a normal paragraph, even if the
+  % footnote reference occurs in (for example) a display environment.
+  % So reset some parameters.
+  \hsize=\pagewidth
+  \interlinepenalty\interfootnotelinepenalty
+  \splittopskip\ht\strutbox % top baseline for broken footnotes
+  \splitmaxdepth\dp\strutbox
+  \floatingpenalty\@MM
+  \leftskip\z@skip
+  \rightskip\z@skip
+  \spaceskip\z@skip
+  \xspaceskip\z@skip
+  \parindent\defaultparindent
+  %
+  \smallfonts \rm
+  %
+  % Because we use hanging indentation in footnotes, a @noindent appears
+  % to exdent this text, so make it be a no-op.  makeinfo does not use
+  % hanging indentation so @noindent can still be needed within footnote
+  % text after an @example or the like (not that this is good style).
+  \let\noindent = \relax
+  %
+  % Hang the footnote text off the number.  Use \everypar in case the
+  % footnote extends for more than one paragraph.
+  \everypar = {\hang}%
+  \textindent{\thisfootno}%
+  %
+  % Don't crash into the line above the footnote text.  Since this
+  % expands into a box, it must come within the paragraph, lest it
+  % provide a place where TeX can split the footnote.
+  \footstrut
+  \futurelet\next\fo@t
+}
+}%end \catcode `\@=11
+
+% In case a @footnote appears in a vbox, save the footnote text and create
+% the real \insert just after the vbox finished.  Otherwise, the insertion
+% would be lost.
+% Similarly, if a @footnote appears inside an alignment, save the footnote
+% text to a box and make the \insert when a row of the table is finished.
+% And the same can be done for other insert classes.  --kasal, 16nov03.
+
+% Replace the \insert primitive by a cheating macro.
+% Deeper inside, just make sure that the saved insertions are not spilled
+% out prematurely.
+%
+\def\startsavinginserts{%
+  \ifx \insert\ptexinsert
+    \let\insert\saveinsert
+  \else
+    \let\checkinserts\relax
+  \fi
+}
+
+% This \insert replacement works for both \insert\footins{foo} and
+% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}.
+%
+\def\saveinsert#1{%
+  \edef\next{\noexpand\savetobox \makeSAVEname#1}%
+  \afterassignment\next
+  % swallow the left brace
+  \let\temp =
+}
+\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}}
+\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1}
+
+\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi}
+
+\def\placesaveins#1{%
+  \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname
+    {\box#1}%
+}
+
+% eat @SAVE -- beware, all of them have catcode \other:
+{
+  \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials  %  ;-)
+  \gdef\gobblesave @SAVE{}
+}
+
+% initialization:
+\def\newsaveins #1{%
+  \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}%
+  \next
+}
+\def\newsaveinsX #1{%
+  \csname newbox\endcsname #1%
+  \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts
+    \checksaveins #1}%
+}
+
+% initialize:
+\let\checkinserts\empty
+\newsaveins\footins
+\newsaveins\margin
+
+
+% @image.  We use the macros from epsf.tex to support this.
+% If epsf.tex is not installed and @image is used, we complain.
+%
+% Check for and read epsf.tex up front.  If we read it only at @image
+% time, we might be inside a group, and then its definitions would get
+% undone and the next image would fail.
+\openin 1 = epsf.tex
+\ifeof 1 \else
+  % Do not bother showing banner with epsf.tex v2.7k (available in
+  % doc/epsf.tex and on ctan).
+  \def\epsfannounce{\toks0 = }%
+  \input epsf.tex
+\fi
+\closein 1
+%
+% We will only complain once about lack of epsf.tex.
+\newif\ifwarnednoepsf
+\newhelp\noepsfhelp{epsf.tex must be installed for images to
+  work.  It is also included in the Texinfo distribution, or you can get
+  it from ftp://tug.org/tex/epsf.tex.}
+%
+\def\image#1{%
+  \ifx\epsfbox\undefined
+    \ifwarnednoepsf \else
+      \errhelp = \noepsfhelp
+      \errmessage{epsf.tex not found, images will be ignored}%
+      \global\warnednoepsftrue
+    \fi
+  \else
+    \imagexxx #1,,,,,\finish
+  \fi
+}
+%
+% Arguments to @image:
+% #1 is (mandatory) image filename; we tack on .eps extension.
+% #2 is (optional) width, #3 is (optional) height.
+% #4 is (ignored optional) html alt text.
+% #5 is (ignored optional) extension.
+% #6 is just the usual extra ignored arg for parsing this stuff.
+\newif\ifimagevmode
+\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
+  \catcode`\^^M = 5     % in case we're inside an example
+  \normalturnoffactive  % allow _ et al. in names
+  % If the image is by itself, center it.
+  \ifvmode
+    \imagevmodetrue
+    \nobreak\medskip
+    % Usually we'll have text after the image which will insert
+    % \parskip glue, so insert it here too to equalize the space
+    % above and below.
+    \nobreak\vskip\parskip
+    \nobreak
+  \fi
+  %
+  % Leave vertical mode so that indentation from an enclosing
+  % environment such as @quotation is respected.  On the other hand, if
+  % it's at the top level, we don't want the normal paragraph indentation.
+  \noindent
+  %
+  % Output the image.
+  \ifpdf
+    \dopdfimage{#1}{#2}{#3}%
+  \else
+    % \epsfbox itself resets \epsf?size at each figure.
+    \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi
+    \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi
+    \epsfbox{#1.eps}%
+  \fi
+  %
+  \ifimagevmode \medskip \fi  % space after the standalone image
+\endgroup}
+
+
+% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables,
+% etc.  We don't actually implement floating yet, we always include the
+% float "here".  But it seemed the best name for the future.
+%
+\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish}
+
+% There may be a space before second and/or third parameter; delete it.
+\def\eatcommaspace#1, {#1,}
+
+% #1 is the optional FLOATTYPE, the text label for this float, typically
+% "Figure", "Table", "Example", etc.  Can't contain commas.  If omitted,
+% this float will not be numbered and cannot be referred to.
+%
+% #2 is the optional xref label.  Also must be present for the float to
+% be referable.
+%
+% #3 is the optional positioning argument; for now, it is ignored.  It
+% will somehow specify the positions allowed to float to (here, top, bottom).
+%
+% We keep a separate counter for each FLOATTYPE, which we reset at each
+% chapter-level command.
+\let\resetallfloatnos=\empty
+%
+\def\dofloat#1,#2,#3,#4\finish{%
+  \let\thiscaption=\empty
+  \let\thisshortcaption=\empty
+  %
+  % don't lose footnotes inside @float.
+  %
+  % BEWARE: when the floats start float, we have to issue warning whenever an
+  % insert appears inside a float which could possibly float. --kasal, 26may04
+  %
+  \startsavinginserts
+  %
+  % We can't be used inside a paragraph.
+  \par
+  %
+  \vtop\bgroup
+    \def\floattype{#1}%
+    \def\floatlabel{#2}%
+    \def\floatloc{#3}% we do nothing with this yet.
+    %
+    \ifx\floattype\empty
+      \let\safefloattype=\empty
+    \else
+      {%
+        % the floattype might have accents or other special characters,
+        % but we need to use it in a control sequence name.
+        \indexnofonts
+        \turnoffactive
+        \xdef\safefloattype{\floattype}%
+      }%
+    \fi
+    %
+    % If label is given but no type, we handle that as the empty type.
+    \ifx\floatlabel\empty \else
+      % We want each FLOATTYPE to be numbered separately (Figure 1,
+      % Table 1, Figure 2, ...).  (And if no label, no number.)
+      %
+      \expandafter\getfloatno\csname\safefloattype floatno\endcsname
+      \global\advance\floatno by 1
+      %
+      {%
+        % This magic value for \lastsection is output by \setref as the
+        % XREFLABEL-title value.  \xrefX uses it to distinguish float
+        % labels (which have a completely different output format) from
+        % node and anchor labels.  And \xrdef uses it to construct the
+        % lists of floats.
+        %
+        \edef\lastsection{\floatmagic=\safefloattype}%
+        \setref{\floatlabel}{Yfloat}%
+      }%
+    \fi
+    %
+    % start with \parskip glue, I guess.
+    \vskip\parskip
+    %
+    % Don't suppress indentation if a float happens to start a section.
+    \restorefirstparagraphindent
+}
+
+% we have these possibilities:
+% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap
+% @float Foo,lbl & no caption:    Foo 1.1
+% @float Foo & @caption{Cap}:     Foo: Cap
+% @float Foo & no caption:        Foo
+% @float ,lbl & Caption{Cap}:     1.1: Cap
+% @float ,lbl & no caption:       1.1
+% @float & @caption{Cap}:         Cap
+% @float & no caption:
+%
+\def\Efloat{%
+    \let\floatident = \empty
+    %
+    % In all cases, if we have a float type, it comes first.
+    \ifx\floattype\empty \else \def\floatident{\floattype}\fi
+    %
+    % If we have an xref label, the number comes next.
+    \ifx\floatlabel\empty \else
+      \ifx\floattype\empty \else % if also had float type, need tie first.
+        \appendtomacro\floatident{\tie}%
+      \fi
+      % the number.
+      \appendtomacro\floatident{\chaplevelprefix\the\floatno}%
+    \fi
+    %
+    % Start the printed caption with what we've constructed in
+    % \floatident, but keep it separate; we need \floatident again.
+    \let\captionline = \floatident
+    %
+    \ifx\thiscaption\empty \else
+      \ifx\floatident\empty \else
+       \appendtomacro\captionline{: }% had ident, so need a colon between
+      \fi
+      %
+      % caption text.
+      \appendtomacro\captionline{\scanexp\thiscaption}%
+    \fi
+    %
+    % If we have anything to print, print it, with space before.
+    % Eventually this needs to become an \insert.
+    \ifx\captionline\empty \else
+      \vskip.5\parskip
+      \captionline
+      %
+      % Space below caption.
+      \vskip\parskip
+    \fi
+    %
+    % If have an xref label, write the list of floats info.  Do this
+    % after the caption, to avoid chance of it being a breakpoint.
+    \ifx\floatlabel\empty \else
+      % Write the text that goes in the lof to the aux file as
+      % \floatlabel-lof.  Besides \floatident, we include the short
+      % caption if specified, else the full caption if specified, else nothing.
+      {%
+        \atdummies
+        %
+        % since we read the caption text in the macro world, where ^^M
+        % is turned into a normal character, we have to scan it back, so
+        % we don't write the literal three characters "^^M" into the aux file.
+       \scanexp{%
+         \xdef\noexpand\gtemp{%
+           \ifx\thisshortcaption\empty
+             \thiscaption
+           \else
+             \thisshortcaption
+           \fi
+         }%
+       }%
+        \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident
+         \ifx\gtemp\empty \else : \gtemp \fi}}%
+      }%
+    \fi
+  \egroup  % end of \vtop
+  %
+  % place the captured inserts
+  %
+  % BEWARE: when the floats start floating, we have to issue warning
+  % whenever an insert appears inside a float which could possibly
+  % float. --kasal, 26may04
+  %
+  \checkinserts
+}
+
+% Append the tokens #2 to the definition of macro #1, not expanding either.
+%
+\def\appendtomacro#1#2{%
+  \expandafter\def\expandafter#1\expandafter{#1#2}%
+}
+
+% @caption, @shortcaption
+%
+\def\caption{\docaption\thiscaption}
+\def\shortcaption{\docaption\thisshortcaption}
+\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption}
+\def\defcaption#1#2{\egroup \def#1{#2}}
+
+% The parameter is the control sequence identifying the counter we are
+% going to use.  Create it if it doesn't exist and assign it to \floatno.
+\def\getfloatno#1{%
+  \ifx#1\relax
+      % Haven't seen this figure type before.
+      \csname newcount\endcsname #1%
+      %
+      % Remember to reset this floatno at the next chap.
+      \expandafter\gdef\expandafter\resetallfloatnos
+        \expandafter{\resetallfloatnos #1=0 }%
+  \fi
+  \let\floatno#1%
+}
+
+% \setref calls this to get the XREFLABEL-snt value.  We want an @xref
+% to the FLOATLABEL to expand to "Figure 3.1".  We call \setref when we
+% first read the @float command.
+%
+\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}%
+
+% Magic string used for the XREFLABEL-title value, so \xrefX can
+% distinguish floats from other xref types.
+\def\floatmagic{!!float!!}
+
+% #1 is the control sequence we are passed; we expand into a conditional
+% which is true if #1 represents a float ref.  That is, the magic
+% \lastsection value which we \setref above.
+%
+\def\iffloat#1{\expandafter\doiffloat#1==\finish}
+%
+% #1 is (maybe) the \floatmagic string.  If so, #2 will be the
+% (safe) float type for this float.  We set \iffloattype to #2.
+%
+\def\doiffloat#1=#2=#3\finish{%
+  \def\temp{#1}%
+  \def\iffloattype{#2}%
+  \ifx\temp\floatmagic
+}
+
+% @listoffloats FLOATTYPE - print a list of floats like a table of contents.
+%
+\parseargdef\listoffloats{%
+  \def\floattype{#1}% floattype
+  {%
+    % the floattype might have accents or other special characters,
+    % but we need to use it in a control sequence name.
+    \indexnofonts
+    \turnoffactive
+    \xdef\safefloattype{\floattype}%
+  }%
+  %
+  % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE.
+  \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax
+    \ifhavexrefs
+      % if the user said @listoffloats foo but never @float foo.
+      \message{\linenumber No `\safefloattype' floats to list.}%
+    \fi
+  \else
+    \begingroup
+      \leftskip=\tocindent  % indent these entries like a toc
+      \let\do=\listoffloatsdo
+      \csname floatlist\safefloattype\endcsname
+    \endgroup
+  \fi
+}
+
+% This is called on each entry in a list of floats.  We're passed the
+% xref label, in the form LABEL-title, which is how we save it in the
+% aux file.  We strip off the -title and look up \XRLABEL-lof, which
+% has the text we're supposed to typeset here.
+%
+% Figures without xref labels will not be included in the list (since
+% they won't appear in the aux file).
+%
+\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish}
+\def\listoffloatsdoentry#1-title\finish{{%
+  % Can't fully expand XR#1-lof because it can contain anything.  Just
+  % pass the control sequence.  On the other hand, XR#1-pg is just the
+  % page number, and we want to fully expand that so we can get a link
+  % in pdf output.
+  \toksA = \expandafter{\csname XR#1-lof\endcsname}%
+  %
+  % use the same \entry macro we use to generate the TOC and index.
+  \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}%
+  \writeentry
+}}
+
+
+\message{localization,}
+
+% For single-language documents, @documentlanguage is usually given very
+% early, just after @documentencoding.  Single argument is the language
+% (de) or locale (de_DE) abbreviation.
+%
+{
+  \catcode`\_ = \active
+  \globaldefs=1
+\parseargdef\documentlanguage{\begingroup
+  \let_=\normalunderscore  % normal _ character for filenames
+  \tex % read txi-??.tex file in plain TeX.
+    % Read the file by the name they passed if it exists.
+    \openin 1 txi-#1.tex
+    \ifeof 1
+      \documentlanguagetrywithoutunderscore{#1_\finish}%
+    \else
+      \globaldefs = 1  % everything in the txi-LL files needs to persist
+      \input txi-#1.tex
+    \fi
+    \closein 1
+  \endgroup % end raw TeX
+\endgroup}
+%
+% If they passed de_DE, and txi-de_DE.tex doesn't exist,
+% try txi-de.tex.
+%
+\gdef\documentlanguagetrywithoutunderscore#1_#2\finish{%
+  \openin 1 txi-#1.tex
+  \ifeof 1
+    \errhelp = \nolanghelp
+    \errmessage{Cannot read language file txi-#1.tex}%
+  \else
+    \globaldefs = 1  % everything in the txi-LL files needs to persist
+    \input txi-#1.tex
+  \fi
+  \closein 1
+}
+}% end of special _ catcode
+%
+\newhelp\nolanghelp{The given language definition file cannot be found or
+is empty.  Maybe you need to install it?  Putting it in the current
+directory should work if nowhere else does.}
+
+% This macro is called from txi-??.tex files; the first argument is the
+% \language name to set (without the "\lang@" prefix), the second and
+% third args are \{left,right}hyphenmin.
+%
+% The language names to pass are determined when the format is built.
+% See the etex.log file created at that time, e.g.,
+% /usr/local/texlive/2008/texmf-var/web2c/pdftex/etex.log.
+%
+% With TeX Live 2008, etex now includes hyphenation patterns for all
+% available languages.  This means we can support hyphenation in
+% Texinfo, at least to some extent.  (This still doesn't solve the
+% accented characters problem.)
+%
+\catcode`@=11
+\def\txisetlanguage#1#2#3{%
+  % do not set the language if the name is undefined in the current TeX.
+  \expandafter\ifx\csname lang@#1\endcsname \relax
+    \message{no patterns for #1}%
+  \else
+    \global\language = \csname lang@#1\endcsname
+  \fi
+  % but there is no harm in adjusting the hyphenmin values regardless.
+  \global\lefthyphenmin = #2\relax
+  \global\righthyphenmin = #3\relax
+}
+
+% Helpers for encodings.
+% Set the catcode of characters 128 through 255 to the specified number.
+%
+\def\setnonasciicharscatcode#1{%
+   \count255=128
+   \loop\ifnum\count255<256
+      \global\catcode\count255=#1\relax
+      \advance\count255 by 1
+   \repeat
+}
+
+\def\setnonasciicharscatcodenonglobal#1{%
+   \count255=128
+   \loop\ifnum\count255<256
+      \catcode\count255=#1\relax
+      \advance\count255 by 1
+   \repeat
+}
+
+% @documentencoding sets the definition of non-ASCII characters
+% according to the specified encoding.
+%
+\parseargdef\documentencoding{%
+  % Encoding being declared for the document.
+  \def\declaredencoding{\csname #1.enc\endcsname}%
+  %
+  % Supported encodings: names converted to tokens in order to be able
+  % to compare them with \ifx.
+  \def\ascii{\csname US-ASCII.enc\endcsname}%
+  \def\latnine{\csname ISO-8859-15.enc\endcsname}%
+  \def\latone{\csname ISO-8859-1.enc\endcsname}%
+  \def\lattwo{\csname ISO-8859-2.enc\endcsname}%
+  \def\utfeight{\csname UTF-8.enc\endcsname}%
+  %
+  \ifx \declaredencoding \ascii
+     \asciichardefs
+  %
+  \else \ifx \declaredencoding \lattwo
+     \setnonasciicharscatcode\active
+     \lattwochardefs
+  %
+  \else \ifx \declaredencoding \latone
+     \setnonasciicharscatcode\active
+     \latonechardefs
+  %
+  \else \ifx \declaredencoding \latnine
+     \setnonasciicharscatcode\active
+     \latninechardefs
+  %
+  \else \ifx \declaredencoding \utfeight
+     \setnonasciicharscatcode\active
+     \utfeightchardefs
+  %
+  \else
+    \message{Unknown document encoding #1, ignoring.}%
+  %
+  \fi % utfeight
+  \fi % latnine
+  \fi % latone
+  \fi % lattwo
+  \fi % ascii
+}
+
+% A message to be logged when using a character that isn't available
+% the default font encoding (OT1).
+%
+\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}}
+
+% Take account of \c (plain) vs. \, (Texinfo) difference.
+\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi}
+
+% First, make active non-ASCII characters in order for them to be
+% correctly categorized when TeX reads the replacement text of
+% macros containing the character definitions.
+\setnonasciicharscatcode\active
+%
+% Latin1 (ISO-8859-1) character definitions.
+\def\latonechardefs{%
+  \gdef^^a0{~}
+  \gdef^^a1{\exclamdown}
+  \gdef^^a2{\missingcharmsg{CENT SIGN}}
+  \gdef^^a3{{\pounds}}
+  \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+  \gdef^^a5{\missingcharmsg{YEN SIGN}}
+  \gdef^^a6{\missingcharmsg{BROKEN BAR}}
+  \gdef^^a7{\S}
+  \gdef^^a8{\"{}}
+  \gdef^^a9{\copyright}
+  \gdef^^aa{\ordf}
+  \gdef^^ab{\guillemetleft}
+  \gdef^^ac{$\lnot$}
+  \gdef^^ad{\-}
+  \gdef^^ae{\registeredsymbol}
+  \gdef^^af{\={}}
+  %
+  \gdef^^b0{\textdegree}
+  \gdef^^b1{$\pm$}
+  \gdef^^b2{$^2$}
+  \gdef^^b3{$^3$}
+  \gdef^^b4{\'{}}
+  \gdef^^b5{$\mu$}
+  \gdef^^b6{\P}
+  %
+  \gdef^^b7{$^.$}
+  \gdef^^b8{\cedilla\ }
+  \gdef^^b9{$^1$}
+  \gdef^^ba{\ordm}
+  %
+  \gdef^^bb{\guilletright}
+  \gdef^^bc{$1\over4$}
+  \gdef^^bd{$1\over2$}
+  \gdef^^be{$3\over4$}
+  \gdef^^bf{\questiondown}
+  %
+  \gdef^^c0{\`A}
+  \gdef^^c1{\'A}
+  \gdef^^c2{\^A}
+  \gdef^^c3{\~A}
+  \gdef^^c4{\"A}
+  \gdef^^c5{\ringaccent A}
+  \gdef^^c6{\AE}
+  \gdef^^c7{\cedilla C}
+  \gdef^^c8{\`E}
+  \gdef^^c9{\'E}
+  \gdef^^ca{\^E}
+  \gdef^^cb{\"E}
+  \gdef^^cc{\`I}
+  \gdef^^cd{\'I}
+  \gdef^^ce{\^I}
+  \gdef^^cf{\"I}
+  %
+  \gdef^^d0{\DH}
+  \gdef^^d1{\~N}
+  \gdef^^d2{\`O}
+  \gdef^^d3{\'O}
+  \gdef^^d4{\^O}
+  \gdef^^d5{\~O}
+  \gdef^^d6{\"O}
+  \gdef^^d7{$\times$}
+  \gdef^^d8{\O}
+  \gdef^^d9{\`U}
+  \gdef^^da{\'U}
+  \gdef^^db{\^U}
+  \gdef^^dc{\"U}
+  \gdef^^dd{\'Y}
+  \gdef^^de{\TH}
+  \gdef^^df{\ss}
+  %
+  \gdef^^e0{\`a}
+  \gdef^^e1{\'a}
+  \gdef^^e2{\^a}
+  \gdef^^e3{\~a}
+  \gdef^^e4{\"a}
+  \gdef^^e5{\ringaccent a}
+  \gdef^^e6{\ae}
+  \gdef^^e7{\cedilla c}
+  \gdef^^e8{\`e}
+  \gdef^^e9{\'e}
+  \gdef^^ea{\^e}
+  \gdef^^eb{\"e}
+  \gdef^^ec{\`{\dotless i}}
+  \gdef^^ed{\'{\dotless i}}
+  \gdef^^ee{\^{\dotless i}}
+  \gdef^^ef{\"{\dotless i}}
+  %
+  \gdef^^f0{\dh}
+  \gdef^^f1{\~n}
+  \gdef^^f2{\`o}
+  \gdef^^f3{\'o}
+  \gdef^^f4{\^o}
+  \gdef^^f5{\~o}
+  \gdef^^f6{\"o}
+  \gdef^^f7{$\div$}
+  \gdef^^f8{\o}
+  \gdef^^f9{\`u}
+  \gdef^^fa{\'u}
+  \gdef^^fb{\^u}
+  \gdef^^fc{\"u}
+  \gdef^^fd{\'y}
+  \gdef^^fe{\th}
+  \gdef^^ff{\"y}
+}
+
+% Latin9 (ISO-8859-15) encoding character definitions.
+\def\latninechardefs{%
+  % Encoding is almost identical to Latin1.
+  \latonechardefs
+  %
+  \gdef^^a4{\euro}
+  \gdef^^a6{\v S}
+  \gdef^^a8{\v s}
+  \gdef^^b4{\v Z}
+  \gdef^^b8{\v z}
+  \gdef^^bc{\OE}
+  \gdef^^bd{\oe}
+  \gdef^^be{\"Y}
+}
+
+% Latin2 (ISO-8859-2) character definitions.
+\def\lattwochardefs{%
+  \gdef^^a0{~}
+  \gdef^^a1{\ogonek{A}}
+  \gdef^^a2{\u{}}
+  \gdef^^a3{\L}
+  \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+  \gdef^^a5{\v L}
+  \gdef^^a6{\'S}
+  \gdef^^a7{\S}
+  \gdef^^a8{\"{}}
+  \gdef^^a9{\v S}
+  \gdef^^aa{\cedilla S}
+  \gdef^^ab{\v T}
+  \gdef^^ac{\'Z}
+  \gdef^^ad{\-}
+  \gdef^^ae{\v Z}
+  \gdef^^af{\dotaccent Z}
+  %
+  \gdef^^b0{\textdegree}
+  \gdef^^b1{\ogonek{a}}
+  \gdef^^b2{\ogonek{ }}
+  \gdef^^b3{\l}
+  \gdef^^b4{\'{}}
+  \gdef^^b5{\v l}
+  \gdef^^b6{\'s}
+  \gdef^^b7{\v{}}
+  \gdef^^b8{\cedilla\ }
+  \gdef^^b9{\v s}
+  \gdef^^ba{\cedilla s}
+  \gdef^^bb{\v t}
+  \gdef^^bc{\'z}
+  \gdef^^bd{\H{}}
+  \gdef^^be{\v z}
+  \gdef^^bf{\dotaccent z}
+  %
+  \gdef^^c0{\'R}
+  \gdef^^c1{\'A}
+  \gdef^^c2{\^A}
+  \gdef^^c3{\u A}
+  \gdef^^c4{\"A}
+  \gdef^^c5{\'L}
+  \gdef^^c6{\'C}
+  \gdef^^c7{\cedilla C}
+  \gdef^^c8{\v C}
+  \gdef^^c9{\'E}
+  \gdef^^ca{\ogonek{E}}
+  \gdef^^cb{\"E}
+  \gdef^^cc{\v E}
+  \gdef^^cd{\'I}
+  \gdef^^ce{\^I}
+  \gdef^^cf{\v D}
+  %
+  \gdef^^d0{\DH}
+  \gdef^^d1{\'N}
+  \gdef^^d2{\v N}
+  \gdef^^d3{\'O}
+  \gdef^^d4{\^O}
+  \gdef^^d5{\H O}
+  \gdef^^d6{\"O}
+  \gdef^^d7{$\times$}
+  \gdef^^d8{\v R}
+  \gdef^^d9{\ringaccent U}
+  \gdef^^da{\'U}
+  \gdef^^db{\H U}
+  \gdef^^dc{\"U}
+  \gdef^^dd{\'Y}
+  \gdef^^de{\cedilla T}
+  \gdef^^df{\ss}
+  %
+  \gdef^^e0{\'r}
+  \gdef^^e1{\'a}
+  \gdef^^e2{\^a}
+  \gdef^^e3{\u a}
+  \gdef^^e4{\"a}
+  \gdef^^e5{\'l}
+  \gdef^^e6{\'c}
+  \gdef^^e7{\cedilla c}
+  \gdef^^e8{\v c}
+  \gdef^^e9{\'e}
+  \gdef^^ea{\ogonek{e}}
+  \gdef^^eb{\"e}
+  \gdef^^ec{\v e}
+  \gdef^^ed{\'\i}
+  \gdef^^ee{\^\i}
+  \gdef^^ef{\v d}
+  %
+  \gdef^^f0{\dh}
+  \gdef^^f1{\'n}
+  \gdef^^f2{\v n}
+  \gdef^^f3{\'o}
+  \gdef^^f4{\^o}
+  \gdef^^f5{\H o}
+  \gdef^^f6{\"o}
+  \gdef^^f7{$\div$}
+  \gdef^^f8{\v r}
+  \gdef^^f9{\ringaccent u}
+  \gdef^^fa{\'u}
+  \gdef^^fb{\H u}
+  \gdef^^fc{\"u}
+  \gdef^^fd{\'y}
+  \gdef^^fe{\cedilla t}
+  \gdef^^ff{\dotaccent{}}
+}
+
+% UTF-8 character definitions.
+%
+% This code to support UTF-8 is based on LaTeX's utf8.def, with some
+% changes for Texinfo conventions.  It is included here under the GPL by
+% permission from Frank Mittelbach and the LaTeX team.
+%
+\newcount\countUTFx
+\newcount\countUTFy
+\newcount\countUTFz
+
+\gdef\UTFviiiTwoOctets#1#2{\expandafter
+   \UTFviiiDefined\csname u8:#1\string #2\endcsname}
+%
+\gdef\UTFviiiThreeOctets#1#2#3{\expandafter
+   \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname}
+%
+\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter
+   \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname}
+
+\gdef\UTFviiiDefined#1{%
+  \ifx #1\relax
+    \message{\linenumber Unicode char \string #1 not defined for Texinfo}%
+  \else
+    \expandafter #1%
+  \fi
+}
+
+\begingroup
+  \catcode`\~13
+  \catcode`\"12
+
+  \def\UTFviiiLoop{%
+    \global\catcode\countUTFx\active
+    \uccode`\~\countUTFx
+    \uppercase\expandafter{\UTFviiiTmp}%
+    \advance\countUTFx by 1
+    \ifnum\countUTFx < \countUTFy
+      \expandafter\UTFviiiLoop
+    \fi}
+
+  \countUTFx = "C2
+  \countUTFy = "E0
+  \def\UTFviiiTmp{%
+    \xdef~{\noexpand\UTFviiiTwoOctets\string~}}
+  \UTFviiiLoop
+
+  \countUTFx = "E0
+  \countUTFy = "F0
+  \def\UTFviiiTmp{%
+    \xdef~{\noexpand\UTFviiiThreeOctets\string~}}
+  \UTFviiiLoop
+
+  \countUTFx = "F0
+  \countUTFy = "F4
+  \def\UTFviiiTmp{%
+    \xdef~{\noexpand\UTFviiiFourOctets\string~}}
+  \UTFviiiLoop
+\endgroup
+
+\begingroup
+  \catcode`\"=12
+  \catcode`\<=12
+  \catcode`\.=12
+  \catcode`\,=12
+  \catcode`\;=12
+  \catcode`\!=12
+  \catcode`\~=13
+
+  \gdef\DeclareUnicodeCharacter#1#2{%
+    \countUTFz = "#1\relax
+    \wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}%
+    \begingroup
+      \parseXMLCharref
+      \def\UTFviiiTwoOctets##1##2{%
+        \csname u8:##1\string ##2\endcsname}%
+      \def\UTFviiiThreeOctets##1##2##3{%
+        \csname u8:##1\string ##2\string ##3\endcsname}%
+      \def\UTFviiiFourOctets##1##2##3##4{%
+        \csname u8:##1\string ##2\string ##3\string ##4\endcsname}%
+      \expandafter\expandafter\expandafter\expandafter
+       \expandafter\expandafter\expandafter
+       \gdef\UTFviiiTmp{#2}%
+    \endgroup}
+
+  \gdef\parseXMLCharref{%
+    \ifnum\countUTFz < "A0\relax
+      \errhelp = \EMsimple
+      \errmessage{Cannot define Unicode char value < 00A0}%
+    \else\ifnum\countUTFz < "800\relax
+      \parseUTFviiiA,%
+      \parseUTFviiiB C\UTFviiiTwoOctets.,%
+    \else\ifnum\countUTFz < "10000\relax
+      \parseUTFviiiA;%
+      \parseUTFviiiA,%
+      \parseUTFviiiB E\UTFviiiThreeOctets.{,;}%
+    \else
+      \parseUTFviiiA;%
+      \parseUTFviiiA,%
+      \parseUTFviiiA!%
+      \parseUTFviiiB F\UTFviiiFourOctets.{!,;}%
+    \fi\fi\fi
+  }
+
+  \gdef\parseUTFviiiA#1{%
+    \countUTFx = \countUTFz
+    \divide\countUTFz by 64
+    \countUTFy = \countUTFz
+    \multiply\countUTFz by 64
+    \advance\countUTFx by -\countUTFz
+    \advance\countUTFx by 128
+    \uccode `#1\countUTFx
+    \countUTFz = \countUTFy}
+
+  \gdef\parseUTFviiiB#1#2#3#4{%
+    \advance\countUTFz by "#10\relax
+    \uccode `#3\countUTFz
+    \uppercase{\gdef\UTFviiiTmp{#2#3#4}}}
+\endgroup
+
+\def\utfeightchardefs{%
+  \DeclareUnicodeCharacter{00A0}{\tie}
+  \DeclareUnicodeCharacter{00A1}{\exclamdown}
+  \DeclareUnicodeCharacter{00A3}{\pounds}
+  \DeclareUnicodeCharacter{00A8}{\"{ }}
+  \DeclareUnicodeCharacter{00A9}{\copyright}
+  \DeclareUnicodeCharacter{00AA}{\ordf}
+  \DeclareUnicodeCharacter{00AB}{\guillemetleft}
+  \DeclareUnicodeCharacter{00AD}{\-}
+  \DeclareUnicodeCharacter{00AE}{\registeredsymbol}
+  \DeclareUnicodeCharacter{00AF}{\={ }}
+
+  \DeclareUnicodeCharacter{00B0}{\ringaccent{ }}
+  \DeclareUnicodeCharacter{00B4}{\'{ }}
+  \DeclareUnicodeCharacter{00B8}{\cedilla{ }}
+  \DeclareUnicodeCharacter{00BA}{\ordm}
+  \DeclareUnicodeCharacter{00BB}{\guillemetright}
+  \DeclareUnicodeCharacter{00BF}{\questiondown}
+
+  \DeclareUnicodeCharacter{00C0}{\`A}
+  \DeclareUnicodeCharacter{00C1}{\'A}
+  \DeclareUnicodeCharacter{00C2}{\^A}
+  \DeclareUnicodeCharacter{00C3}{\~A}
+  \DeclareUnicodeCharacter{00C4}{\"A}
+  \DeclareUnicodeCharacter{00C5}{\AA}
+  \DeclareUnicodeCharacter{00C6}{\AE}
+  \DeclareUnicodeCharacter{00C7}{\cedilla{C}}
+  \DeclareUnicodeCharacter{00C8}{\`E}
+  \DeclareUnicodeCharacter{00C9}{\'E}
+  \DeclareUnicodeCharacter{00CA}{\^E}
+  \DeclareUnicodeCharacter{00CB}{\"E}
+  \DeclareUnicodeCharacter{00CC}{\`I}
+  \DeclareUnicodeCharacter{00CD}{\'I}
+  \DeclareUnicodeCharacter{00CE}{\^I}
+  \DeclareUnicodeCharacter{00CF}{\"I}
+
+  \DeclareUnicodeCharacter{00D0}{\DH}
+  \DeclareUnicodeCharacter{00D1}{\~N}
+  \DeclareUnicodeCharacter{00D2}{\`O}
+  \DeclareUnicodeCharacter{00D3}{\'O}
+  \DeclareUnicodeCharacter{00D4}{\^O}
+  \DeclareUnicodeCharacter{00D5}{\~O}
+  \DeclareUnicodeCharacter{00D6}{\"O}
+  \DeclareUnicodeCharacter{00D8}{\O}
+  \DeclareUnicodeCharacter{00D9}{\`U}
+  \DeclareUnicodeCharacter{00DA}{\'U}
+  \DeclareUnicodeCharacter{00DB}{\^U}
+  \DeclareUnicodeCharacter{00DC}{\"U}
+  \DeclareUnicodeCharacter{00DD}{\'Y}
+  \DeclareUnicodeCharacter{00DE}{\TH}
+  \DeclareUnicodeCharacter{00DF}{\ss}
+
+  \DeclareUnicodeCharacter{00E0}{\`a}
+  \DeclareUnicodeCharacter{00E1}{\'a}
+  \DeclareUnicodeCharacter{00E2}{\^a}
+  \DeclareUnicodeCharacter{00E3}{\~a}
+  \DeclareUnicodeCharacter{00E4}{\"a}
+  \DeclareUnicodeCharacter{00E5}{\aa}
+  \DeclareUnicodeCharacter{00E6}{\ae}
+  \DeclareUnicodeCharacter{00E7}{\cedilla{c}}
+  \DeclareUnicodeCharacter{00E8}{\`e}
+  \DeclareUnicodeCharacter{00E9}{\'e}
+  \DeclareUnicodeCharacter{00EA}{\^e}
+  \DeclareUnicodeCharacter{00EB}{\"e}
+  \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}}
+  \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}}
+  \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}
+  \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}
+
+  \DeclareUnicodeCharacter{00F0}{\dh}
+  \DeclareUnicodeCharacter{00F1}{\~n}
+  \DeclareUnicodeCharacter{00F2}{\`o}
+  \DeclareUnicodeCharacter{00F3}{\'o}
+  \DeclareUnicodeCharacter{00F4}{\^o}
+  \DeclareUnicodeCharacter{00F5}{\~o}
+  \DeclareUnicodeCharacter{00F6}{\"o}
+  \DeclareUnicodeCharacter{00F8}{\o}
+  \DeclareUnicodeCharacter{00F9}{\`u}
+  \DeclareUnicodeCharacter{00FA}{\'u}
+  \DeclareUnicodeCharacter{00FB}{\^u}
+  \DeclareUnicodeCharacter{00FC}{\"u}
+  \DeclareUnicodeCharacter{00FD}{\'y}
+  \DeclareUnicodeCharacter{00FE}{\th}
+  \DeclareUnicodeCharacter{00FF}{\"y}
+
+  \DeclareUnicodeCharacter{0100}{\=A}
+  \DeclareUnicodeCharacter{0101}{\=a}
+  \DeclareUnicodeCharacter{0102}{\u{A}}
+  \DeclareUnicodeCharacter{0103}{\u{a}}
+  \DeclareUnicodeCharacter{0104}{\ogonek{A}}
+  \DeclareUnicodeCharacter{0105}{\ogonek{a}}
+  \DeclareUnicodeCharacter{0106}{\'C}
+  \DeclareUnicodeCharacter{0107}{\'c}
+  \DeclareUnicodeCharacter{0108}{\^C}
+  \DeclareUnicodeCharacter{0109}{\^c}
+  \DeclareUnicodeCharacter{0118}{\ogonek{E}}
+  \DeclareUnicodeCharacter{0119}{\ogonek{e}}
+  \DeclareUnicodeCharacter{010A}{\dotaccent{C}}
+  \DeclareUnicodeCharacter{010B}{\dotaccent{c}}
+  \DeclareUnicodeCharacter{010C}{\v{C}}
+  \DeclareUnicodeCharacter{010D}{\v{c}}
+  \DeclareUnicodeCharacter{010E}{\v{D}}
+
+  \DeclareUnicodeCharacter{0112}{\=E}
+  \DeclareUnicodeCharacter{0113}{\=e}
+  \DeclareUnicodeCharacter{0114}{\u{E}}
+  \DeclareUnicodeCharacter{0115}{\u{e}}
+  \DeclareUnicodeCharacter{0116}{\dotaccent{E}}
+  \DeclareUnicodeCharacter{0117}{\dotaccent{e}}
+  \DeclareUnicodeCharacter{011A}{\v{E}}
+  \DeclareUnicodeCharacter{011B}{\v{e}}
+  \DeclareUnicodeCharacter{011C}{\^G}
+  \DeclareUnicodeCharacter{011D}{\^g}
+  \DeclareUnicodeCharacter{011E}{\u{G}}
+  \DeclareUnicodeCharacter{011F}{\u{g}}
+
+  \DeclareUnicodeCharacter{0120}{\dotaccent{G}}
+  \DeclareUnicodeCharacter{0121}{\dotaccent{g}}
+  \DeclareUnicodeCharacter{0124}{\^H}
+  \DeclareUnicodeCharacter{0125}{\^h}
+  \DeclareUnicodeCharacter{0128}{\~I}
+  \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}}
+  \DeclareUnicodeCharacter{012A}{\=I}
+  \DeclareUnicodeCharacter{012B}{\={\dotless{i}}}
+  \DeclareUnicodeCharacter{012C}{\u{I}}
+  \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}}
+
+  \DeclareUnicodeCharacter{0130}{\dotaccent{I}}
+  \DeclareUnicodeCharacter{0131}{\dotless{i}}
+  \DeclareUnicodeCharacter{0132}{IJ}
+  \DeclareUnicodeCharacter{0133}{ij}
+  \DeclareUnicodeCharacter{0134}{\^J}
+  \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}}
+  \DeclareUnicodeCharacter{0139}{\'L}
+  \DeclareUnicodeCharacter{013A}{\'l}
+
+  \DeclareUnicodeCharacter{0141}{\L}
+  \DeclareUnicodeCharacter{0142}{\l}
+  \DeclareUnicodeCharacter{0143}{\'N}
+  \DeclareUnicodeCharacter{0144}{\'n}
+  \DeclareUnicodeCharacter{0147}{\v{N}}
+  \DeclareUnicodeCharacter{0148}{\v{n}}
+  \DeclareUnicodeCharacter{014C}{\=O}
+  \DeclareUnicodeCharacter{014D}{\=o}
+  \DeclareUnicodeCharacter{014E}{\u{O}}
+  \DeclareUnicodeCharacter{014F}{\u{o}}
+
+  \DeclareUnicodeCharacter{0150}{\H{O}}
+  \DeclareUnicodeCharacter{0151}{\H{o}}
+  \DeclareUnicodeCharacter{0152}{\OE}
+  \DeclareUnicodeCharacter{0153}{\oe}
+  \DeclareUnicodeCharacter{0154}{\'R}
+  \DeclareUnicodeCharacter{0155}{\'r}
+  \DeclareUnicodeCharacter{0158}{\v{R}}
+  \DeclareUnicodeCharacter{0159}{\v{r}}
+  \DeclareUnicodeCharacter{015A}{\'S}
+  \DeclareUnicodeCharacter{015B}{\'s}
+  \DeclareUnicodeCharacter{015C}{\^S}
+  \DeclareUnicodeCharacter{015D}{\^s}
+  \DeclareUnicodeCharacter{015E}{\cedilla{S}}
+  \DeclareUnicodeCharacter{015F}{\cedilla{s}}
+
+  \DeclareUnicodeCharacter{0160}{\v{S}}
+  \DeclareUnicodeCharacter{0161}{\v{s}}
+  \DeclareUnicodeCharacter{0162}{\cedilla{t}}
+  \DeclareUnicodeCharacter{0163}{\cedilla{T}}
+  \DeclareUnicodeCharacter{0164}{\v{T}}
+
+  \DeclareUnicodeCharacter{0168}{\~U}
+  \DeclareUnicodeCharacter{0169}{\~u}
+  \DeclareUnicodeCharacter{016A}{\=U}
+  \DeclareUnicodeCharacter{016B}{\=u}
+  \DeclareUnicodeCharacter{016C}{\u{U}}
+  \DeclareUnicodeCharacter{016D}{\u{u}}
+  \DeclareUnicodeCharacter{016E}{\ringaccent{U}}
+  \DeclareUnicodeCharacter{016F}{\ringaccent{u}}
+
+  \DeclareUnicodeCharacter{0170}{\H{U}}
+  \DeclareUnicodeCharacter{0171}{\H{u}}
+  \DeclareUnicodeCharacter{0174}{\^W}
+  \DeclareUnicodeCharacter{0175}{\^w}
+  \DeclareUnicodeCharacter{0176}{\^Y}
+  \DeclareUnicodeCharacter{0177}{\^y}
+  \DeclareUnicodeCharacter{0178}{\"Y}
+  \DeclareUnicodeCharacter{0179}{\'Z}
+  \DeclareUnicodeCharacter{017A}{\'z}
+  \DeclareUnicodeCharacter{017B}{\dotaccent{Z}}
+  \DeclareUnicodeCharacter{017C}{\dotaccent{z}}
+  \DeclareUnicodeCharacter{017D}{\v{Z}}
+  \DeclareUnicodeCharacter{017E}{\v{z}}
+
+  \DeclareUnicodeCharacter{01C4}{D\v{Z}}
+  \DeclareUnicodeCharacter{01C5}{D\v{z}}
+  \DeclareUnicodeCharacter{01C6}{d\v{z}}
+  \DeclareUnicodeCharacter{01C7}{LJ}
+  \DeclareUnicodeCharacter{01C8}{Lj}
+  \DeclareUnicodeCharacter{01C9}{lj}
+  \DeclareUnicodeCharacter{01CA}{NJ}
+  \DeclareUnicodeCharacter{01CB}{Nj}
+  \DeclareUnicodeCharacter{01CC}{nj}
+  \DeclareUnicodeCharacter{01CD}{\v{A}}
+  \DeclareUnicodeCharacter{01CE}{\v{a}}
+  \DeclareUnicodeCharacter{01CF}{\v{I}}
+
+  \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}}
+  \DeclareUnicodeCharacter{01D1}{\v{O}}
+  \DeclareUnicodeCharacter{01D2}{\v{o}}
+  \DeclareUnicodeCharacter{01D3}{\v{U}}
+  \DeclareUnicodeCharacter{01D4}{\v{u}}
+
+  \DeclareUnicodeCharacter{01E2}{\={\AE}}
+  \DeclareUnicodeCharacter{01E3}{\={\ae}}
+  \DeclareUnicodeCharacter{01E6}{\v{G}}
+  \DeclareUnicodeCharacter{01E7}{\v{g}}
+  \DeclareUnicodeCharacter{01E8}{\v{K}}
+  \DeclareUnicodeCharacter{01E9}{\v{k}}
+
+  \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}}
+  \DeclareUnicodeCharacter{01F1}{DZ}
+  \DeclareUnicodeCharacter{01F2}{Dz}
+  \DeclareUnicodeCharacter{01F3}{dz}
+  \DeclareUnicodeCharacter{01F4}{\'G}
+  \DeclareUnicodeCharacter{01F5}{\'g}
+  \DeclareUnicodeCharacter{01F8}{\`N}
+  \DeclareUnicodeCharacter{01F9}{\`n}
+  \DeclareUnicodeCharacter{01FC}{\'{\AE}}
+  \DeclareUnicodeCharacter{01FD}{\'{\ae}}
+  \DeclareUnicodeCharacter{01FE}{\'{\O}}
+  \DeclareUnicodeCharacter{01FF}{\'{\o}}
+
+  \DeclareUnicodeCharacter{021E}{\v{H}}
+  \DeclareUnicodeCharacter{021F}{\v{h}}
+
+  \DeclareUnicodeCharacter{0226}{\dotaccent{A}}
+  \DeclareUnicodeCharacter{0227}{\dotaccent{a}}
+  \DeclareUnicodeCharacter{0228}{\cedilla{E}}
+  \DeclareUnicodeCharacter{0229}{\cedilla{e}}
+  \DeclareUnicodeCharacter{022E}{\dotaccent{O}}
+  \DeclareUnicodeCharacter{022F}{\dotaccent{o}}
+
+  \DeclareUnicodeCharacter{0232}{\=Y}
+  \DeclareUnicodeCharacter{0233}{\=y}
+  \DeclareUnicodeCharacter{0237}{\dotless{j}}
+
+  \DeclareUnicodeCharacter{02DB}{\ogonek{ }}
+
+  \DeclareUnicodeCharacter{1E02}{\dotaccent{B}}
+  \DeclareUnicodeCharacter{1E03}{\dotaccent{b}}
+  \DeclareUnicodeCharacter{1E04}{\udotaccent{B}}
+  \DeclareUnicodeCharacter{1E05}{\udotaccent{b}}
+  \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}}
+  \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}}
+  \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}}
+  \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}}
+  \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}}
+  \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}}
+  \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}}
+  \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}}
+
+  \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}}
+  \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}}
+
+  \DeclareUnicodeCharacter{1E20}{\=G}
+  \DeclareUnicodeCharacter{1E21}{\=g}
+  \DeclareUnicodeCharacter{1E22}{\dotaccent{H}}
+  \DeclareUnicodeCharacter{1E23}{\dotaccent{h}}
+  \DeclareUnicodeCharacter{1E24}{\udotaccent{H}}
+  \DeclareUnicodeCharacter{1E25}{\udotaccent{h}}
+  \DeclareUnicodeCharacter{1E26}{\"H}
+  \DeclareUnicodeCharacter{1E27}{\"h}
+
+  \DeclareUnicodeCharacter{1E30}{\'K}
+  \DeclareUnicodeCharacter{1E31}{\'k}
+  \DeclareUnicodeCharacter{1E32}{\udotaccent{K}}
+  \DeclareUnicodeCharacter{1E33}{\udotaccent{k}}
+  \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}}
+  \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}}
+  \DeclareUnicodeCharacter{1E36}{\udotaccent{L}}
+  \DeclareUnicodeCharacter{1E37}{\udotaccent{l}}
+  \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}}
+  \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}}
+  \DeclareUnicodeCharacter{1E3E}{\'M}
+  \DeclareUnicodeCharacter{1E3F}{\'m}
+
+  \DeclareUnicodeCharacter{1E40}{\dotaccent{M}}
+  \DeclareUnicodeCharacter{1E41}{\dotaccent{m}}
+  \DeclareUnicodeCharacter{1E42}{\udotaccent{M}}
+  \DeclareUnicodeCharacter{1E43}{\udotaccent{m}}
+  \DeclareUnicodeCharacter{1E44}{\dotaccent{N}}
+  \DeclareUnicodeCharacter{1E45}{\dotaccent{n}}
+  \DeclareUnicodeCharacter{1E46}{\udotaccent{N}}
+  \DeclareUnicodeCharacter{1E47}{\udotaccent{n}}
+  \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}}
+  \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}}
+
+  \DeclareUnicodeCharacter{1E54}{\'P}
+  \DeclareUnicodeCharacter{1E55}{\'p}
+  \DeclareUnicodeCharacter{1E56}{\dotaccent{P}}
+  \DeclareUnicodeCharacter{1E57}{\dotaccent{p}}
+  \DeclareUnicodeCharacter{1E58}{\dotaccent{R}}
+  \DeclareUnicodeCharacter{1E59}{\dotaccent{r}}
+  \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}}
+  \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}}
+  \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}}
+  \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}}
+
+  \DeclareUnicodeCharacter{1E60}{\dotaccent{S}}
+  \DeclareUnicodeCharacter{1E61}{\dotaccent{s}}
+  \DeclareUnicodeCharacter{1E62}{\udotaccent{S}}
+  \DeclareUnicodeCharacter{1E63}{\udotaccent{s}}
+  \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}}
+  \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}}
+  \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}}
+  \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}}
+  \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}}
+  \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}}
+
+  \DeclareUnicodeCharacter{1E7C}{\~V}
+  \DeclareUnicodeCharacter{1E7D}{\~v}
+  \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}}
+  \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}}
+
+  \DeclareUnicodeCharacter{1E80}{\`W}
+  \DeclareUnicodeCharacter{1E81}{\`w}
+  \DeclareUnicodeCharacter{1E82}{\'W}
+  \DeclareUnicodeCharacter{1E83}{\'w}
+  \DeclareUnicodeCharacter{1E84}{\"W}
+  \DeclareUnicodeCharacter{1E85}{\"w}
+  \DeclareUnicodeCharacter{1E86}{\dotaccent{W}}
+  \DeclareUnicodeCharacter{1E87}{\dotaccent{w}}
+  \DeclareUnicodeCharacter{1E88}{\udotaccent{W}}
+  \DeclareUnicodeCharacter{1E89}{\udotaccent{w}}
+  \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}}
+  \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}}
+  \DeclareUnicodeCharacter{1E8C}{\"X}
+  \DeclareUnicodeCharacter{1E8D}{\"x}
+  \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}}
+  \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}}
+
+  \DeclareUnicodeCharacter{1E90}{\^Z}
+  \DeclareUnicodeCharacter{1E91}{\^z}
+  \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}}
+  \DeclareUnicodeCharacter{1E93}{\udotaccent{z}}
+  \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}}
+  \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}}
+  \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}}
+  \DeclareUnicodeCharacter{1E97}{\"t}
+  \DeclareUnicodeCharacter{1E98}{\ringaccent{w}}
+  \DeclareUnicodeCharacter{1E99}{\ringaccent{y}}
+
+  \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}}
+  \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}}
+
+  \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}}
+  \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}}
+  \DeclareUnicodeCharacter{1EBC}{\~E}
+  \DeclareUnicodeCharacter{1EBD}{\~e}
+
+  \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}}
+  \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}}
+  \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}}
+  \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}}
+
+  \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}}
+  \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}}
+
+  \DeclareUnicodeCharacter{1EF2}{\`Y}
+  \DeclareUnicodeCharacter{1EF3}{\`y}
+  \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}}
+
+  \DeclareUnicodeCharacter{1EF8}{\~Y}
+  \DeclareUnicodeCharacter{1EF9}{\~y}
+
+  \DeclareUnicodeCharacter{2013}{--}
+  \DeclareUnicodeCharacter{2014}{---}
+  \DeclareUnicodeCharacter{2018}{\quoteleft}
+  \DeclareUnicodeCharacter{2019}{\quoteright}
+  \DeclareUnicodeCharacter{201A}{\quotesinglbase}
+  \DeclareUnicodeCharacter{201C}{\quotedblleft}
+  \DeclareUnicodeCharacter{201D}{\quotedblright}
+  \DeclareUnicodeCharacter{201E}{\quotedblbase}
+  \DeclareUnicodeCharacter{2022}{\bullet}
+  \DeclareUnicodeCharacter{2026}{\dots}
+  \DeclareUnicodeCharacter{2039}{\guilsinglleft}
+  \DeclareUnicodeCharacter{203A}{\guilsinglright}
+  \DeclareUnicodeCharacter{20AC}{\euro}
+
+  \DeclareUnicodeCharacter{2192}{\expansion}
+  \DeclareUnicodeCharacter{21D2}{\result}
+
+  \DeclareUnicodeCharacter{2212}{\minus}
+  \DeclareUnicodeCharacter{2217}{\point}
+  \DeclareUnicodeCharacter{2261}{\equiv}
+}% end of \utfeightchardefs
+
+
+% US-ASCII character definitions.
+\def\asciichardefs{% nothing need be done
+   \relax
+}
+
+% Make non-ASCII characters printable again for compatibility with
+% existing Texinfo documents that may use them, even without declaring a
+% document encoding.
+%
+\setnonasciicharscatcode \other
+
+
+\message{formatting,}
+
+\newdimen\defaultparindent \defaultparindent = 15pt
+
+\chapheadingskip = 15pt plus 4pt minus 2pt
+\secheadingskip = 12pt plus 3pt minus 2pt
+\subsecheadingskip = 9pt plus 2pt minus 2pt
+
+% Prevent underfull vbox error messages.
+\vbadness = 10000
+
+% Don't be so finicky about underfull hboxes, either.
+\hbadness = 2000
+
+% Following George Bush, get rid of widows and orphans.
+\widowpenalty=10000
+\clubpenalty=10000
+
+% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+% using an old version of TeX, don't do anything.  We want the amount of
+% stretch added to depend on the line length, hence the dependence on
+% \hsize.  We call this whenever the paper size is set.
+%
+\def\setemergencystretch{%
+  \ifx\emergencystretch\thisisundefined
+    % Allow us to assign to \emergencystretch anyway.
+    \def\emergencystretch{\dimen0}%
+  \else
+    \emergencystretch = .15\hsize
+  \fi
+}
+
+% Parameters in order: 1) textheight; 2) textwidth;
+% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip;
+% 7) physical page height; 8) physical page width.
+%
+% We also call \setleading{\textleading}, so the caller should define
+% \textleading.  The caller should also set \parskip.
+%
+\def\internalpagesizes#1#2#3#4#5#6#7#8{%
+  \voffset = #3\relax
+  \topskip = #6\relax
+  \splittopskip = \topskip
+  %
+  \vsize = #1\relax
+  \advance\vsize by \topskip
+  \outervsize = \vsize
+  \advance\outervsize by 2\topandbottommargin
+  \pageheight = \vsize
+  %
+  \hsize = #2\relax
+  \outerhsize = \hsize
+  \advance\outerhsize by 0.5in
+  \pagewidth = \hsize
+  %
+  \normaloffset = #4\relax
+  \bindingoffset = #5\relax
+  %
+  \ifpdf
+    \pdfpageheight #7\relax
+    \pdfpagewidth #8\relax
+    % if we don't reset these, they will remain at "1 true in" of
+    % whatever layout pdftex was dumped with.
+    \pdfhorigin = 1 true in
+    \pdfvorigin = 1 true in
+  \fi
+  %
+  \setleading{\textleading}
+  %
+  \parindent = \defaultparindent
+  \setemergencystretch
+}
+
+% @letterpaper (the default).
+\def\letterpaper{{\globaldefs = 1
+  \parskip = 3pt plus 2pt minus 1pt
+  \textleading = 13.2pt
+  %
+  % If page is nothing but text, make it come out even.
+  \internalpagesizes{607.2pt}{6in}% that's 46 lines
+                    {\voffset}{.25in}%
+                    {\bindingoffset}{36pt}%
+                    {11in}{8.5in}%
+}}
+
+% Use @smallbook to reset parameters for 7x9.25 trim size.
+\def\smallbook{{\globaldefs = 1
+  \parskip = 2pt plus 1pt
+  \textleading = 12pt
+  %
+  \internalpagesizes{7.5in}{5in}%
+                    {-.2in}{0in}%
+                    {\bindingoffset}{16pt}%
+                    {9.25in}{7in}%
+  %
+  \lispnarrowing = 0.3in
+  \tolerance = 700
+  \hfuzz = 1pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = .5cm
+}}
+
+% Use @smallerbook to reset parameters for 6x9 trim size.
+% (Just testing, parameters still in flux.)
+\def\smallerbook{{\globaldefs = 1
+  \parskip = 1.5pt plus 1pt
+  \textleading = 12pt
+  %
+  \internalpagesizes{7.4in}{4.8in}%
+                    {-.2in}{-.4in}%
+                    {0pt}{14pt}%
+                    {9in}{6in}%
+  %
+  \lispnarrowing = 0.25in
+  \tolerance = 700
+  \hfuzz = 1pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = .4cm
+}}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{{\globaldefs = 1
+  \parskip = 3pt plus 2pt minus 1pt
+  \textleading = 13.2pt
+  %
+  % Double-side printing via postscript on Laserjet 4050
+  % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm.
+  % To change the settings for a different printer or situation, adjust
+  % \normaloffset until the front-side and back-side texts align.  Then
+  % do the same for \bindingoffset.  You can set these for testing in
+  % your texinfo source file like this:
+  % @tex
+  % \global\normaloffset = -6mm
+  % \global\bindingoffset = 10mm
+  % @end tex
+  \internalpagesizes{673.2pt}{160mm}% that's 51 lines
+                    {\voffset}{\hoffset}%
+                    {\bindingoffset}{44pt}%
+                    {297mm}{210mm}%
+  %
+  \tolerance = 700
+  \hfuzz = 1pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = 5mm
+}}
+
+% Use @afivepaper to print on European A5 paper.
+% From romildo@urano.iceb.ufop.br, 2 July 2000.
+% He also recommends making @example and @lisp be small.
+\def\afivepaper{{\globaldefs = 1
+  \parskip = 2pt plus 1pt minus 0.1pt
+  \textleading = 12.5pt
+  %
+  \internalpagesizes{160mm}{120mm}%
+                    {\voffset}{\hoffset}%
+                    {\bindingoffset}{8pt}%
+                    {210mm}{148mm}%
+  %
+  \lispnarrowing = 0.2in
+  \tolerance = 800
+  \hfuzz = 1.2pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = 2mm
+  \tableindent = 12mm
+}}
+
+% A specific text layout, 24x15cm overall, intended for A4 paper.
+\def\afourlatex{{\globaldefs = 1
+  \afourpaper
+  \internalpagesizes{237mm}{150mm}%
+                    {\voffset}{4.6mm}%
+                    {\bindingoffset}{7mm}%
+                    {297mm}{210mm}%
+  %
+  % Must explicitly reset to 0 because we call \afourpaper.
+  \globaldefs = 0
+}}
+
+% Use @afourwide to print on A4 paper in landscape format.
+\def\afourwide{{\globaldefs = 1
+  \afourpaper
+  \internalpagesizes{241mm}{165mm}%
+                    {\voffset}{-2.95mm}%
+                    {\bindingoffset}{7mm}%
+                    {297mm}{210mm}%
+  \globaldefs = 0
+}}
+
+% @pagesizes TEXTHEIGHT[,TEXTWIDTH]
+% Perhaps we should allow setting the margins, \topskip, \parskip,
+% and/or leading, also. Or perhaps we should compute them somehow.
+%
+\parseargdef\pagesizes{\pagesizesyyy #1,,\finish}
+\def\pagesizesyyy#1,#2,#3\finish{{%
+  \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi
+  \globaldefs = 1
+  %
+  \parskip = 3pt plus 2pt minus 1pt
+  \setleading{\textleading}%
+  %
+  \dimen0 = #1\relax
+  \advance\dimen0 by \voffset
+  %
+  \dimen2 = \hsize
+  \advance\dimen2 by \normaloffset
+  %
+  \internalpagesizes{#1}{\hsize}%
+                    {\voffset}{\normaloffset}%
+                    {\bindingoffset}{44pt}%
+                    {\dimen0}{\dimen2}%
+}}
+
+% Set default to letter.
+%
+\letterpaper
+
+
+\message{and turning on texinfo input format.}
+
+% DEL is a comment character, in case @c does not suffice.
+\catcode`\^^? = 14
+
+% Define macros to output various characters with catcode for normal text.
+\catcode`\"=\other
+\catcode`\~=\other
+\catcode`\^=\other
+\catcode`\_=\other
+\catcode`\|=\other
+\catcode`\<=\other
+\catcode`\>=\other
+\catcode`\+=\other
+\catcode`\$=\other
+\def\normaldoublequote{"}
+\def\normaltilde{~}
+\def\normalcaret{^}
+\def\normalunderscore{_}
+\def\normalverticalbar{|}
+\def\normalless{<}
+\def\normalgreater{>}
+\def\normalplus{+}
+\def\normaldollar{$}%$ font-lock fix
+
+% This macro is used to make a character print one way in \tt
+% (where it can probably be output as-is), and another way in other fonts,
+% where something hairier probably needs to be done.
+%
+% #1 is what to print if we are indeed using \tt; #2 is what to print
+% otherwise.  Since all the Computer Modern typewriter fonts have zero
+% interword stretch (and shrink), and it is reasonable to expect all
+% typewriter fonts to have this, we can check that font parameter.
+%
+\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi}
+
+% Same as above, but check for italic font.  Actually this also catches
+% non-italic slanted fonts since it is impossible to distinguish them from
+% italic fonts.  But since this is only used by $ and it uses \sl anyway
+% this is not a problem.
+\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi}
+
+% Turn off all special characters except @
+% (and those which the user can use as if they were ordinary).
+% Most of these we simply print from the \tt font, but for some, we can
+% use math or other variants that look better in normal text.
+
+\catcode`\"=\active
+\def\activedoublequote{{\tt\char34}}
+\let"=\activedoublequote
+\catcode`\~=\active
+\def~{{\tt\char126}}
+\chardef\hat=`\^
+\catcode`\^=\active
+\def^{{\tt \hat}}
+
+\catcode`\_=\active
+\def_{\ifusingtt\normalunderscore\_}
+\let\realunder=_
+% Subroutine for the previous macro.
+\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }
+
+\catcode`\|=\active
+\def|{{\tt\char124}}
+\chardef \less=`\<
+\catcode`\<=\active
+\def<{{\tt \less}}
+\chardef \gtr=`\>
+\catcode`\>=\active
+\def>{{\tt \gtr}}
+\catcode`\+=\active
+\def+{{\tt \char 43}}
+\catcode`\$=\active
+\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
+
+% If a .fmt file is being used, characters that might appear in a file
+% name cannot be active until we have parsed the command line.
+% So turn them off again, and have \everyjob (or @setfilename) turn them on.
+% \otherifyactive is called near the end of this file.
+\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
+
+% Used sometimes to turn off (effectively) the active characters even after
+% parsing them.
+\def\turnoffactive{%
+  \normalturnoffactive
+  \otherbackslash
+}
+
+\catcode`\@=0
+
+% \backslashcurfont outputs one backslash character in current font,
+% as in \char`\\.
+\global\chardef\backslashcurfont=`\\
+\global\let\rawbackslashxx=\backslashcurfont  % let existing .??s files work
+
+% \realbackslash is an actual character `\' with catcode other, and
+% \doublebackslash is two of them (for the pdf outlines).
+{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}}
+
+% In texinfo, backslash is an active character; it prints the backslash
+% in fixed width font.
+\catcode`\\=\active
+@def@normalbackslash{{@tt@backslashcurfont}}
+% On startup, @fixbackslash assigns:
+%  @let \ = @normalbackslash
+
+% \rawbackslash defines an active \ to do \backslashcurfont.
+% \otherbackslash defines an active \ to be a literal `\' character with
+% catcode other.
+@gdef@rawbackslash{@let\=@backslashcurfont}
+@gdef@otherbackslash{@let\=@realbackslash}
+
+% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
+% the literal character `\'.
+%
+@def@normalturnoffactive{%
+  @let\=@normalbackslash
+  @let"=@normaldoublequote
+  @let~=@normaltilde
+  @let^=@normalcaret
+  @let_=@normalunderscore
+  @let|=@normalverticalbar
+  @let<=@normalless
+  @let>=@normalgreater
+  @let+=@normalplus
+  @let$=@normaldollar %$ font-lock fix
+  @markupsetuplqdefault
+  @markupsetuprqdefault
+  @unsepspaces
+}
+
+% Make _ and + \other characters, temporarily.
+% This is canceled by @fixbackslash.
+@otherifyactive
+
+% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+% That is what \eatinput is for; after that, the `\' should revert to printing
+% a backslash.
+%
+@gdef@eatinput input texinfo{@fixbackslash}
+@global@let\ = @eatinput
+
+% On the other hand, perhaps the file did not have a `\input texinfo'. Then
+% the first `\' in the file would cause an error. This macro tries to fix
+% that, assuming it is called before the first `\' could plausibly occur.
+% Also turn back on active characters that might appear in the input
+% file name, in case not using a pre-dumped format.
+%
+@gdef@fixbackslash{%
+  @ifx\@eatinput @let\ = @normalbackslash @fi
+  @catcode`+=@active
+  @catcode`@_=@active
+}
+
+% Say @foo, not \foo, in error messages.
+@escapechar = `@@
+
+% These look ok in all fonts, so just make them not special.
+@catcode`@& = @other
+@catcode`@# = @other
+@catcode`@% = @other
+
+@c Finally, make ` and ' active, so that txicodequoteundirected and
+@c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}.  If we
+@c don't make ` and ' active, @code will not get them as active chars.
+@c Do this last of all since we use ` in the previous @catcode assignments.
+@catcode`@'=@active
+@catcode`@`=@active
+@markupsetuplqdefault
+@markupsetuprqdefault
+
+@c Local variables:
+@c eval: (add-hook 'write-file-hooks 'time-stamp)
+@c page-delimiter: "^\\\\message"
+@c time-stamp-start: "def\\\\texinfoversion{"
+@c time-stamp-format: "%:y-%02m-%02d.%02H"
+@c time-stamp-end: "}"
+@c End:
+
+@c vim:sw=2:
+
+@ignore
+   arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115
+@end ignore
diff --git a/tools/Makefile.in b/tools/Makefile.in
new file mode 100644 (file)
index 0000000..5ca73b2
--- /dev/null
@@ -0,0 +1,87 @@
+@SET_MAKE@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+top_srcdir = @top_srcdir@
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = $(INSTALL_PROGRAM) -s
+MKDIR_P = @MKDIR_P@
+
+include ../config.make
+
+PRE_CPPFLAGS = -I.. -I$(top_srcdir)
+PRE_LDFLAGS = -L..
+
+HOGWEED_TARGETS = pkcs1-conv$(EXEEXT)
+TARGETS = sexp-conv$(EXEEXT) nettle-hash$(EXEEXT) nettle-lfib-stream$(EXEEXT) \
+         @IF_HOGWEED@ $(HOGWEED_TARGETS)
+
+all: $(TARGETS)
+
+sexp_conv_SOURCES = sexp-conv.c input.c output.c parse.c \
+       getopt.c getopt1.c misc.c
+pkcs1_conv_SOURCES = pkcs1-conv.c getopt.c getopt1.c misc.c
+nettle_hash_SOURCES = nettle-hash.c getopt.c getopt1.c misc.c
+
+SOURCES = $(sexp_conv_SOURCES) nettle-hash.c nettle-lfib-stream.c pkcs1-conv.c
+
+DISTFILES = $(SOURCES) Makefile.in getopt.h input.h misc.h output.h parse.h
+
+sexp_conv_OBJS = $(sexp_conv_SOURCES:.c=.$(OBJEXT))
+sexp-conv$(EXEEXT): $(sexp_conv_OBJS) ../libnettle.a
+       $(LINK) $(sexp_conv_OBJS) -lnettle $(LIBS) -o $@
+
+nettle-lfib-stream$(EXEEXT): nettle-lfib-stream.$(OBJEXT) ../libnettle.a
+       $(LINK) nettle-lfib-stream.$(OBJEXT) -lnettle $(LIBS) -o $@
+
+pkcs1_conv_OBJS = $(pkcs1_conv_SOURCES:.c=.$(OBJEXT))
+pkcs1-conv$(EXEEXT): $(pkcs1_conv_OBJS) ../libnettle.a ../libhogweed.a
+       $(LINK) $(pkcs1_conv_OBJS) -lhogweed -lnettle $(LIBS) -o $@
+
+# FIXME: Avoid linking with gmp
+nettle_hash_OBJS = $(nettle_hash_SOURCES:.c=.$(OBJEXT))
+nettle-hash$(EXEEXT): $(nettle_hash_OBJS) ../libnettle.a
+       $(LINK) $(nettle_hash_OBJS) -lnettle $(LIBS) -o $@
+
+
+.c.$(OBJEXT):
+       $(COMPILE) -c $< && $(DEP_PROCESS)
+
+
+Makefile: $(srcdir)/Makefile.in ../config.status
+       cd .. && $(SHELL) ./config.status tools/$@
+
+check:
+       true
+
+install: $(TARGETS)
+       $(MKDIR_P) $(DESTDIR)$(bindir)
+       for f in $(TARGETS) ; do \
+         $(INSTALL_PROGRAM) $$f $(DESTDIR)$(bindir) ; \
+       done
+
+uninstall:
+       for f in $(TARGETS) ; do \
+         rm -f $(DESTDIR)$(bindir)/$$f ; \
+       done
+
+# NOTE: I'd like to use $^, but that's a GNU extension. $? should be
+# more portable, equivalent for phony targets.
+distdir: $(DISTFILES)
+       cp $? $(distdir)
+
+clean:
+       -rm -f $(TARGETS) *.o
+
+distclean: clean
+       -rm -f Makefile *.d
+
+tags:
+       etags -o $(srcdir)/TAGS --include $(top_srcdir) $(srcdir)/*.c $(srcdir)/*.h
+
+@DEP_INCLUDE@ $(SOURCES:.c=.$(OBJEXT).d)
diff --git a/tools/getopt.c b/tools/getopt.c
new file mode 100644 (file)
index 0000000..ed32692
--- /dev/null
@@ -0,0 +1,1067 @@
+/* Getopt for GNU.
+   NOTE: getopt is now part of the C library, so if you don't know what
+   "Keep this file name-space clean" means, talk to drepper@gnu.org
+   before changing it!
+   Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
+       Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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, 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.  */
+\f
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+   Ditto for AIX 3.2 and <stdlib.h>.  */
+#ifndef _NO_PROTO
+# define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+   reject `defined (const)'.  */
+# ifndef const
+#  define const
+# endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+# include <gnu-versions.h>
+# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#  define ELIDE_CODE
+# endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+   contain conflicting prototypes for getopt.  */
+# include <stdlib.h>
+# include <unistd.h>
+#endif /* GNU C library.  */
+
+#ifdef VMS
+# include <unixlib.h>
+# if HAVE_STRING_H - 0
+#  include <string.h>
+# endif
+#endif
+
+#ifndef _
+/* This is for other GNU distributions with internationalized messages.  */
+# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
+#  include <libintl.h>
+#  ifndef _
+#   define _(msgid)    gettext (msgid)
+#  endif
+# else
+#  define _(msgid)     (msgid)
+# endif
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+   but it behaves differently for the user, since it allows the user
+   to intersperse the options with the other arguments.
+
+   As `getopt' works, it permutes the elements of ARGV so that,
+   when it is done, all the options precede everything else.  Thus
+   all application programs are extended to handle flexible argument order.
+
+   Setting the environment variable POSIXLY_CORRECT disables permutation.
+   Then the behavior is completely standard.
+
+   GNU application programs can use a third alternative mode in which
+   they can distinguish the relative order of options and other arguments.  */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns -1, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+/* 1003.2 says this must be 1 before any call.  */
+int optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+   causes problems with re-calling getopt as programs generally don't
+   know that. */
+
+int __getopt_initialized;
+
+/* The next char to be scanned in the option-element
+   in which the last option character we returned was found.
+   This allows us to pick up the scan where we left off.
+
+   If this is zero, or a null string, it means resume the scan
+   by advancing to the next ARGV-element.  */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+   REQUIRE_ORDER means don't recognize them as options;
+   stop option processing when the first non-option is seen.
+   This is what Unix does.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-options are at the end.  This allows options
+   to be given in any order, even with programs that were not written to
+   expect this.
+
+   RETURN_IN_ORDER is an option available to programs that were written
+   to expect options and other ARGV-elements in any order and that care about
+   the ordering of the two.  We describe each non-option ARGV-element
+   as if it were the argument of an option with character code 1.
+   Using `-' as the first character of the list of option characters
+   selects this mode of operation.
+
+   The special argument `--' forces an end of option-scanning regardless
+   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+   `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable.  */
+static char *posixly_correct;
+\f
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+   because there are many ways it can cause trouble.
+   On some systems, it contains special magic macros that don't work
+   in GCC.  */
+# include <string.h>
+# define my_index      strchr
+#else
+
+# if HAVE_STRING_H
+#  include <string.h>
+# else
+#  include <strings.h>
+# endif
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+#ifndef getenv
+extern char *getenv ();
+#endif
+
+static char *
+my_index (str, chr)
+     const char *str;
+     int chr;
+{
+  while (*str)
+    {
+      if (*str == chr)
+       return (char *) str;
+      str++;
+    }
+  return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+   If not using GCC, it is ok not to declare it.  */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+   That was relevant to code that was here before.  */
+# if (!defined __STDC__ || !__STDC__) && !defined strlen
+/* gcc with -traditional declares the built-in strlen to return int,
+   and has done so at least since version 2.4.5. -- rms.  */
+extern int strlen (const char *);
+# endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+\f
+/* Handle permutation of arguments.  */
+
+/* Describe the part of ARGV that contains non-options that have
+   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+   `last_nonopt' is the index after the last of them.  */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Bash 2.0 gives us an environment variable containing flags
+   indicating ARGV elements that should not be considered arguments.  */
+
+#ifdef USE_NONOPTION_FLAGS
+/* Defined in getopt_init.c  */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+#endif
+
+static int original_argc;
+static char *const *original_argv;
+
+/* Make sure the environment variable bash 2.0 puts in the environment
+   is valid for the getopt call we must make sure that the ARGV passed
+   to getopt is that one passed to the process.  */
+static void
+__attribute__ ((unused))
+store_args_and_env (int argc, char *const *argv)
+{
+  /* XXX This is no good solution.  We should rather copy the args so
+     that we can compare them later.  But we must not use malloc(3).  */
+  original_argc = argc;
+  original_argv = argv;
+}
+# ifdef text_set_element
+text_set_element (__libc_subinit, store_args_and_env);
+# endif /* text_set_element */
+
+# ifdef USE_NONOPTION_FLAGS
+#  define SWAP_FLAGS(ch1, ch2) \
+  if (nonoption_flags_len > 0)                                               \
+    {                                                                        \
+      char __tmp = __getopt_nonoption_flags[ch1];                            \
+      __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];         \
+      __getopt_nonoption_flags[ch2] = __tmp;                                 \
+    }
+# else
+#  define SWAP_FLAGS(ch1, ch2)
+# endif
+#else  /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [first_nonopt,last_nonopt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [last_nonopt,optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `first_nonopt' and `last_nonopt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.  */
+
+#if defined __STDC__ && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (argv)
+     char **argv;
+{
+  int bottom = first_nonopt;
+  int middle = last_nonopt;
+  int top = optind;
+  char *tem;
+
+  /* Exchange the shorter segment with the far end of the longer segment.
+     That puts the shorter segment into the right place.
+     It leaves the longer segment in the right place overall,
+     but it consists of two parts that need to be swapped next.  */
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+  /* First make sure the handling of the `__getopt_nonoption_flags'
+     string can work normally.  Our top argument must be in the range
+     of the string.  */
+  if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+    {
+      /* We must extend the array.  The user plays games with us and
+        presents new arguments.  */
+      char *new_str = malloc (top + 1);
+      if (new_str == NULL)
+       nonoption_flags_len = nonoption_flags_max_len = 0;
+      else
+       {
+         memset (__mempcpy (new_str, __getopt_nonoption_flags,
+                            nonoption_flags_max_len),
+                 '\0', top + 1 - nonoption_flags_max_len);
+         nonoption_flags_max_len = top + 1;
+         __getopt_nonoption_flags = new_str;
+       }
+    }
+#endif
+
+  while (top > middle && middle > bottom)
+    {
+      if (top - middle > middle - bottom)
+       {
+         /* Bottom segment is the short one.  */
+         int len = middle - bottom;
+         register int i;
+
+         /* Swap it with the top part of the top segment.  */
+         for (i = 0; i < len; i++)
+           {
+             tem = argv[bottom + i];
+             argv[bottom + i] = argv[top - (middle - bottom) + i];
+             argv[top - (middle - bottom) + i] = tem;
+             SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+           }
+         /* Exclude the moved bottom segment from further swapping.  */
+         top -= len;
+       }
+      else
+       {
+         /* Top segment is the short one.  */
+         int len = top - middle;
+         register int i;
+
+         /* Swap it with the bottom part of the bottom segment.  */
+         for (i = 0; i < len; i++)
+           {
+             tem = argv[bottom + i];
+             argv[bottom + i] = argv[middle + i];
+             argv[middle + i] = tem;
+             SWAP_FLAGS (bottom + i, middle + i);
+           }
+         /* Exclude the moved top segment from further swapping.  */
+         bottom += len;
+       }
+    }
+
+  /* Update records for the slots the non-options now occupy.  */
+
+  first_nonopt += (optind - last_nonopt);
+  last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made.  */
+
+#if defined __STDC__ && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  /* Start processing options with ARGV-element 1 (since ARGV-element 0
+     is the program name); the sequence of previously skipped
+     non-option ARGV-elements is empty.  */
+
+  first_nonopt = last_nonopt = optind;
+
+  nextchar = NULL;
+
+  posixly_correct = getenv ("POSIXLY_CORRECT");
+
+  /* Determine how to handle the ordering of options and nonoptions.  */
+
+  if (optstring[0] == '-')
+    {
+      ordering = RETURN_IN_ORDER;
+      ++optstring;
+    }
+  else if (optstring[0] == '+')
+    {
+      ordering = REQUIRE_ORDER;
+      ++optstring;
+    }
+  else if (posixly_correct != NULL)
+    ordering = REQUIRE_ORDER;
+  else
+    ordering = PERMUTE;
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+  if (posixly_correct == NULL
+      && argc == original_argc && argv == original_argv)
+    {
+      if (nonoption_flags_max_len == 0)
+       {
+         if (__getopt_nonoption_flags == NULL
+             || __getopt_nonoption_flags[0] == '\0')
+           nonoption_flags_max_len = -1;
+         else
+           {
+             const char *orig_str = __getopt_nonoption_flags;
+             int len = nonoption_flags_max_len = strlen (orig_str);
+             if (nonoption_flags_max_len < argc)
+               nonoption_flags_max_len = argc;
+             __getopt_nonoption_flags =
+               (char *) malloc (nonoption_flags_max_len);
+             if (__getopt_nonoption_flags == NULL)
+               nonoption_flags_max_len = -1;
+             else
+               memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+                       '\0', nonoption_flags_max_len - len);
+           }
+       }
+      nonoption_flags_len = nonoption_flags_max_len;
+    }
+  else
+    nonoption_flags_len = 0;
+#endif
+
+  return optstring;
+}
+\f
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns -1.
+   Then `optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return '?' after printing an error message.  If you set `opterr' to
+   zero, the error message is suppressed but we still return '?'.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `optarg', otherwise `optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+     const struct option *longopts;
+     int *longind;
+     int long_only;
+{
+  int print_errors = opterr;
+  if (optstring[0] == ':')
+    print_errors = 0;
+
+  if (argc < 1)
+    return -1;
+
+  optarg = NULL;
+
+  if (optind == 0 || !__getopt_initialized)
+    {
+      if (optind == 0)
+       optind = 1;     /* Don't scan ARGV[0], the program name.  */
+      optstring = _getopt_initialize (argc, argv, optstring);
+      __getopt_initialized = 1;
+    }
+
+  /* Test whether ARGV[optind] points to a non-option argument.
+     Either it does not have option syntax, or there is an environment flag
+     from the shell indicating it is not an option.  The later information
+     is only used when the used in the GNU libc.  */
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'              \
+                     || (optind < nonoption_flags_len                        \
+                         && __getopt_nonoption_flags[optind] == '1'))
+#else
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#endif
+
+  if (nextchar == NULL || *nextchar == '\0')
+    {
+      /* Advance to the next ARGV-element.  */
+
+      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+        moved back by the user (who may also have changed the arguments).  */
+      if (last_nonopt > optind)
+       last_nonopt = optind;
+      if (first_nonopt > optind)
+       first_nonopt = optind;
+
+      if (ordering == PERMUTE)
+       {
+         /* If we have just processed some options following some non-options,
+            exchange them so that the options come first.  */
+
+         if (first_nonopt != last_nonopt && last_nonopt != optind)
+           exchange ((char **) argv);
+         else if (last_nonopt != optind)
+           first_nonopt = optind;
+
+         /* Skip any additional non-options
+            and extend the range of non-options previously skipped.  */
+
+         while (optind < argc && NONOPTION_P)
+           optind++;
+         last_nonopt = optind;
+       }
+
+      /* The special ARGV-element `--' means premature end of options.
+        Skip it like a null option,
+        then exchange with previous non-options as if it were an option,
+        then skip everything else like a non-option.  */
+
+      if (optind != argc && !strcmp (argv[optind], "--"))
+       {
+         optind++;
+
+         if (first_nonopt != last_nonopt && last_nonopt != optind)
+           exchange ((char **) argv);
+         else if (first_nonopt == last_nonopt)
+           first_nonopt = optind;
+         last_nonopt = argc;
+
+         optind = argc;
+       }
+
+      /* If we have done all the ARGV-elements, stop the scan
+        and back over any non-options that we skipped and permuted.  */
+
+      if (optind == argc)
+       {
+         /* Set the next-arg-index to point at the non-options
+            that we previously skipped, so the caller will digest them.  */
+         if (first_nonopt != last_nonopt)
+           optind = first_nonopt;
+         return -1;
+       }
+
+      /* If we have come to a non-option and did not permute it,
+        either stop the scan or describe it to the caller and pass it by.  */
+
+      if (NONOPTION_P)
+       {
+         if (ordering == REQUIRE_ORDER)
+           return -1;
+         optarg = argv[optind++];
+         return 1;
+       }
+
+      /* We have found another option-ARGV-element.
+        Skip the initial punctuation.  */
+
+      nextchar = (argv[optind] + 1
+                 + (longopts != NULL && argv[optind][1] == '-'));
+    }
+
+  /* Decode the current option-ARGV-element.  */
+
+  /* Check whether the ARGV-element is a long option.
+
+     If long_only and the ARGV-element has the form "-f", where f is
+     a valid short option, don't consider it an abbreviated form of
+     a long option that starts with f.  Otherwise there would be no
+     way to give the -f short option.
+
+     On the other hand, if there's a long option "fubar" and
+     the ARGV-element is "-fu", do consider that an abbreviation of
+     the long option, just like "--fu", and not "-f" with arg "u".
+
+     This distinction seems to be the most useful approach.  */
+
+  if (longopts != NULL
+      && (argv[optind][1] == '-'
+         || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+    {
+      char *nameend;
+      const struct option *p;
+      const struct option *pfound = NULL;
+      int exact = 0;
+      int ambig = 0;
+      int indfound = -1;
+      int option_index;
+
+      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+       /* Do nothing.  */ ;
+
+      /* Test all long options for either exact match
+        or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name; p++, option_index++)
+       if (!strncmp (p->name, nextchar, nameend - nextchar))
+         {
+           if ((unsigned int) (nameend - nextchar)
+               == (unsigned int) strlen (p->name))
+             {
+               /* Exact match found.  */
+               pfound = p;
+               indfound = option_index;
+               exact = 1;
+               break;
+             }
+           else if (pfound == NULL)
+             {
+               /* First nonexact match found.  */
+               pfound = p;
+               indfound = option_index;
+             }
+           else if (long_only
+                    || pfound->has_arg != p->has_arg
+                    || pfound->flag != p->flag
+                    || pfound->val != p->val)
+             /* Second or later nonexact match found.  */
+             ambig = 1;
+         }
+
+      if (ambig && !exact)
+       {
+         if (print_errors)
+           fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+                    argv[0], argv[optind]);
+         nextchar += strlen (nextchar);
+         optind++;
+         optopt = 0;
+         return '?';
+       }
+
+      if (pfound != NULL)
+       {
+         option_index = indfound;
+         optind++;
+         if (*nameend)
+           {
+             /* Don't test has_arg with >, because some C compilers don't
+                allow it to be used on enums.  */
+             if (pfound->has_arg)
+               optarg = nameend + 1;
+             else
+               {
+                 if (print_errors)
+                   {
+                     if (argv[optind - 1][1] == '-')
+                       /* --option */
+                       fprintf (stderr,
+                                _("%s: option `--%s' doesn't allow an argument\n"),
+                                argv[0], pfound->name);
+                     else
+                       /* +option or -option */
+                       fprintf (stderr,
+                                _("%s: option `%c%s' doesn't allow an argument\n"),
+                                argv[0], argv[optind - 1][0], pfound->name);
+                   }
+
+                 nextchar += strlen (nextchar);
+
+                 optopt = pfound->val;
+                 return '?';
+               }
+           }
+         else if (pfound->has_arg == 1)
+           {
+             if (optind < argc)
+               optarg = argv[optind++];
+             else
+               {
+                 if (print_errors)
+                   fprintf (stderr,
+                          _("%s: option `%s' requires an argument\n"),
+                          argv[0], argv[optind - 1]);
+                 nextchar += strlen (nextchar);
+                 optopt = pfound->val;
+                 return optstring[0] == ':' ? ':' : '?';
+               }
+           }
+         nextchar += strlen (nextchar);
+         if (longind != NULL)
+           *longind = option_index;
+         if (pfound->flag)
+           {
+             *(pfound->flag) = pfound->val;
+             return 0;
+           }
+         return pfound->val;
+       }
+
+      /* Can't find it as a long option.  If this is not getopt_long_only,
+        or the option starts with '--' or is not a valid short
+        option, then it's an error.
+        Otherwise interpret it as a short option.  */
+      if (!long_only || argv[optind][1] == '-'
+         || my_index (optstring, *nextchar) == NULL)
+       {
+         if (print_errors)
+           {
+             if (argv[optind][1] == '-')
+               /* --option */
+               fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+                        argv[0], nextchar);
+             else
+               /* +option or -option */
+               fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+                        argv[0], argv[optind][0], nextchar);
+           }
+         nextchar = (char *) "";
+         optind++;
+         optopt = 0;
+         return '?';
+       }
+    }
+
+  /* Look at and handle the next short option-character.  */
+
+  {
+    char c = *nextchar++;
+    char *temp = my_index (optstring, c);
+
+    /* Increment `optind' when we start to process its last character.  */
+    if (*nextchar == '\0')
+      ++optind;
+
+    if (temp == NULL || c == ':')
+      {
+       if (print_errors)
+         {
+           if (posixly_correct)
+             /* 1003.2 specifies the format of this message.  */
+             fprintf (stderr, _("%s: illegal option -- %c\n"),
+                      argv[0], c);
+           else
+             fprintf (stderr, _("%s: invalid option -- %c\n"),
+                      argv[0], c);
+         }
+       optopt = c;
+       return '?';
+      }
+    /* Convenience. Treat POSIX -W foo same as long option --foo */
+    if (temp[0] == 'W' && temp[1] == ';')
+      {
+       char *nameend;
+       const struct option *p;
+       const struct option *pfound = NULL;
+       int exact = 0;
+       int ambig = 0;
+       int indfound = 0;
+       int option_index;
+
+       /* This is an option that requires an argument.  */
+       if (*nextchar != '\0')
+         {
+           optarg = nextchar;
+           /* If we end this ARGV-element by taking the rest as an arg,
+              we must advance to the next element now.  */
+           optind++;
+         }
+       else if (optind == argc)
+         {
+           if (print_errors)
+             {
+               /* 1003.2 specifies the format of this message.  */
+               fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+                        argv[0], c);
+             }
+           optopt = c;
+           if (optstring[0] == ':')
+             c = ':';
+           else
+             c = '?';
+           return c;
+         }
+       else
+         /* We already incremented `optind' once;
+            increment it again when taking next ARGV-elt as argument.  */
+         optarg = argv[optind++];
+
+       /* optarg is now the argument, see if it's in the
+          table of longopts.  */
+
+       for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+         /* Do nothing.  */ ;
+
+       /* Test all long options for either exact match
+          or abbreviated matches.  */
+       for (p = longopts, option_index = 0; p->name; p++, option_index++)
+         if (!strncmp (p->name, nextchar, nameend - nextchar))
+           {
+             if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+               {
+                 /* Exact match found.  */
+                 pfound = p;
+                 indfound = option_index;
+                 exact = 1;
+                 break;
+               }
+             else if (pfound == NULL)
+               {
+                 /* First nonexact match found.  */
+                 pfound = p;
+                 indfound = option_index;
+               }
+             else
+               /* Second or later nonexact match found.  */
+               ambig = 1;
+           }
+       if (ambig && !exact)
+         {
+           if (print_errors)
+             fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+                      argv[0], argv[optind]);
+           nextchar += strlen (nextchar);
+           optind++;
+           return '?';
+         }
+       if (pfound != NULL)
+         {
+           option_index = indfound;
+           if (*nameend)
+             {
+               /* Don't test has_arg with >, because some C compilers don't
+                  allow it to be used on enums.  */
+               if (pfound->has_arg)
+                 optarg = nameend + 1;
+               else
+                 {
+                   if (print_errors)
+                     fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+                              argv[0], pfound->name);
+
+                   nextchar += strlen (nextchar);
+                   return '?';
+                 }
+             }
+           else if (pfound->has_arg == 1)
+             {
+               if (optind < argc)
+                 optarg = argv[optind++];
+               else
+                 {
+                   if (print_errors)
+                     fprintf (stderr,
+                              _("%s: option `%s' requires an argument\n"),
+                              argv[0], argv[optind - 1]);
+                   nextchar += strlen (nextchar);
+                   return optstring[0] == ':' ? ':' : '?';
+                 }
+             }
+           nextchar += strlen (nextchar);
+           if (longind != NULL)
+             *longind = option_index;
+           if (pfound->flag)
+             {
+               *(pfound->flag) = pfound->val;
+               return 0;
+             }
+           return pfound->val;
+         }
+         nextchar = NULL;
+         return 'W';   /* Let the application handle it.   */
+      }
+    if (temp[1] == ':')
+      {
+       if (temp[2] == ':')
+         {
+           /* This is an option that accepts an argument optionally.  */
+           if (*nextchar != '\0')
+             {
+               optarg = nextchar;
+               optind++;
+             }
+           else
+             optarg = NULL;
+           nextchar = NULL;
+         }
+       else
+         {
+           /* This is an option that requires an argument.  */
+           if (*nextchar != '\0')
+             {
+               optarg = nextchar;
+               /* If we end this ARGV-element by taking the rest as an arg,
+                  we must advance to the next element now.  */
+               optind++;
+             }
+           else if (optind == argc)
+             {
+               if (print_errors)
+                 {
+                   /* 1003.2 specifies the format of this message.  */
+                   fprintf (stderr,
+                            _("%s: option requires an argument -- %c\n"),
+                            argv[0], c);
+                 }
+               optopt = c;
+               if (optstring[0] == ':')
+                 c = ':';
+               else
+                 c = '?';
+             }
+           else
+             /* We already incremented `optind' once;
+                increment it again when taking next ARGV-elt as argument.  */
+             optarg = argv[optind++];
+           nextchar = NULL;
+         }
+      }
+    return c;
+  }
+}
+
+int
+getopt (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  return _getopt_internal (argc, argv, optstring,
+                          (const struct option *) 0,
+                          (int *) 0,
+                          0);
+}
+
+#endif /* Not ELIDE_CODE.  */
+\f
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+   the above definition of `getopt'.  */
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+
+      c = getopt (argc, argv, "abc:d:0123456789");
+      if (c == -1)
+       break;
+
+      switch (c)
+       {
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+         if (digit_optind != 0 && digit_optind != this_option_optind)
+           printf ("digits occur in two different argv-elements.\n");
+         digit_optind = this_option_optind;
+         printf ("option %c\n", c);
+         break;
+
+       case 'a':
+         printf ("option a\n");
+         break;
+
+       case 'b':
+         printf ("option b\n");
+         break;
+
+       case 'c':
+         printf ("option c with value `%s'\n", optarg);
+         break;
+
+       case '?':
+         break;
+
+       default:
+         printf ("?? getopt returned character code 0%o ??\n", c);
+       }
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+       printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/tools/getopt.h b/tools/getopt.h
new file mode 100644 (file)
index 0000000..76cf5ee
--- /dev/null
@@ -0,0 +1,179 @@
+/* Declarations for getopt.
+   Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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, 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.  */
+
+#ifndef _GETOPT_H
+
+#ifndef __need_getopt
+# define _GETOPT_H 1
+#endif
+
+/* If __GNU_LIBRARY__ is not already defined, either we are being used
+   standalone, or this is the first header included in the source file.
+   If we are being used with glibc, we need to include <features.h>, but
+   that does not exist if we are standalone.  So: if __GNU_LIBRARY__ is
+   not defined, include <ctype.h>, which will pull in <features.h> for us
+   if it's from glibc.  (Why ctype.h?  It's guaranteed to exist and it
+   doesn't flood the namespace with stuff the way some other headers do.)  */
+#if !defined __GNU_LIBRARY__
+# include <ctype.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns -1, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int optopt;
+
+#ifndef __need_getopt
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument         (or 0) if the option does not take an argument,
+   required_argument   (or 1) if the option requires an argument,
+   optional_argument   (or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+# if (defined __STDC__ && __STDC__) || defined __cplusplus
+  const char *name;
+# else
+  char *name;
+# endif
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+# define no_argument           0
+# define required_argument     1
+# define optional_argument     2
+#endif /* need getopt */
+
+
+/* Get definitions and prototypes for functions to process the
+   arguments in ARGV (ARGC of them, minus the program name) for
+   options given in OPTS.
+
+   Return the option character from OPTS just read.  Return -1 when
+   there are no more options.  For unrecognized options, or options
+   missing arguments, `optopt' is set to the option letter, and '?' is
+   returned.
+
+   The OPTS string is a list of characters which are recognized option
+   letters, optionally followed by colons, specifying that that letter
+   takes an argument, to be placed in `optarg'.
+
+   If a letter in OPTS is followed by two colons, its argument is
+   optional.  This behavior is specific to the GNU `getopt'.
+
+   The argument `--' causes premature termination of argument
+   scanning, explicitly telling `getopt' that there are no more
+   options.
+
+   If OPTS begins with `--', then non-option arguments are treated as
+   arguments to the option '\0'.  This behavior is specific to the GNU
+   `getopt'.  */
+
+#if (defined __STDC__ && __STDC__) || defined __cplusplus
+# ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+   differences in the consts, in stdlib.h.  To avoid compilation
+   errors, only prototype getopt for the GNU C library.  */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+# else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+# endif /* __GNU_LIBRARY__ */
+
+# ifndef __need_getopt
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+                       const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+                            const char *shortopts,
+                            const struct option *longopts, int *longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _getopt_internal (int argc, char *const *argv,
+                            const char *shortopts,
+                            const struct option *longopts, int *longind,
+                            int long_only);
+# endif
+#else /* not __STDC__ */
+extern int getopt ();
+# ifndef __need_getopt
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+# endif
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Make sure we later can get all the definitions and declarations.  */
+#undef __need_getopt
+
+#endif /* getopt.h */
diff --git a/tools/getopt1.c b/tools/getopt1.c
new file mode 100644 (file)
index 0000000..62c55cf
--- /dev/null
@@ -0,0 +1,187 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+   Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
+     Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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, 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.  */
+\f
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "getopt.h"
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+   reject `defined (const)'.  */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#endif
+
+#ifndef        NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+   If an option that starts with '-' (not '--') doesn't match a long option,
+   but does match a short option, it is parsed as a short option
+   instead.  */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif /* Not ELIDE_CODE.  */
+\f
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+      int option_index = 0;
+      static struct option long_options[] =
+      {
+       {"add", 1, 0, 0},
+       {"append", 0, 0, 0},
+       {"delete", 1, 0, 0},
+       {"verbose", 0, 0, 0},
+       {"create", 0, 0, 0},
+       {"file", 1, 0, 0},
+       {0, 0, 0, 0}
+      };
+
+      c = getopt_long (argc, argv, "abc:d:0123456789",
+                      long_options, &option_index);
+      if (c == -1)
+       break;
+
+      switch (c)
+       {
+       case 0:
+         printf ("option %s", long_options[option_index].name);
+         if (optarg)
+           printf (" with arg %s", optarg);
+         printf ("\n");
+         break;
+
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+         if (digit_optind != 0 && digit_optind != this_option_optind)
+           printf ("digits occur in two different argv-elements.\n");
+         digit_optind = this_option_optind;
+         printf ("option %c\n", c);
+         break;
+
+       case 'a':
+         printf ("option a\n");
+         break;
+
+       case 'b':
+         printf ("option b\n");
+         break;
+
+       case 'c':
+         printf ("option c with value `%s'\n", optarg);
+         break;
+
+       case 'd':
+         printf ("option d with value `%s'\n", optarg);
+         break;
+
+       case '?':
+         break;
+
+       default:
+         printf ("?? getopt returned character code 0%o ??\n", c);
+       }
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+       printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/tools/input.c b/tools/input.c
new file mode 100644 (file)
index 0000000..8dd7d0c
--- /dev/null
@@ -0,0 +1,442 @@
+/* input.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002, 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "input.h"
+
+void
+sexp_input_init(struct sexp_input *input, FILE *f)
+{
+  input->f = f;
+  input->coding = NULL;
+}
+
+static void
+sexp_get_raw_char(struct sexp_input *input)
+{
+  int c = getc(input->f);
+  
+  if (c < 0)
+    {
+      if (ferror(input->f))
+       die("Read error: %s\n", strerror(errno));
+      
+      input->ctype = SEXP_EOF_CHAR;
+    }
+  else
+    {
+      input->ctype = SEXP_NORMAL_CHAR;
+      input->c = c;
+    }
+}
+
+void
+sexp_get_char(struct sexp_input *input)
+{
+  if (input->coding)
+    for (;;)
+      {
+       unsigned done;
+
+       sexp_get_raw_char(input);
+       if (input->ctype == SEXP_EOF_CHAR)
+         die("Unexpected end of file in coded data.\n");
+
+       if (input->c == input->terminator)
+         {
+           input->ctype = SEXP_END_CHAR;
+           return;
+         }
+
+       done = 1;
+
+       /* Decodes in place. Should always work, when we decode one
+        * character at a time. */
+       if (!input->coding->decode_update(&input->state,
+                                         &done, &input->c,
+                                         1, &input->c))
+         die("Invalid coded data.\n");
+       
+       if (done)
+         return;
+      }
+  else
+    sexp_get_raw_char(input);
+}
+
+static uint8_t
+sexp_next_char(struct sexp_input *input)
+{
+  sexp_get_char(input);
+  if (input->ctype != SEXP_NORMAL_CHAR)
+    die("Unexpected end of file.\n");
+
+  return input->c;
+}
+
+static void
+sexp_push_char(struct sexp_input *input,
+              struct nettle_buffer *string)
+{
+  assert(input->ctype == SEXP_NORMAL_CHAR);
+    
+  if (!NETTLE_BUFFER_PUTC(string, input->c))
+    die("Virtual memory exhasuted.\n");
+}
+
+static void
+sexp_input_start_coding(struct sexp_input *input,
+                       const struct nettle_armor *coding,
+                       uint8_t terminator)
+{
+  assert(!input->coding);
+  
+  input->coding = coding;
+  input->coding->decode_init(&input->state);
+  input->terminator = terminator;
+}
+
+static void
+sexp_input_end_coding(struct sexp_input *input)
+{
+  assert(input->coding);
+
+  if (!input->coding->decode_final(&input->state))
+    die("Invalid coded data.\n");
+  
+  input->coding = NULL;
+}
+
+
+/* Return 0 at end-of-string */
+static int
+sexp_get_quoted_char(struct sexp_input *input)
+{
+  sexp_next_char(input);
+
+  for (;;)
+    switch (input->c)
+      {
+      default:
+       return 1;
+      case '\"':
+       return 0;
+      case '\\':
+       sexp_next_char(input);
+       
+       switch (input->c)
+         {
+         case 'b': input->c = '\b'; return 1;
+         case 't': input->c = '\t'; return 1;
+         case 'n': input->c = '\n'; return 1;
+         case 'f': input->c = '\f'; return 1;
+         case 'r': input->c = '\r'; return 1;
+         case '\\': input->c = '\\'; return 1;
+         case 'o':
+         case 'x':
+           /* FIXME: Not implemnted */
+           abort();
+         case '\n':
+           if (sexp_next_char(input) == '\r')
+             sexp_next_char(input);
+
+           break;
+         case '\r':
+           if (sexp_next_char(input) == '\n')
+             sexp_next_char(input);
+
+           break;
+         }
+       return 1;
+      }
+}
+
+static void
+sexp_get_token_string(struct sexp_input *input,
+                     struct nettle_buffer *string)
+{
+  assert(!input->coding);
+  assert(input->ctype == SEXP_NORMAL_CHAR);
+  
+  if (!TOKEN_CHAR(input->c))
+    die("Invalid token.\n");
+
+  do
+    {
+      sexp_push_char(input, string);
+      sexp_get_char(input);
+    }
+  while (input->ctype == SEXP_NORMAL_CHAR && TOKEN_CHAR(input->c));
+  
+  assert (string->size);
+}
+
+static void
+sexp_get_string(struct sexp_input *input,
+               struct nettle_buffer *string)
+{
+  nettle_buffer_reset(string);
+  input->token = SEXP_STRING;
+  
+  switch (input->c)
+    {
+    case '\"':
+      while (sexp_get_quoted_char(input))
+       sexp_push_char(input, string);
+      
+      sexp_get_char(input);
+      break;
+      
+    case '#':
+      sexp_input_start_coding(input, &nettle_base16, '#');
+      goto decode;
+
+    case '|':
+      sexp_input_start_coding(input, &nettle_base64, '|');
+
+    decode:
+      for (;;)
+       {
+         sexp_get_char(input);
+         switch (input->ctype)
+           {
+           case SEXP_NORMAL_CHAR:
+             sexp_push_char(input, string);
+             break;
+           case SEXP_EOF_CHAR:
+             die("Unexpected end of file in coded string.\n");
+           case SEXP_END_CHAR:
+             sexp_input_end_coding(input);
+             sexp_get_char(input);
+             return;
+           }
+       }
+
+      break;
+
+    default:
+      sexp_get_token_string(input, string);
+      break;
+    }
+}
+
+static void
+sexp_get_string_length(struct sexp_input *input, enum sexp_mode mode,
+                      struct nettle_buffer *string)
+{
+  unsigned length;
+
+  nettle_buffer_reset(string);
+  input->token = SEXP_STRING;
+  
+  length = input->c - '0';
+  
+  if (!length)
+    /* There must be no more digits */
+    sexp_next_char(input);
+
+  else
+    {
+      assert(length < 10);
+      /* Get rest of digits */
+      for (;;)
+       {
+         sexp_next_char(input);
+         
+         if (input->c < '0' || input->c > '9')
+           break;
+         
+         /* FIXME: Check for overflow? */
+         length = length * 10 + input->c - '0';
+       }
+    }
+
+  switch(input->c)
+    {
+    case ':':
+      /* Verbatim */
+      for (; length; length--)
+       {
+         sexp_next_char(input);
+         sexp_push_char(input, string);
+       }
+      
+      break;
+
+    case '"':
+      if (mode != SEXP_ADVANCED)
+       die("Encountered quoted string in canonical mode.\n");
+
+      for (; length; length--)
+       if (sexp_get_quoted_char(input))
+         sexp_push_char(input, string);
+       else
+         die("Unexpected end of string.\n");
+      
+      if (sexp_get_quoted_char(input))
+       die("Quoted string longer than expected.\n");
+
+      break;
+      
+    case '#':
+      sexp_input_start_coding(input, &nettle_base16, '#');
+      goto decode;
+
+    case '|':
+      sexp_input_start_coding(input, &nettle_base64, '|');
+
+    decode:
+      for (; length; length--)
+       {
+         sexp_next_char(input);
+         sexp_push_char(input, string);
+       }
+      sexp_get_char(input);
+      if (input->ctype != SEXP_END_CHAR)
+       die("Coded string too long.\n");
+
+      sexp_input_end_coding(input);
+      
+      break;
+      
+    default:
+      die("Invalid string.\n");
+    }
+
+  /* Skip the ending character. */
+  sexp_get_char(input);  
+}
+
+static void
+sexp_get_comment(struct sexp_input *input, struct nettle_buffer *string)
+{
+  nettle_buffer_reset(string);
+
+  assert(input->ctype == SEXP_NORMAL_CHAR);
+  assert(input->c == ';');
+
+  do
+    {
+      sexp_push_char(input, string);
+      sexp_get_raw_char(input);
+    }
+  while (input->ctype == SEXP_NORMAL_CHAR && input->c != '\n');
+
+  input->token = SEXP_COMMENT;
+}
+
+/* When called, input->c should be the first character of the current
+ * token.
+ *
+ * When returning, input->c should be the first character of the next
+ * token. */
+void
+sexp_get_token(struct sexp_input *input, enum sexp_mode mode,
+              struct nettle_buffer *string)
+{
+  for(;;)
+    switch(input->ctype)
+      {
+      case SEXP_EOF_CHAR:
+       input->token = SEXP_EOF;
+       return;
+
+      case SEXP_END_CHAR:
+       input->token = SEXP_CODING_END;
+       sexp_input_end_coding(input);
+       sexp_get_char(input);
+       return;
+
+      case SEXP_NORMAL_CHAR:
+       switch(input->c)
+         {
+         case '0': case '1': case '2': case '3': case '4':
+         case '5': case '6': case '7': case '8': case '9':
+           sexp_get_string_length(input, mode, string);
+           return;
+         
+         case '(':
+           input->token = SEXP_LIST_START;
+           sexp_get_char(input);
+           return;
+         
+         case ')':
+           input->token = SEXP_LIST_END;
+           sexp_get_char(input);
+           return;
+
+         case '[':
+           input->token = SEXP_DISPLAY_START;
+           sexp_get_char(input);
+           return;
+
+         case ']':
+           input->token = SEXP_DISPLAY_END;
+           sexp_get_char(input);
+           return;
+
+         case '{':
+           if (mode == SEXP_CANONICAL)
+             die("Unexpected transport data in canonical mode.\n");
+           
+           sexp_input_start_coding(input, &nettle_base64, '}');
+           sexp_get_char(input);
+
+           input->token = SEXP_TRANSPORT_START;
+           
+           return;
+         
+         case ' ':  /* SPC, TAB, LF, CR */
+         case '\t':
+         case '\n':
+         case '\r':
+           if (mode == SEXP_CANONICAL)
+             die("Whitespace encountered in canonical mode.\n");
+
+           sexp_get_char(input);
+           break;
+
+         case ';': /* Comments */
+           if (mode == SEXP_CANONICAL)
+             die("Comment encountered in canonical mode.\n");
+
+           sexp_get_comment(input, string);
+           return;
+         
+         default:
+           /* Ought to be a string */
+           if (mode != SEXP_ADVANCED)
+             die("Encountered advanced string in canonical mode.\n");
+
+           sexp_get_string(input, string);
+           return;
+         }
+      }
+}
diff --git a/tools/input.h b/tools/input.h
new file mode 100644 (file)
index 0000000..5c59add
--- /dev/null
@@ -0,0 +1,76 @@
+/* input.h */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002, 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_TOOLS_INPUT_H_INCLUDED
+#define NETTLE_TOOLS_INPUT_H_INCLUDED
+
+#include "misc.h"
+
+#include "base16.h"
+#include "base64.h"
+#include "buffer.h"
+#include "nettle-meta.h"
+
+#include <stdio.h>
+
+/* Special marks in the input stream */
+enum sexp_char_type
+  {
+    SEXP_NORMAL_CHAR = 0,
+    SEXP_EOF_CHAR, SEXP_END_CHAR,
+  };
+
+struct sexp_input
+{
+  FILE *f;
+
+  /* Character stream, consisting of ordinary characters,
+   * SEXP_EOF_CHAR, and SEXP_END_CHAR. */
+  enum sexp_char_type ctype;
+  uint8_t c;
+  
+  const struct nettle_armor *coding;
+
+  union {
+    struct base64_decode_ctx base64;
+    struct base16_decode_ctx hex;
+  } state;
+
+  /* Terminator for current coding */
+  uint8_t terminator;
+  
+  /* Type of current token */
+  enum sexp_token token;
+};
+
+void
+sexp_input_init(struct sexp_input *input, FILE *f);
+
+void
+sexp_get_char(struct sexp_input *input);
+
+void
+sexp_get_token(struct sexp_input *input, enum sexp_mode mode,
+              struct nettle_buffer *string);
+
+
+#endif /* NETTLE_TOOLS_INPUT_H_INCLUDED */
diff --git a/tools/misc.c b/tools/misc.c
new file mode 100644 (file)
index 0000000..bd20842
--- /dev/null
@@ -0,0 +1,84 @@
+/* misc.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002, 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "misc.h"
+
+void
+die(const char *format, ...)
+{
+  va_list args;
+  va_start(args, format);
+  vfprintf(stderr, format, args);
+  va_end(args);
+
+  exit(EXIT_FAILURE);
+}
+
+void
+werror(const char *format, ...)
+{
+  va_list args;
+  va_start(args, format);
+  vfprintf(stderr, format, args);
+  va_end(args);
+}
+
+void *
+xalloc(size_t size)
+{
+  void *p = malloc(size);
+  if (!p)
+    {
+      fprintf(stderr, "Virtual memory exhausted.\n");
+      abort();
+    }
+
+  return p;
+}
+
+const char
+sexp_token_chars[0x80] =
+  {
+    /* 0, ... 0x1f */
+    0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+/* SPC ! " # $ % & ' ( ) * + , - . / */
+    0,0,0,0,0,0,0,0, 0,0,1,1,0,1,1,1,
+ /* 0 1 2 3 4 5 6 7  8 9 : ; < = > ? */
+    1,1,1,1,1,1,1,1, 1,1,1,0,0,1,0,0,
+    /* @ A ... O */
+    0,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,  
+    /* P ...             Z [ \ ] ^ _ */
+    1,1,1,1,1,1,1,1, 1,1,1,0,0,0,0,1,
+    /* ` a, ... o */
+    0,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,  
+    /* p ...             z { | } ~ DEL */
+    1,1,1,1,1,1,1,1, 1,1,1,0,0,0,0,0,
+  };
diff --git a/tools/misc.h b/tools/misc.h
new file mode 100644 (file)
index 0000000..828fe9b
--- /dev/null
@@ -0,0 +1,77 @@
+/* misc.h */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002, 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_TOOLS_MISC_H_INCLUDED
+#define NETTLE_TOOLS_MISC_H_INCLUDED
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+void
+die(const char *format, ...)
+#if __GNUC___
+     __attribute__((__format__ (__printf__,1, 2)))
+     __attribute__((__noreturn__))
+#endif
+     ;
+
+void
+werror(const char *format, ...)
+#if __GNUC___
+     __attribute__((__format__ (__printf__,1, 2)))
+#endif
+     ;
+
+void *
+xalloc(size_t size);
+
+enum sexp_mode
+  {
+    SEXP_CANONICAL = 0,
+    SEXP_ADVANCED = 1,
+    SEXP_TRANSPORT = 2,
+  };
+
+enum sexp_token
+  {
+    SEXP_STRING,
+    SEXP_DISPLAY, /* Constructed by sexp_parse */
+    SEXP_COMMENT,
+    SEXP_LIST_START,
+    SEXP_LIST_END,
+    SEXP_EOF,
+
+    /* The below types are internal to the input parsing. sexp_parse
+     * should never return a token of this type. */
+    SEXP_DISPLAY_START,
+    SEXP_DISPLAY_END,
+    SEXP_TRANSPORT_START,
+    SEXP_CODING_END,
+  };
+
+extern const char
+sexp_token_chars[0x80];
+
+#define TOKEN_CHAR(c) ((c) < 0x80 && sexp_token_chars[(c)])
+
+#endif /* NETTLE_TOOLS_MISC_H_INCLUDED */
diff --git a/tools/nettle-hash.c b/tools/nettle-hash.c
new file mode 100644 (file)
index 0000000..afb388e
--- /dev/null
@@ -0,0 +1,232 @@
+/* nettle-hash.c
+ *
+ * General hashing tool. */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2011 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "nettle-meta.h"
+#include "base16.h"
+
+#include "getopt.h"
+#include "misc.h"
+
+#define BUFSIZE 16384
+
+static void
+list_algorithms (void)
+{
+  unsigned i;
+  const struct nettle_hash *alg;
+  printf ("%10s digestsize (internal block size), in units of octets\n", "name");
+
+  for (i = 0; (alg = nettle_hashes[i]); i++)
+    printf ("%10s %d (%d)\n",
+           alg->name, alg->digest_size, alg->block_size);
+};
+
+static const struct nettle_hash *
+find_algorithm (const char *name)
+{
+  const struct nettle_hash *alg;
+  unsigned i;
+  
+  for (i = 0; (alg = nettle_hashes[i]); i++)
+    if (!strcmp(name, alg->name))
+      return alg;
+
+  return NULL;
+}
+
+/* Also in examples/io.c */
+static int
+hash_file(const struct nettle_hash *hash, void *ctx, FILE *f)
+{
+  for (;;)
+    {
+      char buffer[BUFSIZE];
+      size_t res = fread(buffer, 1, sizeof(buffer), f);
+      if (ferror(f))
+       return 0;
+      
+      hash->update(ctx, res, buffer);
+      if (feof(f))
+       return 1;
+    }
+}
+
+static int
+digest_file(const struct nettle_hash *alg,
+           unsigned digest_length, int raw,
+           FILE *f)
+{
+  void *ctx;
+  uint8_t *digest;
+  ctx = xalloc(alg->context_size);
+
+  alg->init(ctx);
+
+  if (!hash_file (alg, ctx, f))
+    {
+      free (ctx);
+      return 0;
+    }
+
+  digest = xalloc(digest_length);
+  alg->digest(ctx, digest_length, digest);
+  free(ctx);
+
+  if (raw)
+    fwrite (digest, digest_length, 1, stdout);
+
+  else
+    {
+      unsigned i;
+      char *hex = xalloc(BASE16_ENCODE_LENGTH(8) + 1);
+      for (i = 0; i + 8 < digest_length; i += 8)
+       {
+         base16_encode_update(hex, 8, digest + i);
+         hex[BASE16_ENCODE_LENGTH(8)] = 0;
+         printf("%s ", hex);
+       }
+      base16_encode_update(hex, digest_length - i, digest + i);
+      hex[BASE16_ENCODE_LENGTH(digest_length - i)] = 0;
+      printf("%s %s\n", hex, alg->name);
+      free(hex);
+    }
+  
+  free(digest);
+
+  return 1;
+}
+
+/* FIXME: Be more compatible with md5sum and sha1sum. Options -c
+   (check), -b (binary), -t (text), and output format with hex hash
+   sum, optional star (meaning binary mode), and file name. */
+int
+main (int argc, char **argv)
+{
+  const char *alg_name = NULL;
+  const struct nettle_hash *alg;
+  unsigned length = 0;
+  int raw = 0;
+  int c;
+
+  enum { OPT_HELP = 0x300, OPT_RAW, OPT_LIST };
+  static const struct option options[] =
+    {
+      /* Name, args, flag, val */
+      { "help", no_argument, NULL, OPT_HELP },
+      { "version", no_argument, NULL, 'V' },
+      { "algorithm", required_argument, NULL, 'a' },
+      { "length", required_argument, NULL, 'l' },
+      { "list", no_argument, NULL, OPT_LIST },
+      { "raw", no_argument, NULL, OPT_RAW },
+
+      { NULL, 0, NULL, 0 }
+    };
+
+  while ( (c = getopt_long(argc, argv, "Va:l:", options, NULL)) != -1)
+    switch (c)
+      {
+      default:
+       abort();
+      case OPT_HELP:
+       printf("nettle-hash -a ALGORITHM [OPTIONS] [FILE ...]\n"
+              "Options:\n"
+              "  --help              Show this help.\n"
+              "  -V, --version       Show version information.\n"
+              "  --list              List supported hash algorithms.\n"
+              "  -a, --algorithm=ALG Hash algorithm to use.\n"
+              "  -l, --length=LENGTH Desired digest length (octets)\n"
+              "  --raw               Raw binary output.\n");
+       return EXIT_SUCCESS;
+      case 'V':
+       printf("nettle-hash (" PACKAGE_STRING ")\n");
+       return EXIT_SUCCESS;
+      case 'a':
+       alg_name = optarg;
+       break;
+      case 'l':
+       {
+         int arg;
+         arg = atoi (optarg);
+         if (arg <= 0)
+           die ("Invalid length argument: `%s'\n", optarg);
+         length = arg;
+       }
+       break;
+      case OPT_RAW:
+       raw = 1;
+       break;
+      case OPT_LIST:
+       list_algorithms();
+       return EXIT_SUCCESS;
+      }
+
+  if (!alg_name)
+    die("Algorithm argument (-a option) is mandatory.\n"
+       "See nettle-hash --help for further information.\n");
+      
+  alg = find_algorithm (alg_name);
+  if (!alg)
+    die("Hash algorithm `%s' not supported or .\n"
+       "Use nettle-hash --list to list available algorithms.\n",
+       alg_name);
+
+  if (length == 0)
+    length = alg->digest_size;
+  else if (length > alg->digest_size)
+    die ("Length argument %d too large for selected algorithm.\n",
+        length);
+    
+  argv += optind;
+  argc -= optind;
+
+  if (argc == 0)
+    digest_file (alg, length, raw, stdin);
+  else
+    {
+      int i;
+      for (i = 0; i < argc; i++)
+       {
+         FILE *f = fopen (argv[i], "rb");
+         if (!f)
+           die ("Cannot open `%s': %s\n", argv[i], STRERROR(errno));
+         printf("%s: ", argv[i]);
+         if (!digest_file (alg, length, raw, f))
+           die("Reading `%s' failed: %s\n", argv[i], STRERROR(errno));
+         fclose(f);
+       }
+    }
+  if (fflush(stdout) != 0 )
+    die("Write failed: %s\n", STRERROR(errno));
+
+  return EXIT_SUCCESS;
+}
diff --git a/tools/nettle-lfib-stream.c b/tools/nettle-lfib-stream.c
new file mode 100644 (file)
index 0000000..641a2f7
--- /dev/null
@@ -0,0 +1,85 @@
+/* lfib-stream.c
+ *
+ * Generates a pseudorandom stream, using the Knuth lfib
+ * (non-cryptographic) pseudorandom generator.
+ *
+ */
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "knuth-lfib.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <time.h>
+
+#define BUFSIZE 500
+
+static void
+usage(void)
+{
+  fprintf(stderr, "Usage: lfib-stream [SEED]\n");
+}
+
+int
+main(int argc, char **argv)
+{
+  struct knuth_lfib_ctx ctx;
+  uint32_t seed;
+
+  if (argc == 1)
+    seed = time(NULL);
+
+  else if (argc == 2)
+    {
+      seed = atoi(argv[1]);
+      if (!seed)
+       {
+         usage();
+         return EXIT_FAILURE;
+       }
+    }
+  else
+    {
+      usage();
+      return EXIT_FAILURE;
+    }
+
+  knuth_lfib_init(&ctx, seed);
+
+  for (;;)
+    {
+      char buffer[BUFSIZE];
+      knuth_lfib_random(&ctx, BUFSIZE, buffer);
+
+      if (fwrite(buffer, 1, BUFSIZE, stdout) < BUFSIZE
+         || fflush(stdout) < 0)
+       return EXIT_FAILURE;
+    }
+
+  /* Not reached. This program is usually terminated by SIGPIPE */
+}
diff --git a/tools/output.c b/tools/output.c
new file mode 100644 (file)
index 0000000..d491d9a
--- /dev/null
@@ -0,0 +1,303 @@
+/* output.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002, 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "output.h"
+
+/* For TMP_ALLOC */ 
+#include "nettle-internal.h"
+
+void
+sexp_output_init(struct sexp_output *output, FILE *f,
+                unsigned width, int prefer_hex)
+{
+  output->f = f;
+  output->line_width = width;
+  output->coding = NULL;
+  output->prefer_hex = prefer_hex;
+  output->hash = NULL;
+  output->ctx = NULL;
+  
+  output->pos = 0;
+  output->soft_newline = 0;
+}
+
+void
+sexp_output_hash_init(struct sexp_output *output,
+                     const struct nettle_hash *hash, void *ctx)
+{
+  output->hash = hash;
+  output->ctx = ctx;
+  hash->init(ctx);
+}
+
+static void
+sexp_put_raw_char(struct sexp_output *output, uint8_t c)
+{
+  if (putc(c, output->f) < 0)
+    die("Write failed: %s\n", strerror(errno));
+
+  output->pos++;
+  output->soft_newline = 0;
+}
+
+void
+sexp_put_newline(struct sexp_output *output,
+                unsigned indent)
+{
+  if (output->soft_newline)
+    output->soft_newline = 0;
+  else
+    {
+      unsigned i;
+
+      sexp_put_raw_char(output, '\n');
+      output->pos = 0;
+  
+      for(i = 0; i < indent; i++)
+       sexp_put_raw_char(output, ' ');
+  
+      output->pos = indent;
+    }
+}
+
+/* Put a newline, but only if it is followed by another newline,
+   collaps to one newline only. */
+void
+sexp_put_soft_newline(struct sexp_output *output,
+                     unsigned indent)
+{
+  sexp_put_newline(output, indent);
+  output->soft_newline = 1;
+}
+
+void
+sexp_put_char(struct sexp_output *output, uint8_t c)
+{
+  if (output->coding)
+    {
+      /* Two is enough for both base16 and base64. */
+      uint8_t encoded[2];
+      unsigned done;
+
+      unsigned i;
+
+      done = output->coding->encode_update(&output->base64, encoded,
+                                          1, &c);
+      assert(done <= sizeof(encoded));
+      
+      for (i = 0; i<done; i++)
+       {
+         if (output->line_width
+             && output->pos >= output->line_width
+             && output->pos >= (output->coding_indent + 10))
+           sexp_put_newline(output, output->coding_indent);
+         
+         sexp_put_raw_char(output, encoded[i]);
+       }
+    }
+  else if (output->hash)
+    output->hash->update(output->ctx, 1, &c);
+  else
+    sexp_put_raw_char(output, c);
+}
+
+void
+sexp_put_data(struct sexp_output *output,
+             unsigned length, const uint8_t *data)
+{
+  unsigned i;
+
+  for (i = 0; i<length; i++)
+    sexp_put_char(output, data[i]);
+}
+
+static void
+sexp_put_length(struct sexp_output *output, 
+               unsigned length)
+{
+  unsigned digit = 1;
+
+  for (;;)
+    {
+      unsigned next = digit * 10;
+      if (next > length)
+       break;
+      digit = next;
+    }
+
+  for (; digit; length %= digit, digit /= 10)
+    sexp_put_char(output, '0' + length / digit);
+}
+
+void
+sexp_put_code_start(struct sexp_output *output,
+                   const struct nettle_armor *coding)
+{
+  assert(!output->coding);
+  
+  output->coding_indent = output->pos;
+  
+  output->coding = coding;
+  output->coding->encode_init(&output->base64);
+}
+
+void
+sexp_put_code_end(struct sexp_output *output)
+{
+  /* Enough for both hex and base64 */
+  uint8_t encoded[BASE64_ENCODE_FINAL_LENGTH];
+  unsigned done;
+
+  assert(output->coding);
+
+  done = output->coding->encode_final(&output->base64, encoded);
+
+  assert(done <= sizeof(encoded));
+  
+  output->coding = NULL;
+
+  sexp_put_data(output, done, encoded);
+}
+
+void
+sexp_put_string(struct sexp_output *output, enum sexp_mode mode,
+               struct nettle_buffer *string)
+{
+  if (!string->size)
+    sexp_put_data(output, 2,
+                 (mode == SEXP_ADVANCED) ? "\"\"": "0:");
+
+  else if (mode == SEXP_ADVANCED)
+    {
+      unsigned i;
+      int token = (string->contents[0] < '0' || string->contents[0] > '9');
+      int quote_friendly = 1;
+#define CONTROL_SIZE 0x20
+      static const char escape_names[CONTROL_SIZE] =
+       {
+         0,0,0,0,0,0,0,0, 'b','t','n',0,'f','r',0,0,
+         0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0
+       };
+
+      for (i = 0; i<string->size; i++)
+       {
+         uint8_t c = string->contents[i];
+         
+         if (token & !TOKEN_CHAR(c))
+           token = 0;
+         
+         if (quote_friendly)
+           {
+             if (c >= 0x7f)
+               quote_friendly = 0;
+             else if (c < CONTROL_SIZE && !escape_names[c])
+               quote_friendly = 0;
+           }
+       }
+      
+      if (token)
+       sexp_put_data(output, string->size, string->contents);
+
+      else if (quote_friendly)
+       {
+         sexp_put_char(output, '"');
+
+         for (i = 0; i<string->size; i++)
+           {
+             int escape = 0;
+             uint8_t c = string->contents[i];
+
+             assert(c < 0x7f);
+             
+             if (c == '\\' || c == '"')
+               escape = 1;
+             else if (c < CONTROL_SIZE)
+               {
+                 escape = 1;
+                 c = escape_names[c];
+                 assert(c);
+               }
+             if (escape)
+               sexp_put_char(output, '\\');
+
+             sexp_put_char(output, c);
+           }
+         
+         sexp_put_char(output, '"');
+       }
+      else 
+       {
+         uint8_t delimiter;
+         const struct nettle_armor *coding;
+         
+         if (output->prefer_hex)
+           {
+             delimiter = '#';
+             coding = &nettle_base16;
+           }
+         else
+           {
+             delimiter = '|';
+             coding = &nettle_base64;
+           }
+         
+         sexp_put_char(output, delimiter);
+         sexp_put_code_start(output, coding);
+         sexp_put_data(output, string->size, string->contents);
+         sexp_put_code_end(output);
+         sexp_put_char(output, delimiter);
+       }
+#undef CONTROL_SIZE
+    }
+  else
+    {
+      sexp_put_length(output, string->size);
+      sexp_put_char(output, ':');
+      sexp_put_data(output, string->size, string->contents);
+    }
+}
+
+void
+sexp_put_digest(struct sexp_output *output)
+{
+  TMP_DECL(digest, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE);
+  TMP_ALLOC(digest, output->hash->digest_size);
+  
+  assert(output->hash);
+
+  output->hash->digest(output->ctx, output->hash->digest_size, digest);
+
+  sexp_put_code_start(output, &nettle_base16);
+  sexp_put_data(output, output->hash->digest_size, digest);
+  sexp_put_code_end(output);
+}
+
diff --git a/tools/output.h b/tools/output.h
new file mode 100644 (file)
index 0000000..8ac5256
--- /dev/null
@@ -0,0 +1,93 @@
+/* output.h */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002, 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_TOOLS_OUTPUT_H_INCLUDED
+#define NETTLE_TOOLS_OUTPUT_H_INCLUDED
+
+#include "misc.h"
+
+#include "base64.h"
+#include "buffer.h"
+#include "nettle-meta.h"
+
+#include <stdio.h>
+
+struct sexp_output
+{
+  FILE *f;
+
+  unsigned line_width;
+  
+  const struct nettle_armor *coding;
+  unsigned coding_indent;
+
+  int prefer_hex;
+  
+  const struct nettle_hash *hash;
+  void *ctx;
+  
+  /* NOTE: There's no context for hex encoding, the state argument to
+     encode_update is ignored */
+  struct base64_decode_ctx base64;
+  
+  unsigned pos;
+  int soft_newline;
+};
+
+void
+sexp_output_init(struct sexp_output *output, FILE *f,
+                unsigned width, int prefer_hex);
+
+void
+sexp_output_hash_init(struct sexp_output *output,
+                     const struct nettle_hash *hash, void *ctx);
+
+void 
+sexp_put_newline(struct sexp_output *output,
+                unsigned indent);
+
+void
+sexp_put_soft_newline(struct sexp_output *output,
+                     unsigned indent);
+
+void
+sexp_put_char(struct sexp_output *output, uint8_t c);
+
+void
+sexp_put_data(struct sexp_output *output,
+             unsigned length, const uint8_t *data);
+
+void
+sexp_put_code_start(struct sexp_output *output,
+                   const struct nettle_armor *coding);
+
+void
+sexp_put_code_end(struct sexp_output *output);
+
+void
+sexp_put_string(struct sexp_output *output, enum sexp_mode mode,
+               struct nettle_buffer *string);
+
+void
+sexp_put_digest(struct sexp_output *output);
+
+#endif /* NETTLE_TOOLS_OUTPUT_H_INCLUDED */
diff --git a/tools/parse.c b/tools/parse.c
new file mode 100644 (file)
index 0000000..292c6ce
--- /dev/null
@@ -0,0 +1,164 @@
+/* parse.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002, 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "parse.h"
+
+#include "input.h"
+
+void
+sexp_compound_token_init(struct sexp_compound_token *token)
+{
+  token->type = 0;
+  nettle_buffer_init(&token->display);
+  nettle_buffer_init(&token->string);
+}
+
+void
+sexp_compound_token_clear(struct sexp_compound_token *token)
+{
+  nettle_buffer_clear(&token->display);
+  nettle_buffer_clear(&token->string);
+}
+
+void
+sexp_parse_init(struct sexp_parser *parser,
+               struct sexp_input *input,
+               enum sexp_mode mode)
+{
+  parser->input = input;
+  parser->mode = mode;
+
+  /* Start counting with 1 for the top level, to make comparisons
+   * between transport and level simpler.
+   *
+   * FIXME: Is that trick ugly? */
+  parser->level = 1;
+  parser->transport = 0;
+}
+
+/* Get next token, and check that it is of the expected kind. */
+static void
+sexp_check_token(struct sexp_parser *parser,
+                enum sexp_token token,
+                struct nettle_buffer *string)
+{
+  sexp_get_token(parser->input,
+                parser->transport ? SEXP_CANONICAL : parser->mode,
+                string);
+
+  if (parser->input->token != token)
+    die("Syntax error.\n");
+}
+
+/* Performs further processing of the input, in particular display
+ * types and transport decoding.
+ *
+ * This is complicated a little by the requirement that a
+ * transport-encoded block, {xxxxx}, must include exactly one
+ * expression. We check at the end of strings and list whether or not
+ * we should expect a SEXP_CODING_END as the next token. */
+void
+sexp_parse(struct sexp_parser *parser,
+          struct sexp_compound_token *token)
+{
+  for (;;)
+    {
+      sexp_get_token(parser->input,
+                    parser->transport ? SEXP_CANONICAL : parser->mode,
+                    &token->string);
+
+      switch(parser->input->token)
+       {
+       case SEXP_LIST_END:
+         if (parser->level == parser->transport)
+           die("Unmatched end of list in transport encoded data.\n");
+         parser->level--;
+
+         if (!parser->level)
+           die("Unmatched end of list.\n");
+
+         token->type = SEXP_LIST_END;
+
+       check_transport_end:
+         if (parser->level == parser->transport)
+           {
+             sexp_check_token(parser, SEXP_CODING_END, &token->string);
+             assert(parser->transport);
+             assert(parser->level == parser->transport);
+
+             parser->level--;
+             parser->transport = 0;
+           }
+         return;
+    
+       case SEXP_EOF:
+         if (parser->level > 1)
+           die("Unexpected end of file.\n");
+
+         token->type = SEXP_EOF;
+         return;
+
+       case SEXP_LIST_START:
+         parser->level++;
+         token->type = SEXP_LIST_START;
+         return;
+
+       case SEXP_DISPLAY_START:
+         sexp_check_token(parser, SEXP_STRING, &token->display);
+         sexp_check_token(parser, SEXP_DISPLAY_END, &token->display);
+         sexp_check_token(parser, SEXP_STRING, &token->string);
+
+         token->type = SEXP_DISPLAY;
+         goto check_transport_end;
+
+       case SEXP_STRING:
+         token->type = SEXP_STRING;
+         goto check_transport_end;
+
+       case SEXP_COMMENT:
+         token->type = SEXP_COMMENT;
+         return;
+
+       case SEXP_TRANSPORT_START:
+         if (parser->mode == SEXP_CANONICAL)
+           die("Base64 not allowed in canonical mode.\n");
+         parser->level++;
+         parser->transport = parser->level;
+
+         continue;
+
+       case SEXP_CODING_END:
+         die("Unexpected end of transport encoding.\n");
+         
+       default:
+         /* Internal error. */
+         abort();
+       }
+    }
+}
diff --git a/tools/parse.h b/tools/parse.h
new file mode 100644 (file)
index 0000000..df6f8b4
--- /dev/null
@@ -0,0 +1,65 @@
+/* parse.h */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002, 2003 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef NETTLE_TOOLS_PARSE_H_INCLUDED
+#define NETTLE_TOOLS_PARSE_H_INCLUDED
+
+#include "misc.h"
+#include "buffer.h"
+
+struct sexp_compound_token
+{
+  enum sexp_token type;
+  struct nettle_buffer display;
+  struct nettle_buffer string;  
+};
+
+void
+sexp_compound_token_init(struct sexp_compound_token *token);
+
+void
+sexp_compound_token_clear(struct sexp_compound_token *token);
+
+struct sexp_parser
+{
+  struct sexp_input *input;
+  enum sexp_mode mode;
+
+  /* Nesting level of lists. Transport encoding counts as one
+   * level of nesting. */
+  unsigned level;
+
+  /* The nesting level where the transport encoding occured.
+   * Zero if we're not currently using tranport encoding. */
+  unsigned transport;
+};
+
+void
+sexp_parse_init(struct sexp_parser *parser,
+               struct sexp_input *input,
+               enum sexp_mode mode);
+
+void
+sexp_parse(struct sexp_parser *parser,
+          struct sexp_compound_token *token);
+
+#endif /* NETTLE_TOOLS_PARSE_H_INCLUDED */
diff --git a/tools/pkcs1-conv.c b/tools/pkcs1-conv.c
new file mode 100644 (file)
index 0000000..c9c7ff4
--- /dev/null
@@ -0,0 +1,660 @@
+/* pkcs1-conv.c
+ *
+ * Converting pkcs#1 and similar keys to sexp format. */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2005, 2009 Niels Möller, Magnus Holmgren
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "asn1.h"
+#include "base64.h"
+#include "buffer.h"
+#include "rsa.h"
+#include "dsa.h"
+
+#include "getopt.h"
+#include "misc.h"
+
+enum object_type
+  {
+    /* Use a range of values which also work as option id:s */
+    RSA_PRIVATE_KEY = 0x200,
+    RSA_PUBLIC_KEY,
+    DSA_PRIVATE_KEY,
+    /* DSA public keys only supported as part of a
+       SubjectPublicKeyInfo, i.e., the GENERAL_PUBLIC_KEY case. */
+    GENERAL_PUBLIC_KEY,
+  };
+
+static int
+write_file(struct nettle_buffer *buffer, FILE *f)
+{
+  size_t res = fwrite(buffer->contents, 1, buffer->size, f);
+  if (res < buffer->size)
+    {
+      werror("Write failed: %s.\n", strerror(errno));
+      return 0;
+    }
+  else
+    return 1;
+}
+
+/* Return 1 on success, 0 on error, -1 on eof */
+static int
+read_line(struct nettle_buffer *buffer, FILE *f)
+{
+  int c;
+  
+  while ((c = getc(f)) != EOF)
+    {
+      if (!NETTLE_BUFFER_PUTC(buffer, c))
+       return 0;
+
+      if (c == '\n')
+       return 1;
+    }
+  if (ferror(f))
+    {
+      werror("Read failed: %s\n", strerror(errno));
+      return 0;
+    }
+  
+  else 
+    return -1;
+}
+
+static int
+read_file(struct nettle_buffer *buffer, FILE *f)
+{
+  int c;
+  
+  while ((c = getc(f)) != EOF)
+    if (!NETTLE_BUFFER_PUTC(buffer, c))
+      return 0;
+
+  if (ferror(f))
+    {
+      werror("Read failed: %s\n", strerror(errno));
+      return 0;
+    }
+  else
+    return 1;
+}
+
+static const uint8_t
+pem_start_pattern[11] = "-----BEGIN ";
+
+static const uint8_t
+pem_end_pattern[9] = "-----END ";
+
+static const uint8_t
+pem_trailer_pattern[5] = "-----";
+
+static const char
+pem_ws[33] = {
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0, /* \t, \n, \v, \f, \r */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1 /* SPC */
+};
+
+#define PEM_IS_SPACE(c) ((c) < sizeof(pem_ws) && pem_ws[(c)]) 
+
+/* Returns 1 on match, otherwise 0. */ 
+static int
+match_pem_start(unsigned length, const uint8_t *line,
+               unsigned *marker_start,
+               unsigned *marker_length)
+{
+  while (length > 0 && PEM_IS_SPACE(line[length - 1]))
+    length--;
+
+  if (length > (sizeof(pem_start_pattern) + sizeof(pem_trailer_pattern))
+      && memcmp(line, pem_start_pattern, sizeof(pem_start_pattern)) == 0
+      && memcmp(line + length - sizeof(pem_trailer_pattern),
+               pem_trailer_pattern, sizeof(pem_trailer_pattern)) == 0)
+    {
+      *marker_start = 11;
+      *marker_length = length - (sizeof(pem_start_pattern) + sizeof(pem_trailer_pattern));
+
+      return 1;
+    }
+  else
+    return 0;
+}
+
+/* Returns 1 on match, -1 if the line is of the right form except for
+   the marker, otherwise 0. */ 
+static int
+match_pem_end(unsigned length, const uint8_t *line,
+             unsigned marker_length,
+             const uint8_t *marker)
+{
+  while (length > 0 && PEM_IS_SPACE(line[length - 1]))
+    length--;
+
+  if (length > (sizeof(pem_end_pattern) + sizeof(pem_trailer_pattern))
+      && memcmp(line, pem_end_pattern, sizeof(pem_end_pattern)) == 0
+      && memcmp(line + length - sizeof(pem_trailer_pattern),
+               pem_trailer_pattern, sizeof(pem_trailer_pattern)) == 0)
+    {
+      /* Right form. Check marker */
+      if (length == marker_length + (sizeof(pem_end_pattern) + sizeof(pem_trailer_pattern))
+         && memcmp(line + sizeof(pem_end_pattern), marker, marker_length) == 0)
+       return 1;
+      else
+       return -1;
+    }
+  else
+    return 0;  
+}
+
+struct pem_info
+{
+  /* The FOO part in "-----BEGIN FOO-----" */
+  unsigned marker_start;
+  unsigned marker_length;
+  unsigned data_start;
+  unsigned data_length;
+};
+
+static int
+read_pem(struct nettle_buffer *buffer, FILE *f,
+        struct pem_info *info)
+{  
+  /* Find start line */
+  for (;;)
+    {
+      int res;
+
+      nettle_buffer_reset(buffer);
+
+      res = read_line(buffer, f);
+      if (res != 1)
+       return res;
+
+      if (match_pem_start(buffer->size, buffer->contents,
+                         &info->marker_start, &info->marker_length))
+       break;
+    }
+
+  /* NUL-terminate the marker. Don't care to check for embedded NULs. */
+  buffer->contents[info->marker_start + info->marker_length] = 0;
+
+  info->data_start = buffer->size;
+
+  for (;;)
+    {
+      unsigned line_start = buffer->size;
+
+      if (read_line(buffer, f) != 1)
+       return 0;
+
+      switch (match_pem_end(buffer->size - line_start,
+                           buffer->contents + line_start,
+                           info->marker_length,
+                           buffer->contents + info->marker_start))
+       {
+       case 0:
+         break;
+       case -1:
+         werror("PEM END line doesn't match BEGIN.\n");
+         return 0;
+       case 1:
+         /* Return base 64 data; let caller do the decoding */ 
+         info->data_length = line_start - info->data_start;
+         return 1;
+       }
+    }
+}
+
+static int
+decode_base64(struct nettle_buffer *buffer,
+             unsigned start, unsigned *length)
+{
+  struct base64_decode_ctx ctx;
+  
+  base64_decode_init(&ctx);
+
+  /* Decode in place */
+  if (base64_decode_update(&ctx,
+                          length, buffer->contents + start,
+                          *length, buffer->contents + start)
+      && base64_decode_final(&ctx))
+    return 1;
+  
+  else
+    {
+      werror("Invalid base64 date.\n");
+      return 0;
+    }
+}
+
+static int
+convert_rsa_public_key(struct nettle_buffer *buffer, unsigned length, const uint8_t *data)
+{
+  struct rsa_public_key pub;
+  int res;
+  
+  rsa_public_key_init(&pub);
+
+  if (rsa_keypair_from_der(&pub, NULL, 0,
+                          length, data))
+    {
+      /* Reuses the buffer */
+      nettle_buffer_reset(buffer);
+      res = rsa_keypair_to_sexp(buffer, NULL, &pub, NULL);
+    }
+  else
+    {
+      werror("Invalid PKCS#1 public key.\n");
+      res = 0;
+    }
+  rsa_public_key_clear(&pub);
+  return res;
+}
+
+static int
+convert_rsa_private_key(struct nettle_buffer *buffer, unsigned length, const uint8_t *data)
+{
+  struct rsa_public_key pub;
+  struct rsa_private_key priv;
+  int res;
+  
+  rsa_public_key_init(&pub);
+  rsa_private_key_init(&priv);
+
+  if (rsa_keypair_from_der(&pub, &priv, 0,
+                          length, data))
+    {
+      /* Reuses the buffer */
+      nettle_buffer_reset(buffer);
+      res = rsa_keypair_to_sexp(buffer, NULL, &pub, &priv);
+    }
+  else
+    {
+      werror("Invalid PKCS#1 private key.\n");
+      res = 0;
+    }
+  rsa_public_key_clear(&pub);
+  rsa_private_key_clear(&priv);
+
+  return res;
+}
+
+static int
+convert_dsa_private_key(struct nettle_buffer *buffer, unsigned length, const uint8_t *data)
+{
+  struct dsa_public_key pub;
+  struct dsa_private_key priv;
+  int res;
+  
+  dsa_public_key_init(&pub);
+  dsa_private_key_init(&priv);
+
+  if (dsa_openssl_private_key_from_der(&pub, &priv, 0,
+                                      length, data))
+    {
+      /* Reuses the buffer */
+      nettle_buffer_reset(buffer);
+      res = dsa_keypair_to_sexp(buffer, NULL, &pub, &priv);
+    }
+  else
+    {
+      werror("Invalid OpenSSL private key.\n");
+      res = 0;
+    }
+  dsa_public_key_clear(&pub);
+  dsa_private_key_clear(&priv);
+
+  return res;
+}
+
+/* Returns 1 on success, 0 on error, and -1 for unsupported algorithms. */
+static int
+convert_public_key(struct nettle_buffer *buffer, unsigned length, const uint8_t *data)
+{
+  /* SubjectPublicKeyInfo ::= SEQUENCE {
+         algorithm             AlgorithmIdentifier,
+        subjectPublicKey       BIT STRING
+     }
+
+     AlgorithmIdentifier ::= SEQUENCE {
+         algorithm     OBJECT IDENTIFIER,
+        parameters     OPTIONAL
+     }
+  */
+  struct asn1_der_iterator i;
+  struct asn1_der_iterator j;
+  int res = 0;
+
+  if (asn1_der_iterator_first(&i, length, data) == ASN1_ITERATOR_CONSTRUCTED
+      && i.type == ASN1_SEQUENCE
+      && asn1_der_decode_constructed_last(&i) == ASN1_ITERATOR_CONSTRUCTED
+      && i.type == ASN1_SEQUENCE
+
+      /* Use the j iterator to parse the algorithm identifier */
+      && asn1_der_decode_constructed(&i, &j) == ASN1_ITERATOR_PRIMITIVE
+      && j.type == ASN1_IDENTIFIER
+      && asn1_der_iterator_next(&i) == ASN1_ITERATOR_PRIMITIVE
+      && i.type == ASN1_BITSTRING
+
+      /* Use i to parse the object wrapped in the bit string.*/
+      && asn1_der_decode_bitstring_last(&i))
+    {
+      /* pkcs-1 {
+            iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1)
+            modules(0) pkcs-1(1)
+        }
+
+        --
+        -- When rsaEncryption is used in an AlgorithmIdentifier the
+        -- parameters MUST be present and MUST be NULL.
+        --
+        rsaEncryption    OBJECT IDENTIFIER ::= { pkcs-1 1 }
+      */
+      static const uint8_t id_rsaEncryption[9] =
+       { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
+      /*
+        --
+        -- When dsa is used in an AlgorithmIdentifier the
+        -- parameters MUST be present and MUST NOT be NULL.
+        --
+        dsa    OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 }
+      */
+      static const uint8_t id_dsa[7] =
+       { 0x2A, 0x86, 0x48, 0xCE, 0x38, 0x04, 0x01 };
+
+      switch (j.length)
+       {
+       unknown:
+       default:
+         werror("SubjectPublicKeyInfo: Unsupported algorithm.\n");
+         res = -1;
+         break;
+         
+       case 7:
+         if (memcmp(j.data, id_dsa, 7) == 0)
+           {
+             if (asn1_der_iterator_next(&j) == ASN1_ITERATOR_CONSTRUCTED
+                 && asn1_der_decode_constructed_last(&j) == ASN1_ITERATOR_PRIMITIVE)
+               {
+                 struct dsa_public_key pub;
+
+                 dsa_public_key_init(&pub);
+
+                 if (dsa_params_from_der_iterator(&pub, 0, &i)
+                     && dsa_public_key_from_der_iterator(&pub, 0, &j))
+                   {
+                     nettle_buffer_reset(buffer);
+                     res = dsa_keypair_to_sexp(buffer, NULL, &pub, NULL) > 0;
+                   }
+               }
+             if (!res)
+               werror("SubjectPublicKeyInfo: Invalid DSA key.\n");
+             break;
+           }
+         else goto unknown;
+       case 9:
+         if (memcmp(j.data, id_rsaEncryption, 9) == 0)
+           {
+             if (asn1_der_iterator_next(&j) == ASN1_ITERATOR_PRIMITIVE
+                 && j.type == ASN1_NULL
+                 && j.length == 0
+                 && asn1_der_iterator_next(&j) == ASN1_ITERATOR_END)
+               {
+                 struct rsa_public_key pub;
+
+                 rsa_public_key_init(&pub);
+
+                 if (rsa_public_key_from_der_iterator(&pub, 0, &i))
+                   {
+                     nettle_buffer_reset(buffer);
+                     res = rsa_keypair_to_sexp(buffer, NULL, &pub, NULL) > 0;
+                   }
+               }
+             if (!res)
+               werror("SubjectPublicKeyInfo: Invalid RSA key.\n");
+             break;
+           }
+         else goto unknown;
+       }
+    }
+  else
+    werror("SubjectPublicKeyInfo: Invalid object.\n");
+  
+  return res;
+}
+
+/* NOTE: Destroys contents of buffer */
+/* Returns 1 on success, 0 on error, and -1 for unsupported algorithms. */
+static int
+convert_type(struct nettle_buffer *buffer,
+            enum object_type type,
+            unsigned length, const uint8_t *data)
+{
+  int res;
+  
+  switch(type)
+    {
+    default:
+      abort();
+
+    case GENERAL_PUBLIC_KEY:
+      res = convert_public_key(buffer, length, data);
+      break;
+
+    case RSA_PUBLIC_KEY:
+      res = convert_rsa_public_key(buffer, length, data);
+      break;
+
+    case RSA_PRIVATE_KEY:
+      res = convert_rsa_private_key(buffer, length, data);
+      break;
+
+    case DSA_PRIVATE_KEY:
+      res = convert_dsa_private_key(buffer, length, data);
+      break;
+    }
+
+  if (res > 0)
+    res = write_file(buffer, stdout);
+
+  return res;
+}
+
+static int
+convert_file(struct nettle_buffer *buffer,
+            FILE *f,
+            enum object_type type,
+            int base64)
+{
+  if (type)
+    {
+      read_file(buffer, f);
+      if (base64 && !decode_base64(buffer, 0, &buffer->size))
+       return 0;
+      
+      if (convert_type(buffer, type,
+                      buffer->size, buffer->contents) != 1)
+       return 0;
+
+      return 1;
+    }
+  else
+    {
+      /* PEM processing */
+      for (;;)
+       {
+         struct pem_info info;
+         const uint8_t *marker;
+         
+         nettle_buffer_reset(buffer);
+         switch (read_pem(buffer, f, &info))
+           {
+           default:
+             return 0;
+           case 1:
+             break;
+           case -1:
+             /* EOF */
+             return 1;
+           }
+
+         if (!decode_base64(buffer, info.data_start, &info.data_length))
+           return 0;
+
+         marker = buffer->contents + info.marker_start;
+
+         type = 0;
+         switch (info.marker_length)
+           {
+           case 10:
+             if (memcmp(marker, "PUBLIC KEY", 10) == 0)
+               {
+                 type = GENERAL_PUBLIC_KEY;
+                 break;
+               }
+           case 14:
+             if (memcmp(marker, "RSA PUBLIC KEY", 14) == 0)
+               {
+                 type = RSA_PUBLIC_KEY;
+                 break;
+               }
+
+           case 15:
+             if (memcmp(marker, "RSA PRIVATE KEY", 15) == 0)
+               {
+                 type = RSA_PRIVATE_KEY;
+                 break;
+               }
+             if (memcmp(marker, "DSA PRIVATE KEY", 15) == 0)
+               {
+                 type = DSA_PRIVATE_KEY;
+                 break;
+               }
+           }
+         
+         if (!type)
+           werror("Ignoring unsupported object type `%s'.\n", marker);
+
+         else if (convert_type(buffer, type,
+                               info.data_length,
+                               buffer->contents + info.data_start) != 1)
+           return 0;
+       }
+    }
+}
+
+int
+main(int argc, char **argv)
+{
+  struct nettle_buffer buffer;
+  enum object_type type = 0;
+  int base64 = 0;
+  int c;
+
+  enum {
+    OPT_HELP = 0x300,
+    OPT_PRIVATE_RSA = RSA_PRIVATE_KEY,
+    OPT_PUBLIC_RSA = RSA_PUBLIC_KEY,
+    OPT_PRIVATE_DSA = DSA_PRIVATE_KEY,
+    OPT_PUBLIC_KEY = GENERAL_PUBLIC_KEY,
+  };
+  
+  static const struct option options[] =
+    {
+      /* Name, args, flag, val */
+      { "help", no_argument, NULL, OPT_HELP },
+      { "version", no_argument, NULL, 'V' },
+      { "private-rsa-key", no_argument, NULL, OPT_PRIVATE_RSA },
+      { "public-rsa-key", no_argument, NULL, OPT_PUBLIC_RSA },
+      { "private-dsa-key", no_argument, NULL, OPT_PRIVATE_DSA },
+      { "public-key-info", no_argument, NULL, OPT_PUBLIC_KEY },
+      { "base-64", no_argument, NULL, 'b' },
+      { NULL, 0, NULL, 0 }
+    };
+
+  while ( (c = getopt_long(argc, argv, "Vb", options, NULL)) != -1)
+    {
+      switch (c)
+       {
+       default:
+         abort();
+
+       case 'b':
+         base64 = 1;
+         break;
+
+       case OPT_PRIVATE_RSA:
+       case OPT_PUBLIC_RSA:
+       case OPT_PRIVATE_DSA:
+       case OPT_PUBLIC_KEY:
+         /* Same values as the type codes. */
+         type = c;
+         break;
+
+       case OPT_HELP:
+         printf("FIXME: Usage information.\n");
+         return EXIT_SUCCESS;
+       case '?':
+         return EXIT_FAILURE;
+
+       case 'V':
+         printf("pkcs1-conv (" PACKAGE_STRING ")\n");
+         return EXIT_SUCCESS;
+       }
+    }
+
+  nettle_buffer_init_realloc(&buffer, NULL, nettle_xrealloc);  
+
+  if (optind == argc)
+    {
+      if (!convert_file(&buffer, stdin, type, base64))
+       return EXIT_FAILURE;
+    }
+  else
+    {
+      int i;
+      const char *mode = (type || base64) ? "r" : "rb";
+      
+      for (i = optind; i < argc; i++)
+       {
+         FILE *f = fopen(argv[i], mode);
+         if (!f)
+           die("Failed to open `%s': %s.\n", argv[i], strerror(errno));
+
+         if (!convert_file(&buffer, f, type, base64))
+           return EXIT_FAILURE;
+
+         fclose(f);
+       }
+    }
+  return EXIT_SUCCESS;
+}
diff --git a/tools/sexp-conv.c b/tools/sexp-conv.c
new file mode 100644 (file)
index 0000000..f43f27d
--- /dev/null
@@ -0,0 +1,432 @@
+/* sexp-conv.c
+ *
+ * Conversion tool for handling the different flavours of sexp
+ * syntax. */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_FCNTL_LOCKING
+# if HAVE_SYS_TYPES_H
+#  include <sys/types.h>
+# endif
+# if HAVE_UNISTD_H
+#  include <unistd.h>
+# endif
+# include <fcntl.h>
+#endif
+
+#include "buffer.h"
+#include "nettle-meta.h"
+
+#include "getopt.h"
+
+#include "input.h"
+#include "output.h"
+#include "parse.h"
+
+#define BUG_ADDRESS "nettle-bugs@lists.lysator.liu.se"
+
+\f
+/* Conversion functions. */
+
+/* Should be called with input->token being the first token of the
+ * expression, to be converted, and return with input->token being the
+ * last token of the expression. */
+static void
+sexp_convert_item(struct sexp_parser *parser,
+                 struct sexp_compound_token *token,
+                 struct sexp_output *output, enum sexp_mode mode_out,
+                 unsigned indent)
+{
+  if (mode_out == SEXP_TRANSPORT)
+    {
+      sexp_put_char(output, '{');
+      sexp_put_code_start(output, &nettle_base64);
+      sexp_convert_item(parser, token, output, SEXP_CANONICAL, 0);
+      sexp_put_code_end(output);
+      sexp_put_char(output, '}');
+    }
+  else switch(token->type)
+    {
+    case SEXP_LIST_END:
+      die("Unmatched end of list.\n");
+    case SEXP_EOF:
+      die("Unexpected end of file.\n");
+    case SEXP_CODING_END:
+      die("Unexpected end of coding.\n");
+
+    case SEXP_LIST_START:
+      {
+       unsigned item;
+
+       sexp_put_char(output, '(');
+  
+       for (item = 0;
+            sexp_parse(parser, token), token->type != SEXP_LIST_END;
+            item++)
+         {
+           if (mode_out == SEXP_ADVANCED)
+             {
+               /* FIXME: Adapt pretty printing to handle a big first
+                * element. */
+               switch (item)
+                 {
+                 case 0:
+                   if (token->type == SEXP_COMMENT)
+                     {
+                       indent = output->pos;
+                       /* Disable the indentation setup for next item */
+                       item++;
+                     }
+                   break;
+                   
+                 case  1:
+                   sexp_put_char(output, ' ');
+                   indent = output->pos;
+                   break;
+
+                 default:
+                   sexp_put_newline(output, indent);
+                   break;
+                 }
+             }
+
+           sexp_convert_item(parser, token, output, mode_out, indent);
+         }
+       sexp_put_char(output, ')');
+
+       break;
+      }      
+      
+    case SEXP_STRING:
+      sexp_put_string(output, mode_out, &token->string);
+      break;
+
+    case SEXP_DISPLAY:
+      sexp_put_char(output, '[');
+      sexp_put_string(output, mode_out, &token->display);
+      sexp_put_char(output, ']');
+      sexp_put_string(output, mode_out, &token->string);      
+      break;
+
+    case SEXP_COMMENT:
+      if (mode_out == SEXP_ADVANCED)
+       {
+         sexp_put_data(output, token->string.size, token->string.contents);
+         sexp_put_soft_newline(output, indent);
+       }
+      break;
+    default:
+      /* Internal error */
+      abort();
+    }
+}
+
+\f
+/* Argument parsing and main program */
+
+/* The old lsh sexp-conv program took the following options:
+ *
+ * Usage: sexp-conv [OPTION...]
+ *             Conversion: sexp-conv [options] <INPUT-SEXP >OUTPUT
+ *   or:  sexp-conv [OPTION...]
+ *             Fingerprinting: sexp-conv --raw-hash [ --hash=ALGORITHM ]
+ *             <PUBLIC-KEY
+ * Reads an s-expression on stdin, and outputs the same s-expression on stdout,
+ * possibly using a different encoding. By default, output uses the advanced
+ * encoding. 
+ * 
+ *       --hash=Algorithm       Hash algorithm (default sha1).
+ *       --once                 Process exactly one s-expression.
+ *       --raw-hash             Output the hash for the canonical representation
+ *                              of the object, in hexadecimal.
+ *       --replace=Substitution An expression `/before/after/' replaces all
+ *                              occurances of the atom `before' with `after'. The
+ *                              delimiter `/' can be any single character.
+ *       --select=Operator      Select a subexpression (e.g `caddr') for
+ *                              processing.
+ *       --spki-hash            Output an SPKI hash for the object.
+ *       --debug                Print huge amounts of debug information
+ *       --log-file=File name   Append messages to this file.
+ *   -q, --quiet                Suppress all warnings and diagnostic messages
+ *       --trace                Detailed trace
+ *   -v, --verbose              Verbose diagnostic messages
+ * 
+ *  Valid sexp-formats are transport, canonical, advanced, and international.
+ * 
+ *  Valid sexp-formats are transport, canonical, advanced, advanced-hex and
+ *  international.
+ *   -f, --output-format=format Variant of the s-expression syntax to generate.
+ *   -i, --input-format=format  Variant of the s-expression syntax to accept.
+ * 
+ *   -?, --help                 Give this help list
+ *       --usage                Give a short usage message
+ *   -V, --version              Print program version
+ */ 
+
+struct conv_options
+{
+  /* Output mode */
+  enum sexp_mode mode;
+  int prefer_hex;
+  int once;
+  int lock;
+  unsigned width;
+  const struct nettle_hash *hash;
+};
+
+enum { OPT_ONCE = 300, OPT_HASH, OPT_LOCK, OPT_HELP };
+
+static int
+match_argument(const char *given, const char *name)
+{
+  /* FIXME: Allow abbreviations */
+  return !strcmp(given, name);
+}
+
+static void
+parse_options(struct conv_options *o,
+             int argc, char **argv)
+{  
+  o->mode = SEXP_ADVANCED;
+  o->prefer_hex = 0;
+  o->once = 0;
+  o->lock = 0;
+  o->hash = NULL;
+  o->width = 72;
+  
+  for (;;)
+    {
+      static const struct nettle_hash *hashes[] =
+       { &nettle_md5, &nettle_sha1, &nettle_sha256, NULL };
+  
+      static const struct option options[] =
+       {
+         /* Name, args, flag, val */
+         { "help", no_argument, NULL, OPT_HELP },
+         { "version", no_argument, NULL, 'V' },
+         { "once", no_argument, NULL, OPT_ONCE },
+         { "syntax", required_argument, NULL, 's' },
+         { "hash", optional_argument, NULL, OPT_HASH },
+         { "raw-hash", optional_argument, NULL, OPT_HASH },
+         { "width", required_argument, NULL, 'w' },
+#if HAVE_FCNTL_LOCKING
+         { "lock", no_argument, NULL, OPT_LOCK },
+#endif
+#if 0
+         /* Not yet implemented */
+         { "replace", required_argument, NULL, OPT_REPLACE },
+         { "select", required_argument, NULL, OPT_SELECT },
+         { "spki-hash", optional_argument, NULL, OPT_SPKI_HASH },
+#endif
+         { NULL, 0, NULL, 0 }
+       };
+      int c;
+      int option_index = 0;
+      unsigned i;
+     
+      c = getopt_long(argc, argv, "Vs:w:", options, &option_index);
+
+      switch (c)
+       {
+       default:
+         abort();
+         
+       case -1:
+         if (optind != argc)
+           die("sexp-conv: Command line takes no arguments, only options.\n");
+         return;
+
+       case '?':
+         exit(EXIT_FAILURE);
+         
+       case 'w':
+         {
+           char *end;
+           int width = strtol(optarg, &end , 0);
+           if (!*optarg || *end || width < 0)
+             die("sexp-conv: Invalid width `%s'.\n", optarg);
+
+           o->width = width;
+           break;
+         }
+       case 's':
+         if (o->hash)
+           werror("sexp-conv: Combining --hash and -s usually makes no sense.\n");
+         if (match_argument(optarg, "advanced"))
+           o->mode = SEXP_ADVANCED;
+         else if (match_argument(optarg, "transport"))
+           o->mode = SEXP_TRANSPORT;
+         else if (match_argument(optarg, "canonical"))
+           o->mode = SEXP_CANONICAL;
+         else if (match_argument(optarg, "hex"))
+           {
+             o->mode = SEXP_ADVANCED;
+             o->prefer_hex = 1;
+           }
+         else
+           die("Available syntax variants: advanced, transport, canonical\n");
+         break;
+
+       case OPT_ONCE:
+         o->once = 1;
+         break;
+       
+       case OPT_HASH:
+         o->mode = SEXP_CANONICAL;
+         if (!optarg)
+           o->hash = &nettle_sha1;
+         else
+           for (i = 0;; i++)
+             {
+               if (!hashes[i])
+                 die("sexp_conv: Unknown hash algorithm `%s'\n",
+                     optarg);
+             
+               if (match_argument(optarg, hashes[i]->name))
+                 {
+                   o->hash = hashes[i];
+                   break;
+                 }
+             }
+         break;
+#if HAVE_FCNTL_LOCKING
+       case OPT_LOCK:
+         o->lock = 1;
+         break;
+#endif
+       case OPT_HELP:
+         printf("Usage: sexp-conv [OPTION...]\n"
+                "  Conversion:     sexp-conv [OPTION...] <INPUT-SEXP\n"
+                "  Fingerprinting: sexp-conv --hash=HASH <INPUT-SEXP\n\n"
+                "Reads an s-expression on stdin, and outputs the same\n"
+                "sexp on stdout, possibly with a different syntax.\n\n"
+                "       --hash[=ALGORITHM]   Outputs only the hash of the expression.\n"
+                "                            Available hash algorithms:\n"
+                "                            ");
+         for(i = 0; hashes[i]; i++)
+           {
+             if (i) printf(", ");
+             printf("%s", hashes[i]->name);
+           }
+         printf(" (default is sha1).\n"
+                "   -s, --syntax=SYNTAX      The syntax used for the output. Available\n"
+                "                            variants: advanced, hex, transport, canonical\n"
+                "       --once               Process only the first s-expression.\n"
+                "   -w, --width=WIDTH        Linewidth for base64 encoded data.\n"
+                "                            Zero means no limit.\n"
+#if HAVE_FCNTL_LOCKING
+                "       --lock               Lock output file.\n"
+#endif
+                "       --raw-hash           Alias for --hash, for compatibility\n"
+                "                            with lsh-1.x.\n\n"
+                "Report bugs to " BUG_ADDRESS ".\n");
+         exit(EXIT_SUCCESS);
+
+       case 'V':
+         printf("sexp-conv (" PACKAGE_STRING ")\n");
+         exit (EXIT_SUCCESS);
+       }
+    }
+}
+
+int
+main(int argc, char **argv)
+{
+  struct conv_options options;
+  struct sexp_input input;
+  struct sexp_parser parser;
+  struct sexp_compound_token token;
+  struct sexp_output output;
+
+  parse_options(&options, argc, argv);
+
+  sexp_input_init(&input, stdin);
+  sexp_parse_init(&parser, &input, SEXP_ADVANCED);
+  sexp_compound_token_init(&token);
+  sexp_output_init(&output, stdout,
+                  options.width, options.prefer_hex);
+
+#if HAVE_FCNTL_LOCKING
+  if (options.lock)
+    {
+      struct flock fl;
+  
+      memset(&fl, 0, sizeof(fl));
+      fl.l_type = F_WRLCK;
+      fl.l_whence = SEEK_SET;
+      fl.l_start = 0;
+      fl.l_len = 0; /* Means entire file. */
+      
+      if (fcntl(STDOUT_FILENO, F_SETLKW, &fl) == -1)
+       die("Locking output file failed: %s\n", strerror(errno));
+    }
+#endif /* HAVE_FCNTL_LOCKING */
+  if (options.hash)
+    {
+      /* Leaks the context, but that doesn't matter */
+      void *ctx = xalloc(options.hash->context_size);
+      sexp_output_hash_init(&output, options.hash, ctx);
+    }
+  
+  sexp_get_char(&input);
+  
+  sexp_parse(&parser, &token);
+  
+  if (token.type == SEXP_EOF)
+    {
+      if (options.once)
+       die("sexp-conv: No input expression.\n");
+      return EXIT_SUCCESS;
+    }
+  
+  do 
+    {
+      sexp_convert_item(&parser, &token, &output, options.mode, 0);
+      if (options.hash)
+       {
+         sexp_put_digest(&output);
+         sexp_put_newline(&output, 0);
+       }
+      else if (options.mode != SEXP_CANONICAL)
+       sexp_put_newline(&output, 0);
+         
+      sexp_parse(&parser, &token);
+    }
+  while (!options.once && token.type != SEXP_EOF);
+
+  sexp_compound_token_clear(&token);
+  
+  if (fflush(output.f) < 0)
+    die("Final fflush failed: %s.\n", strerror(errno));
+  
+  return EXIT_SUCCESS;
+}
diff --git a/twofish-meta.c b/twofish-meta.c
new file mode 100644 (file)
index 0000000..7e46325
--- /dev/null
@@ -0,0 +1,38 @@
+/* twofish-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "twofish.h"
+
+const struct nettle_cipher nettle_twofish128
+= _NETTLE_CIPHER(twofish, TWOFISH, 128);
+
+const struct nettle_cipher nettle_twofish192
+= _NETTLE_CIPHER(twofish, TWOFISH, 192);
+
+const struct nettle_cipher nettle_twofish256
+= _NETTLE_CIPHER(twofish, TWOFISH, 256);
diff --git a/twofish.c b/twofish.c
new file mode 100644 (file)
index 0000000..0e519ea
--- /dev/null
+++ b/twofish.c
@@ -0,0 +1,464 @@
+/* twofish.c
+ *
+ * The twofish block cipher.
+ */
+
+/* twofish - An implementation of the twofish cipher.
+ * Copyright (C) 1999 Ruud de Rooij <ruud@debian.org>
+ *
+ * Modifications for lsh, integrated testing
+ * Copyright (C) 1999 J.H.M. Dassen (Ray) <jdassen@wi.LeidenUniv.nl>
+ *
+ * Integrated with the nettle library,
+ * Copyright (C) 2001 Niels Möller
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <string.h>
+
+#include "twofish.h"
+
+#include "macros.h"
+
+/* Bitwise rotations on 32-bit words.  These are defined as macros that
+ * evaluate their argument twice, so do not apply to any expressions with
+ * side effects.
+ */
+
+#define rol1(x) (((x) << 1) | (((x) & 0x80000000) >> 31))
+#define rol8(x) (((x) << 8) | (((x) & 0xFF000000) >> 24))
+#define rol9(x) (((x) << 9) | (((x) & 0xFF800000) >> 23))
+#define ror1(x) (((x) >> 1) | (((x) & 0x00000001) << 31))
+
+/* ------------------------------------------------------------------------- */
+
+/* The permutations q0 and q1.  These are fixed permutations on 8-bit values.
+ * The permutations have been computed using the program generate_q
+ * which is distributed along with this file.
+ */
+
+static const uint8_t q0[] = { 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76,
+                     0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38,
+                     0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
+                     0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48,
+                     0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23,
+                     0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
+                     0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C,
+                     0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61,
+                     0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
+                     0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1,
+                     0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66,
+                     0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
+                     0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA,
+                     0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71,
+                     0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
+                     0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7,
+                     0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2,
+                     0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
+                     0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB,
+                     0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF,
+                     0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
+                     0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64,
+                     0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A,
+                     0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
+                     0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02,
+                     0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D,
+                     0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
+                     0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34,
+                     0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8,
+                     0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
+                     0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00,
+                     0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0, };
+
+static const uint8_t q1[] = { 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8,
+                     0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B,
+                     0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
+                     0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F,
+                     0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D,
+                     0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
+                     0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3,
+                     0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51,
+                     0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
+                     0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C,
+                     0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70,
+                     0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
+                     0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC,
+                     0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2,
+                     0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
+                     0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17,
+                     0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3,
+                     0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
+                     0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49,
+                     0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9,
+                     0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
+                     0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48,
+                     0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19,
+                     0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
+                     0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5,
+                     0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69,
+                     0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
+                     0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC,
+                     0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB,
+                     0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
+                     0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2,
+                     0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91, };
+
+/* ------------------------------------------------------------------------- */
+
+/* uint8_t gf_multiply(uint8_t p, uint8_t a, uint8_t b)
+ *
+ * Multiplication in GF(2^8).
+ *
+ * This function multiplies a times b in the Galois Field GF(2^8) with
+ * primitive polynomial p.
+ * The representation of the polynomials a, b, and p uses bits with
+ * values 2^i to represent the terms x^i.  The polynomial p contains an
+ * implicit term x^8.
+ *
+ * Note that addition and subtraction in GF(2^8) is simply the XOR
+ * operation.
+ */
+
+static uint8_t
+gf_multiply(uint8_t p, uint8_t a, uint8_t b)
+{
+  uint32_t shift  = b;
+  uint8_t result = 0;
+  while (a)
+    {
+      if (a & 1) result ^= shift;
+      a = a >> 1;
+      shift = shift << 1;
+      if (shift & 0x100) shift ^= p;
+    }
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* The matrix RS as specified in section 4.3 the twofish paper. */
+
+static const uint8_t rs_matrix[4][8] = {
+    { 0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E },
+    { 0xA4, 0x56, 0x82, 0xF3, 0x1E, 0xC6, 0x68, 0xE5 },
+    { 0x02, 0xA1, 0xFC, 0xC1, 0x47, 0xAE, 0x3D, 0x19 },
+    { 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E, 0x03 } };
+
+/* uint32_t compute_s(uint32_t m1, uint32_t m2);
+ *
+ * Computes the value RS * M, where M is a byte vector composed of the
+ * bytes of m1 and m2.  Arithmetic is done in GF(2^8) with primitive
+ * polynomial x^8 + x^6 + x^3 + x^2 + 1.
+ *
+ * This function is used to compute the sub-keys S which are in turn used
+ * to generate the S-boxes.
+ */
+
+static uint32_t
+compute_s(uint32_t m1, uint32_t m2)
+{
+  uint32_t s = 0;
+  int i;
+  for (i = 0; i < 4; i++)
+    s |=  ((  gf_multiply(0x4D, m1,       rs_matrix[i][0])
+           ^ gf_multiply(0x4D, m1 >> 8,  rs_matrix[i][1])
+           ^ gf_multiply(0x4D, m1 >> 16, rs_matrix[i][2])
+           ^ gf_multiply(0x4D, m1 >> 24, rs_matrix[i][3])
+           ^ gf_multiply(0x4D, m2,       rs_matrix[i][4])
+           ^ gf_multiply(0x4D, m2 >> 8,  rs_matrix[i][5])
+           ^ gf_multiply(0x4D, m2 >> 16, rs_matrix[i][6])
+           ^ gf_multiply(0x4D, m2 >> 24, rs_matrix[i][7])) << (i*8));
+  return s;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* This table describes which q S-boxes are used for each byte in each stage
+ * of the function h, cf. figure 2 of the twofish paper.
+ */
+
+static const uint8_t * const q_table[4][5] =
+  { { q1, q1, q0, q0, q1 },
+    { q0, q1, q1, q0, q0 },
+    { q0, q0, q0, q1, q1 },
+    { q1, q0, q1, q1, q0 } };
+
+/* The matrix MDS as specified in section 4.3.2 of the twofish paper. */
+
+static const uint8_t mds_matrix[4][4] = { { 0x01, 0xEF, 0x5B, 0x5B },
+                                { 0x5B, 0xEF, 0xEF, 0x01 },
+                                { 0xEF, 0x5B, 0x01, 0xEF },
+                                { 0xEF, 0x01, 0xEF, 0x5B } };
+
+/* uint32_t h_uint8_t(int k, int i, uint8_t x, uint8_t l0, uint8_t l1, uint8_t l2, uint8_t l3);
+ *
+ * Perform the h function (section 4.3.2) on one byte.  It consists of
+ * repeated applications of the q permutation, followed by a XOR with
+ * part of a sub-key.  Finally, the value is multiplied by one column of
+ * the MDS matrix.  To obtain the result for a full word, the results of
+ * h for the individual bytes are XORed.
+ *
+ * k is the key size (/ 64 bits), i is the byte number (0 = LSB), x is the
+ * actual byte to apply the function to; l0, l1, l2, and l3 are the
+ * appropriate bytes from the subkey.  Note that only l0..l(k-1) are used.
+ */
+
+static uint32_t
+h_byte(int k, int i, uint8_t x, uint8_t l0, uint8_t l1, uint8_t l2, uint8_t l3)
+{
+  uint8_t y = q_table[i][4][l0 ^
+            q_table[i][3][l1 ^
+              q_table[i][2][k == 2 ? x : l2 ^
+                q_table[i][1][k == 3 ? x : l3 ^ q_table[i][0][x]]]]];
+
+  return ( ((uint32_t)gf_multiply(0x69, mds_matrix[0][i], y))
+          | ((uint32_t)gf_multiply(0x69, mds_matrix[1][i], y) << 8)
+          | ((uint32_t)gf_multiply(0x69, mds_matrix[2][i], y) << 16)
+          | ((uint32_t)gf_multiply(0x69, mds_matrix[3][i], y) << 24) );
+}
+
+/* uint32_t h(int k, uint8_t x, uint32_t l0, uint32_t l1, uint32_t l2, uint32_t l3);
+ *
+ * Perform the function h on a word.  See the description of h_byte() above.
+ */
+
+static uint32_t
+h(int k, uint8_t x, uint32_t l0, uint32_t l1, uint32_t l2, uint32_t l3)
+{
+  return (  h_byte(k, 0, x, l0,       l1,       l2,       l3)
+         ^ h_byte(k, 1, x, l0 >> 8,  l1 >> 8,  l2 >> 8,  l3 >> 8)
+         ^ h_byte(k, 2, x, l0 >> 16, l1 >> 16, l2 >> 16, l3 >> 16)
+         ^ h_byte(k, 3, x, l0 >> 24, l1 >> 24, l2 >> 24, l3 >> 24) );
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+/* API */
+
+/* Structure which contains the tables containing the subkeys and the
+ * key-dependent s-boxes.
+ */
+
+
+/* Set up internal tables required for twofish encryption and decryption.
+ *
+ * The key size is specified in bytes.  Key sizes up to 32 bytes are
+ * supported.  Larger key sizes are silently truncated.  
+ */
+
+void
+twofish_set_key(struct twofish_ctx *context,
+               unsigned keysize, const uint8_t *key)
+{
+  uint8_t key_copy[32];
+  uint32_t m[8], s[4], t;
+  int i, j, k;
+
+  /* Extend key as necessary */
+
+  assert(keysize <= 32);
+
+  /* We do a little more copying than necessary, but that doesn't
+   * really matter. */
+  memset(key_copy, 0, 32);
+  memcpy(key_copy, key, keysize);
+
+  for (i = 0; i<8; i++)
+    m[i] = LE_READ_UINT32(key_copy + i*4);
+  
+  if (keysize <= 16)
+    k = 2;
+  else if (keysize <= 24)
+    k = 3;
+  else
+    k = 4;
+
+  /* Compute sub-keys */
+
+  for (i = 0; i < 20; i++)
+    {
+      t = h(k, 2*i+1, m[1], m[3], m[5], m[7]);
+      t = rol8(t);
+      t += (context->keys[2*i] =
+           t + h(k, 2*i, m[0], m[2], m[4], m[6]));
+      t = rol9(t);
+      context->keys[2*i+1] = t;
+    }
+
+  /* Compute key-dependent S-boxes */
+
+  for (i = 0; i < k; i++)
+    s[k-1-i] = compute_s(m[2*i], m[2*i+1]);
+
+  for (i = 0; i < 4; i++)
+    for (j = 0; j < 256; j++)
+      context->s_box[i][j] = h_byte(k, i, j,
+                                   s[0] >> (i*8),
+                                   s[1] >> (i*8),
+                                   s[2] >> (i*8),
+                                   s[3] >> (i*8));
+}
+
+/* Encrypt blocks of 16 bytes of data with the twofish algorithm.
+ *
+ * Before this function can be used, twofish_set_key() must be used in order to
+ * set up various tables required for the encryption algorithm.
+ * 
+ * This function always encrypts 16 bytes of plaintext to 16 bytes of
+ * ciphertext.  The memory areas of the plaintext and the ciphertext can
+ * overlap.
+ */
+
+void
+twofish_encrypt(const struct twofish_ctx *context,
+               unsigned length,
+               uint8_t *ciphertext,
+               const uint8_t *plaintext)
+{
+  const uint32_t * keys        = context->keys;
+  const uint32_t (*s_box)[256] = context->s_box;
+
+  assert( !(length % TWOFISH_BLOCK_SIZE) );
+  for ( ; length; length -= TWOFISH_BLOCK_SIZE)
+    {  
+      uint32_t words[4];
+      uint32_t r0, r1, r2, r3, t0, t1;
+      int i;
+
+      for (i = 0; i<4; i++, plaintext += 4)
+       words[i] = LE_READ_UINT32(plaintext);
+
+      r0 = words[0] ^ keys[0];
+      r1 = words[1] ^ keys[1];
+      r2 = words[2] ^ keys[2];
+      r3 = words[3] ^ keys[3];
+  
+      for (i = 0; i < 8; i++) {
+       t1 = (  s_box[1][r1 & 0xFF]
+               ^ s_box[2][(r1 >> 8) & 0xFF]
+               ^ s_box[3][(r1 >> 16) & 0xFF]
+               ^ s_box[0][(r1 >> 24) & 0xFF]);
+       t0 = (  s_box[0][r0 & 0xFF]
+               ^ s_box[1][(r0 >> 8) & 0xFF]
+               ^ s_box[2][(r0 >> 16) & 0xFF]
+               ^ s_box[3][(r0 >> 24) & 0xFF]) + t1;
+       r3 = (t1 + t0 + keys[4*i+9]) ^ rol1(r3);
+       r2 = (t0 + keys[4*i+8]) ^ r2;
+       r2 = ror1(r2);
+
+       t1 = (  s_box[1][r3 & 0xFF]
+               ^ s_box[2][(r3 >> 8) & 0xFF]
+               ^ s_box[3][(r3 >> 16) & 0xFF]
+               ^ s_box[0][(r3 >> 24) & 0xFF]);
+       t0 = (  s_box[0][r2 & 0xFF]
+               ^ s_box[1][(r2 >> 8) & 0xFF]
+               ^ s_box[2][(r2 >> 16) & 0xFF]
+               ^ s_box[3][(r2 >> 24) & 0xFF]) + t1;
+       r1 = (t1 + t0 + keys[4*i+11]) ^ rol1(r1);
+       r0 = (t0 + keys[4*i+10]) ^ r0;
+       r0 = ror1(r0);
+      }
+
+      words[0] = r2 ^ keys[4];
+      words[1] = r3 ^ keys[5];
+      words[2] = r0 ^ keys[6];
+      words[3] = r1 ^ keys[7];
+
+      for (i = 0; i<4; i++, ciphertext += 4)
+       LE_WRITE_UINT32(ciphertext, words[i]);
+    }
+}
+
+/* Decrypt blocks of 16 bytes of data with the twofish algorithm.
+ *
+ * Before this function can be used, twofish_set_key() must be used in order to
+ * set up various tables required for the decryption algorithm.
+ * 
+ * This function always decrypts 16 bytes of ciphertext to 16 bytes of
+ * plaintext.  The memory areas of the plaintext and the ciphertext can
+ * overlap.
+ */
+
+void
+twofish_decrypt(const struct twofish_ctx *context,
+               unsigned length,
+               uint8_t *plaintext,
+               const uint8_t *ciphertext)
+
+{
+  const uint32_t *keys  = context->keys;
+  const uint32_t (*s_box)[256] = context->s_box;
+
+  assert( !(length % TWOFISH_BLOCK_SIZE) );
+  for ( ; length; length -= TWOFISH_BLOCK_SIZE)
+    {  
+      uint32_t words[4];
+      uint32_t r0, r1, r2, r3, t0, t1;
+      int i;
+
+      for (i = 0; i<4; i++, ciphertext += 4)
+       words[i] = LE_READ_UINT32(ciphertext);
+
+      r0 = words[2] ^ keys[6];
+      r1 = words[3] ^ keys[7];
+      r2 = words[0] ^ keys[4];
+      r3 = words[1] ^ keys[5];
+
+      for (i = 0; i < 8; i++) {
+       t1 = (  s_box[1][r3 & 0xFF]
+               ^ s_box[2][(r3 >> 8) & 0xFF]
+               ^ s_box[3][(r3 >> 16) & 0xFF]
+               ^ s_box[0][(r3 >> 24) & 0xFF]);
+       t0 = (  s_box[0][r2 & 0xFF]
+               ^ s_box[1][(r2 >> 8) & 0xFF]
+               ^ s_box[2][(r2 >> 16) & 0xFF]
+               ^ s_box[3][(r2 >> 24) & 0xFF]) + t1;
+       r1 = (t1 + t0 + keys[39-4*i]) ^ r1;
+       r1 = ror1(r1);
+       r0 = (t0 + keys[38-4*i]) ^ rol1(r0);
+
+       t1 = (  s_box[1][r1 & 0xFF]
+               ^ s_box[2][(r1 >> 8) & 0xFF]
+               ^ s_box[3][(r1 >> 16) & 0xFF]
+               ^ s_box[0][(r1 >> 24) & 0xFF]);
+       t0 = (  s_box[0][r0 & 0xFF]
+               ^ s_box[1][(r0 >> 8) & 0xFF]
+               ^ s_box[2][(r0 >> 16) & 0xFF]
+               ^ s_box[3][(r0 >> 24) & 0xFF]) + t1;
+       r3 = (t1 + t0 + keys[37-4*i]) ^ r3;
+       r3 = ror1(r3);
+       r2 = (t0 + keys[36-4*i]) ^ rol1(r2);
+      }
+
+      words[0] = r0 ^ keys[0];
+      words[1] = r1 ^ keys[1];
+      words[2] = r2 ^ keys[2];
+      words[3] = r3 ^ keys[3];
+
+      for (i = 0; i<4; i++, plaintext += 4)
+       LE_WRITE_UINT32(plaintext, words[i]);
+    }
+}
diff --git a/twofish.h b/twofish.h
new file mode 100644 (file)
index 0000000..de5dc3c
--- /dev/null
+++ b/twofish.h
@@ -0,0 +1,78 @@
+/* twofish.h
+ *
+ * The twofish block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/*
+ * Twofish is a 128-bit block cipher that accepts a variable-length
+ * key up to 256 bits, designed by Bruce Schneier and others.  See
+ * http://www.counterpane.com/twofish.html for details.
+ */
+
+#ifndef NETTLE_TWOFISH_H_INCLUDED
+#define NETTLE_TWOFISH_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define twofish_set_key nettle_twofish_set_key
+#define twofish_encrypt nettle_twofish_encrypt
+#define twofish_decrypt nettle_twofish_decrypt
+
+#define TWOFISH_BLOCK_SIZE 16
+
+/* Variable key size between 128 and 256 bits. But the only valid
+ * values are 16 (128 bits), 24 (192 bits) and 32 (256 bits). */
+#define TWOFISH_MIN_KEY_SIZE 16
+#define TWOFISH_MAX_KEY_SIZE 32
+
+#define TWOFISH_KEY_SIZE 32
+
+struct twofish_ctx
+{
+  uint32_t keys[40];
+  uint32_t s_box[4][256];
+};
+
+void
+twofish_set_key(struct twofish_ctx *ctx,
+               unsigned length, const uint8_t *key);
+
+void
+twofish_encrypt(const struct twofish_ctx *ctx,
+               unsigned length, uint8_t *dst,
+               const uint8_t *src);
+void
+twofish_decrypt(const struct twofish_ctx *ctx,
+               unsigned length, uint8_t *dst,
+               const uint8_t *src);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_TWOFISH_H_INCLUDED */
diff --git a/write-be32.c b/write-be32.c
new file mode 100644 (file)
index 0000000..e52e565
--- /dev/null
@@ -0,0 +1,68 @@
+/* write-be32.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+
+#include "nettle-write.h"
+
+#include "macros.h"
+
+void
+_nettle_write_be32(unsigned length, uint8_t *dst,
+                  uint32_t *src)
+{
+  unsigned i;
+  unsigned words;
+  unsigned leftover;
+  
+  words = length / 4;
+  leftover = length % 4;
+
+  for (i = 0; i < words; i++, dst += 4)
+    WRITE_UINT32(dst, src[i]);
+
+  if (leftover)
+    {
+      uint32_t word;
+      unsigned j = leftover;
+      
+      word = src[i];
+      
+      switch (leftover)
+       {
+       default:
+         abort();
+       case 3:
+         dst[--j] = (word >> 8) & 0xff;
+         /* Fall through */
+       case 2:
+         dst[--j] = (word >> 16) & 0xff;
+         /* Fall through */
+       case 1:
+         dst[--j] = (word >> 24) & 0xff;
+       }
+    }
+}
diff --git a/write-le32.c b/write-le32.c
new file mode 100644 (file)
index 0000000..6b9391b
--- /dev/null
@@ -0,0 +1,60 @@
+/* write-le32.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001, 2011 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+
+#include "nettle-write.h"
+
+#include "macros.h"
+
+void
+_nettle_write_le32(unsigned length, uint8_t *dst,
+                  uint32_t *src)
+{
+  unsigned i;
+  unsigned words;
+  unsigned leftover;
+  
+  words = length / 4;
+  leftover = length % 4;
+
+  for (i = 0; i < words; i++, dst += 4)
+    LE_WRITE_UINT32(dst, src[i]);
+
+  if (leftover)
+    {
+      uint32_t word;
+      
+      word = src[i];
+
+      do
+       {
+         *dst++ = word & 0xff;
+         word >>= 8;
+       }
+      while (--leftover);
+    }
+}
diff --git a/x86/aes-decrypt-internal.asm b/x86/aes-decrypt-internal.asm
new file mode 100644 (file)
index 0000000..0dc6f7b
--- /dev/null
@@ -0,0 +1,166 @@
+C -*- mode: asm; asm-comment-char: ?C; -*-  
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2001, 2002, 2005 Rafael R. Sevilla, Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+include_src(<x86/aes.m4>)
+
+C Register usage:
+
+C AES state
+define(<SA>,<%eax>)
+define(<SB>,<%ebx>)
+define(<SC>,<%ecx>)
+define(<SD>,<%edx>)
+
+C Primary use of these registers. They're also used temporarily for other things.
+define(<T>,<%ebp>)
+define(<TMP>,<%edi>)
+define(<KEY>,<%esi>)
+
+define(<FRAME_CTX>,    <40(%esp)>)
+define(<FRAME_TABLE>,  <44(%esp)>)
+define(<FRAME_LENGTH>, <48(%esp)>)
+define(<FRAME_DST>,    <52(%esp)>)
+define(<FRAME_SRC>,    <56(%esp)>)
+
+define(<FRAME_KEY>,    <16(%esp)>)
+define(<FRAME_COUNT>,  <12(%esp)>)
+define(<TA>,           <8(%esp)>)
+define(<TB>,           <4(%esp)>)
+define(<TC>,           <(%esp)>)
+
+C The aes state is kept in %eax, %ebx, %ecx and %edx
+C
+C %esi is used as temporary, to point to the input, and to the
+C subkeys, etc.
+C
+C %ebp is used as the round counter, and as a temporary in the final round.
+C
+C %edi is a temporary, often used as an accumulator.
+
+       .file "aes-decrypt-internal.asm"
+       
+       C _aes_decrypt(struct aes_context *ctx, 
+       C              const struct aes_table *T,
+       C              unsigned length, uint8_t *dst,
+       C              uint8_t *src)
+       .text
+       ALIGN(4)
+PROLOGUE(_nettle_aes_decrypt)
+       C save all registers that need to be saved
+       pushl   %ebx            C  20(%esp)
+       pushl   %ebp            C  16(%esp)
+       pushl   %esi            C  12(%esp)
+       pushl   %edi            C  8(%esp)
+
+       subl    $20, %esp       C  loop counter and save area for the key pointer
+
+       movl    FRAME_LENGTH, %ebp
+       testl   %ebp,%ebp
+       jz      .Lend
+
+       shrl    $4, FRAME_LENGTH
+
+.Lblock_loop:
+       movl    FRAME_CTX,KEY   C  address of context struct ctx
+       
+       movl    FRAME_SRC,TMP   C  address of plaintext
+       AES_LOAD(SA, SB, SC, SD, TMP, KEY)
+       addl    $16, FRAME_SRC  C Increment src pointer
+       movl    FRAME_TABLE, T
+
+       C  get number of rounds to do from ctx struct   
+       movl    AES_NROUNDS (KEY),TMP
+       subl    $1,TMP
+
+       C Loop counter on stack
+       movl    TMP, FRAME_COUNT
+
+       addl    $16,KEY         C  point to next key
+       movl    KEY,FRAME_KEY
+       ALIGN(4)
+.Lround_loop:
+       AES_ROUND(T, SA,SD,SC,SB, TMP, KEY)
+       movl    TMP, TA
+
+       AES_ROUND(T, SB,SA,SD,SC, TMP, KEY)
+       movl    TMP, TB
+
+       AES_ROUND(T, SC,SB,SA,SD, TMP, KEY)
+       movl    TMP, TC
+
+       AES_ROUND(T, SD,SC,SB,SA, SD, KEY)
+       
+       movl    TA, SA
+       movl    TB, SB
+       movl    TC, SC
+       
+       movl    FRAME_KEY, KEY
+
+       xorl    (KEY),SA        C  add current session key to plaintext
+       xorl    4(KEY),SB
+       xorl    8(KEY),SC
+       xorl    12(KEY),SD
+       addl    $16,FRAME_KEY   C  point to next key
+       decl    FRAME_COUNT
+       jnz     .Lround_loop
+
+       C last round
+
+       AES_FINAL_ROUND(SA,SD,SC,SB,T, TMP, KEY)
+       movl    TMP, TA
+
+       AES_FINAL_ROUND(SB,SA,SD,SC,T, TMP, KEY)
+       movl    TMP, TB
+
+       AES_FINAL_ROUND(SC,SB,SA,SD,T, TMP, KEY)
+       movl    TMP, TC
+
+       AES_FINAL_ROUND(SD,SC,SB,SA,T, SD, KEY)
+
+       movl    TA, SA
+       movl    TB, SB
+       movl    TC, SC
+
+       C Inverse S-box substitution
+       mov     $3,TMP
+.Lsubst:
+       AES_SUBST_BYTE(SA,SB,SC,SD,T, KEY)
+
+       decl    TMP
+       jnz     .Lsubst
+
+       C Add last subkey, and store decrypted data
+       movl    FRAME_DST,TMP
+       movl    FRAME_KEY, KEY
+       AES_STORE(SA,SB,SC,SD, KEY, TMP)
+       
+       addl    $16, FRAME_DST          C Increment destination pointer
+       decl    FRAME_LENGTH
+
+       jnz     .Lblock_loop
+
+.Lend:
+       addl    $20, %esp
+       popl    %edi
+       popl    %esi
+       popl    %ebp
+       popl    %ebx
+       ret
+EPILOGUE(_nettle_aes_decrypt)
diff --git a/x86/aes-encrypt-internal.asm b/x86/aes-encrypt-internal.asm
new file mode 100644 (file)
index 0000000..99620d4
--- /dev/null
@@ -0,0 +1,166 @@
+C -*- mode: asm; asm-comment-char: ?C; -*-  
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2001, 2002, 2005 Rafael R. Sevilla, Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+include_src(<x86/aes.m4>)
+
+C Register usage:
+
+C AES state
+define(<SA>,<%eax>)
+define(<SB>,<%ebx>)
+define(<SC>,<%ecx>)
+define(<SD>,<%edx>)
+
+C Primary use of these registers. They're also used temporarily for other things.
+define(<T>,<%ebp>)
+define(<TMP>,<%edi>)
+define(<KEY>,<%esi>)
+
+define(<FRAME_CTX>,    <40(%esp)>)
+define(<FRAME_TABLE>,  <44(%esp)>)
+define(<FRAME_LENGTH>, <48(%esp)>)
+define(<FRAME_DST>,    <52(%esp)>)
+define(<FRAME_SRC>,    <56(%esp)>)
+
+define(<FRAME_KEY>,    <16(%esp)>)
+define(<FRAME_COUNT>,  <12(%esp)>)
+define(<TA>,           <8(%esp)>)
+define(<TB>,           <4(%esp)>)
+define(<TC>,           <(%esp)>)
+
+C The aes state is kept in %eax, %ebx, %ecx and %edx
+C
+C %esi is used as temporary, to point to the input, and to the
+C subkeys, etc.
+C
+C %ebp is used as the round counter, and as a temporary in the final round.
+C
+C %edi is a temporary, often used as an accumulator.
+
+       .file "aes-encrypt-internal.asm"
+       
+       C _aes_encrypt(struct aes_context *ctx, 
+       C              const struct aes_table *T,
+       C              unsigned length, uint8_t *dst,
+       C              uint8_t *src)
+       .text
+       ALIGN(4)
+PROLOGUE(_nettle_aes_encrypt)
+       C save all registers that need to be saved
+       pushl   %ebx            C  20(%esp)
+       pushl   %ebp            C  16(%esp)
+       pushl   %esi            C  12(%esp)
+       pushl   %edi            C  8(%esp)
+
+       subl    $20, %esp       C  loop counter and save area for the key pointer
+
+       movl    FRAME_LENGTH, %ebp
+       testl   %ebp,%ebp
+       jz      .Lend
+
+       shrl    $4, FRAME_LENGTH
+
+.Lblock_loop:
+       movl    FRAME_CTX,KEY   C  address of context struct ctx
+       
+       movl    FRAME_SRC,TMP   C  address of plaintext
+       AES_LOAD(SA, SB, SC, SD, TMP, KEY)
+       addl    $16, FRAME_SRC  C Increment src pointer
+       movl    FRAME_TABLE, T
+
+       C  get number of rounds to do from ctx struct   
+       movl    AES_NROUNDS (KEY),TMP
+       subl    $1,TMP
+
+       C Loop counter on stack
+       movl    TMP, FRAME_COUNT
+
+       addl    $16,KEY         C  point to next key
+       movl    KEY,FRAME_KEY
+       ALIGN(4)
+.Lround_loop:
+       AES_ROUND(T, SA,SB,SC,SD, TMP, KEY)
+       movl    TMP, TA
+
+       AES_ROUND(T, SB,SC,SD,SA, TMP, KEY)
+       movl    TMP, TB
+
+       AES_ROUND(T, SC,SD,SA,SB, TMP, KEY)
+       movl    TMP, TC
+
+       AES_ROUND(T, SD,SA,SB,SC, SD, KEY)
+       
+       movl    TA, SA
+       movl    TB, SB
+       movl    TC, SC
+       
+       movl    FRAME_KEY, KEY
+
+       xorl    (KEY),SA        C  add current session key to plaintext
+       xorl    4(KEY),SB
+       xorl    8(KEY),SC
+       xorl    12(KEY),SD
+       addl    $16,FRAME_KEY   C  point to next key
+       decl    FRAME_COUNT
+       jnz     .Lround_loop
+
+       C last round
+
+       AES_FINAL_ROUND(SA,SB,SC,SD, T, TMP, KEY)
+       movl    TMP, TA
+
+       AES_FINAL_ROUND(SB,SC,SD,SA, T, TMP, KEY)
+       movl    TMP, TB
+
+       AES_FINAL_ROUND(SC,SD,SA,SB, T, TMP, KEY)
+       movl    TMP, TC
+
+       AES_FINAL_ROUND(SD,SA,SB,SC, T, SD, KEY)
+
+       movl    TA, SA
+       movl    TB, SB
+       movl    TC, SC
+
+       C S-box substitution
+       mov     $3,TMP
+.Lsubst:
+       AES_SUBST_BYTE(SA,SB,SC,SD, T, KEY)
+
+       decl    TMP
+       jnz     .Lsubst
+
+       C Add last subkey, and store encrypted data
+       movl    FRAME_DST,TMP
+       movl    FRAME_KEY, KEY
+       AES_STORE(SA,SB,SC,SD, KEY, TMP)
+       
+       addl    $16, FRAME_DST          C Increment destination pointer
+       decl    FRAME_LENGTH
+
+       jnz     .Lblock_loop
+
+.Lend:
+       addl    $20, %esp
+       popl    %edi
+       popl    %esi
+       popl    %ebp
+       popl    %ebx
+       ret
+EPILOGUE(_nettle_aes_encrypt)
diff --git a/x86/aes.m4 b/x86/aes.m4
new file mode 100644 (file)
index 0000000..3507e85
--- /dev/null
@@ -0,0 +1,85 @@
+dnl AES_LOAD(a, b, c, d, src, key)
+dnl Loads the next block of data from src, and add the subkey pointed
+dnl to by key.
+dnl Note that x86 allows unaligned accesses.
+dnl Would it be preferable to interleave the loads and stores?
+define(<AES_LOAD>, <
+       movl    ($5),$1
+       movl    4($5),$2
+       movl    8($5),$3
+       movl    12($5),$4
+       
+       xorl    ($6),$1
+       xorl    4($6),$2
+       xorl    8($6),$3
+       xorl    12($6),$4>)dnl
+
+dnl AES_STORE(a, b, c, d, key, dst)
+dnl Adds the subkey to a, b, c, d,
+dnl and stores the result in the area pointed to by dst.
+dnl Note that x86 allows unaligned accesses.
+dnl Would it be preferable to interleave the loads and stores?
+define(<AES_STORE>, <
+       xorl    ($5),$1
+       xorl    4($5),$2
+       xorl    8($5),$3
+       xorl    12($5),$4
+
+       movl    $1,($6)
+       movl    $2,4($6)
+       movl    $3,8($6)
+       movl    $4,12($6)>)dnl
+
+dnl AES_ROUND(table,a,b,c,d,out,ptr)
+dnl Computes one word of the AES round. Leaves result in $6.
+define(<AES_ROUND>, <
+       movzbl  LREG($2), $7
+       movl    AES_TABLE0 ($1, $7, 4),$6
+       movzbl  HREG($3), $7
+       xorl    AES_TABLE1 ($1, $7, 4),$6
+       movl    $4,$7
+       shrl    <$>16,$7
+       andl    <$>0xff,$7
+       xorl    AES_TABLE2 ($1, $7, 4),$6
+       movl    $5,$7
+       shrl    <$>24,$7
+       xorl    AES_TABLE3 ($1, $7, 4),$6>)dnl
+
+dnl AES_FINAL_ROUND(a, b, c, d, table, out, tmp)
+dnl Computes one word of the final round.
+dnl Note that we have to quote $ in constants.
+define(<AES_FINAL_ROUND>, <
+       movzbl  LREG($1),$6
+       movzbl  ($5, $6), $6
+       movl    $2,$7
+       andl    <$>0x0000ff00,$7
+       orl     $7, $6
+       movl    $3,$7
+       andl    <$>0x00ff0000,$7
+       orl     $7, $6
+       movl    $4,$7
+       andl    <$>0xff000000,$7
+       orl     $7, $6
+       roll    <$>8, $6>)dnl
+
+dnl AES_SUBST_BYTE(A, B, C, D, table, ptr)
+dnl Substitutes the least significant byte of
+dnl each of eax, ebx, ecx and edx, and also rotates
+dnl the words one byte to the left.
+dnl Uses that AES_SBOX == 0
+define(<AES_SUBST_BYTE>, <
+       movzbl  LREG($1),$6
+       movb    ($5, $6),LREG($1)
+       roll    <$>8,$1
+
+       movzbl  LREG($2),$6
+       movb    ($5, $6),LREG($2)
+       roll    <$>8,$2
+
+       movzbl  LREG($3),$6
+       movb    ($5, $6),LREG($3)
+       roll    <$>8,$3
+
+       movzbl  LREG($4),$6
+       movb    ($5, $6),LREG($4)
+       roll    <$>8,$4>)dnl
diff --git a/x86/arcfour-crypt.asm b/x86/arcfour-crypt.asm
new file mode 100644 (file)
index 0000000..bdeb98f
--- /dev/null
@@ -0,0 +1,112 @@
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2004, Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+       .file "arcfour-crypt.asm"
+
+       C arcfour_crypt(struct arcfour_ctx *ctx,
+       C               unsigned length, uint8_t *dst,
+       C               const uint8_t *src)
+       .text
+       ALIGN(4)
+PROLOGUE(nettle_arcfour_crypt)
+       C save all registers that need to be saved
+       pushl   %ebx            C  12(%esp)
+       pushl   %ebp            C  8(%esp)
+       pushl   %esi            C  4(%esp)
+       pushl   %edi            C  0(%esp)
+
+C Input arguments:
+       C ctx = 20(%esp)
+       C length = 24(%esp)
+       C dst = 28(%esp)
+       C src = 32(%esp)
+C Register usage:
+       C %ebp = ctx
+       C %esi = src
+       C %edi = dst
+       C %edx = loop counter
+       C %eax = i
+       C %ebx = j
+       C %cl  = si
+       C %ch  = sj
+
+       movl    24(%esp), %edx          C  length
+       movl    20(%esp), %ebp          C  ctx
+       movl    28(%esp), %edi          C  dst
+       movl    32(%esp), %esi          C  src
+
+       lea     (%edx, %edi), %edi
+       lea     (%edx, %esi), %esi
+       negl    %edx
+       jnc     .Lend
+       
+       movzbl  ARCFOUR_I (%ebp), %eax  C  i
+       movzbl  ARCFOUR_J (%ebp), %ebx  C  j
+
+       incb    %al
+       sarl    $1, %edx
+       jc      .Lloop_odd
+       
+       ALIGN(4)
+.Lloop:
+       movb    (%ebp, %eax), %cl       C  si.
+       addb    %cl, %bl
+       movb    (%ebp, %ebx), %ch       C  sj
+       movb    %ch, (%ebp, %eax)       C  S[i] = sj
+       incl    %eax
+       movzbl  %al, %eax
+       movb    %cl, (%ebp, %ebx)       C  S[j] = si
+       addb    %ch, %cl
+       movzbl  %cl, %ecx               C  Clear, so it can be used
+                                       C  for indexing.
+       movb    (%ebp, %ecx), %cl
+       xorb    (%esi, %edx, 2), %cl
+       movb    %cl, (%edi, %edx, 2)
+
+       C FIXME: Could exchange cl and ch in the second half
+       C and try to interleave instructions better.
+.Lloop_odd:
+       movb    (%ebp, %eax), %cl       C  si.
+       addb    %cl, %bl
+       movb    (%ebp, %ebx), %ch       C  sj
+       movb    %ch, (%ebp, %eax)       C  S[i] = sj
+       incl    %eax
+       movzbl  %al, %eax
+       movb    %cl, (%ebp, %ebx)       C  S[j] = si
+       addb    %ch, %cl
+       movzbl  %cl, %ecx               C  Clear, so it can be used
+                                       C  for indexing.
+       movb    (%ebp, %ecx), %cl
+       xorb    1(%esi, %edx, 2), %cl
+       incl    %edx
+       movb    %cl, -1(%edi, %edx, 2)
+
+       jnz     .Lloop
+
+C .Lloop_done:
+       decb    %al
+       movb    %al, ARCFOUR_I (%ebp)           C  Store the new i and j.
+       movb    %bl, ARCFOUR_J (%ebp)
+.Lend:
+       popl    %edi
+       popl    %esi
+       popl    %ebp
+       popl    %ebx
+       ret
+EPILOGUE(nettle_arcfour_crypt)
diff --git a/x86/camellia-crypt-internal.asm b/x86/camellia-crypt-internal.asm
new file mode 100644 (file)
index 0000000..b5c491c
--- /dev/null
@@ -0,0 +1,213 @@
+C -*- mode: asm; asm-comment-char: ?C; -*-  
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2010, Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+C Register usage:
+
+C Camellia state, 128-bit value in little endian order.
+C L0, H0 corresponds to D1 in the spec and i0 in the C implementation.
+C while L1, H1 corresponds to D2/i1.
+define(<L0>,<%eax>)
+define(<H0>,<%ebx>)
+define(<L1>,<%ecx>)
+define(<H1>,<%edx>)
+
+define(<TMP>,<%ebp>)
+define(<KEY>,<%esi>)
+define(<T>,<%edi>)
+
+C Locals on the stack
+
+define(<FRAME_L0>,     <(%esp)>)
+define(<FRAME_H0>,     <4(%esp)>)
+define(<FRAME_L1>,     <8(%esp)>)
+define(<FRAME_H1>,     <12(%esp)>)
+define(<FRAME_CNT>,    <16(%esp)>)
+       
+C Arguments on stack.
+define(<FRAME_CTX>,    <40(%esp)>)
+define(<FRAME_TABLE>,  <44(%esp)>)
+define(<FRAME_LENGTH>, <48(%esp)>)
+define(<FRAME_DST>,    <52(%esp)>)
+define(<FRAME_SRC>,    <56(%esp)>)
+
+define(<SP1110>, <(T,$1,4)>)
+define(<SP0222>, <1024(T,$1,4)>)
+define(<SP3033>, <2048(T,$1,4)>)
+define(<SP4404>, <3072(T,$1,4)>)
+
+C ROUND(xl, xh, yl, yh, key-offset)
+C xl and xh are rotated 16 bits at the end
+C yl and yh are read from stack, and left in registers
+define(<ROUND>, <
+       movzbl  LREG($1), TMP
+       movl    SP1110(TMP), $4
+       movzbl  HREG($1), TMP
+       xorl    SP4404(TMP), $4
+       roll    <$>16, $1
+
+       movzbl  LREG($2), TMP
+       movl    SP4404(TMP), $3
+       movzbl  HREG($2), TMP
+       xorl    SP3033(TMP), $3
+       roll    <$>16, $2
+
+       movzbl  LREG($1), TMP
+       xorl    SP3033(TMP), $4
+       movzbl  HREG($1), TMP
+       xorl    SP0222(TMP), $4
+
+       movzbl  LREG($2), TMP
+       xorl    SP0222(TMP), $3
+       movzbl  HREG($2), TMP
+       xorl    SP1110(TMP), $3
+
+       xorl    $5(KEY), $4
+       xorl    $5 + 4(KEY), $3
+
+       xorl    $3, $4
+       rorl    <$>8, $3
+       xorl    $4, $3
+
+       xorl    FRAME_$3, $3
+       xorl    FRAME_$4, $4
+>)
+
+C Six rounds, with inputs and outputs in registers.
+define(<ROUND6>, <
+       movl    L0, FRAME_L0
+       movl    H0, FRAME_H0
+       movl    L1, FRAME_L1
+       movl    H1, FRAME_H1
+
+       ROUND(L0,H0,<L1>,<H1>,0)
+       movl    L1, FRAME_L1
+       movl    H1, FRAME_H1
+       ROUND(L1,H1,<L0>,<H0>,8)
+       movl    L0, FRAME_L0
+       movl    H0, FRAME_H0
+       ROUND(L0,H0,<L1>,<H1>,16)
+       movl    L1, FRAME_L1
+       movl    H1, FRAME_H1
+       ROUND(L1,H1,<L0>,<H0>,24)
+       movl    L0, FRAME_L0
+       movl    H0, FRAME_H0
+       ROUND(L0,H0,<L1>,<H1>,32)
+       ROUND(L1,H1,<L0>,<H0>,40)
+       roll    <$>16, L1
+       roll    <$>16, H1
+>)
+
+C FL(x0, x1, key-offset)
+define(<FL>, <
+       movl    $3 + 4(KEY), TMP
+       andl    $2, TMP
+       roll    <$>1, TMP
+       xorl    TMP, $1
+       movl    $3(KEY), TMP
+       orl     $1, TMP
+       xorl    TMP, $2
+>)
+C FLINV(x0, x1, key-offset)
+define(<FLINV>, <
+       movl    $3(KEY), TMP
+       orl     $1, TMP
+       xorl    TMP, $2
+       movl    $3 + 4(KEY), TMP
+       andl    $2, TMP
+       roll    <$>1, TMP
+       xorl    TMP, $1
+>)
+
+.file "camellia-encrypt-internal.asm"
+       
+       C _camellia_crypt(struct camellia_context *ctx, 
+       C                 const struct camellia_table *T,
+       C                 unsigned length, uint8_t *dst,
+       C                 uint8_t *src)
+       .text
+       ALIGN(4)
+PROLOGUE(_nettle_camellia_crypt)
+       C save all registers that need to be saved
+       pushl   %ebx            C  32(%esp)
+       pushl   %ebp            C  28(%esp)
+       pushl   %esi            C  24(%esp)
+       pushl   %edi            C  20(%esp)
+
+       subl    $20, %esp 
+
+       movl    FRAME_LENGTH, %ebp
+       testl   %ebp,%ebp
+       jz      .Lend
+
+.Lblock_loop:
+       C Load data, note that we'll happily do unaligned loads
+       movl    FRAME_SRC, TMP
+       movl    (TMP), H0
+       bswap   H0
+       movl    4(TMP), L0
+       bswap   L0
+       movl    8(TMP), H1
+       bswap   H1
+       movl    12(TMP), L1
+       bswap   L1
+       addl    $16, FRAME_SRC
+       movl    FRAME_CTX, KEY
+       movl    (KEY), TMP
+       subl    $8, TMP
+       mov     TMP, FRAME_CNT
+       C       Whitening using first subkey 
+       xor     4(KEY), L0
+       xor     8(KEY), H0
+       add     $12, KEY
+
+       movl    FRAME_TABLE, T
+
+       ROUND6
+.Lround_loop:
+       add     $64, KEY
+       FL(L0, H0, -16)
+       FLINV(L1, H1, -8)
+       ROUND6
+       sub     $8, FRAME_CNT   
+       ja      .Lround_loop
+
+       movl    FRAME_DST, TMP
+       bswap   H0
+       movl    H0,8(TMP)
+       bswap   L0
+       movl    L0,12(TMP)
+       xorl    52(KEY), H1
+       bswap   H1
+       movl    H1, 0(TMP)
+       xorl    48(KEY), L1
+       bswap   L1
+       movl    L1, 4(TMP)
+       addl    $16, FRAME_DST
+       subl    $16, FRAME_LENGTH
+       ja      .Lblock_loop
+
+.Lend:
+       addl    $20, %esp
+       popl    %edi
+       popl    %esi
+       popl    %ebp
+       popl    %ebx
+       ret
+EPILOGUE(_nettle_camellia_crypt)
diff --git a/x86/machine.m4 b/x86/machine.m4
new file mode 100644 (file)
index 0000000..38bee36
--- /dev/null
@@ -0,0 +1,16 @@
+C OFFSET(i)
+C Expands to 4*i, or to the empty string if i is zero
+define(<OFFSET>, <ifelse($1,0,,eval(4*$1))>)
+
+dnl LREG(reg) gives the 8-bit register corresponding to the given 32-bit register.
+define(<LREG>,<ifelse(
+       $1, %eax, %al,
+       $1, %ebx, %bl,
+       $1, %ecx, %cl,
+       $1, %edx, %dl)>)dnl
+
+define(<HREG>,<ifelse(
+       $1, %eax, %ah,
+       $1, %ebx, %bh,
+       $1, %ecx, %ch,
+       $1, %edx, %dh)>)dnl
diff --git a/x86/md5-compress.asm b/x86/md5-compress.asm
new file mode 100644 (file)
index 0000000..44894e3
--- /dev/null
@@ -0,0 +1,174 @@
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2005, Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+C Register usage
+define(<SA>,<%eax>)
+define(<SB>,<%ebx>)
+define(<SC>,<%ecx>)
+define(<SD>,<%edx>)
+define(<TMP>,<%ebp>)
+define(<INPUT>,<%esi>)
+
+C %edi is unused
+
+C F1(x,y,z) = (z ^ (x & (y ^ z)))
+define(<F1>, <
+       movl    $3, TMP
+       xorl    $2, TMP
+       andl    $1, TMP
+       xorl    $3, TMP>)
+
+define(<F2>,<F1($3, $1, $2)>)
+
+C F3(x,y,z) = x ^ y ^ z
+define(<F3>,<
+       movl    $1, TMP
+       xorl    $2, TMP
+       xorl    $3, TMP>)
+
+C F4(x,y,z) = y ^ (x | ~z)
+define(<F4>,<
+       movl    $3, TMP
+       notl    TMP
+       orl     $1, TMP
+       xorl    $2, TMP>)
+
+define(<REF>,<OFFSET($1)(INPUT)>)
+       
+C ROUND(f, w, x, y, z, k, data, s):
+C      w += f(x,y,z) + data + k
+C      w <<< s
+C      w += x
+define(<ROUND>,<
+       addl    $7, $2
+       $1($3, $4, $5)
+       addl    $6, $2
+       addl    TMP, $2
+       roll    <$>$8, $2
+       addl    $3, $2>)
+
+       .file "md5-compress.asm"
+
+       C _nettle_md5_compress(uint32_t *state, uint8_t *data)
+       
+       .text
+       ALIGN(4)
+PROLOGUE(_nettle_md5_compress)
+       C save all registers that need to be saved
+
+                               C  24(%esp)  input
+                               C  20(%esp)  state
+                               C  16(%esp)  Return address
+       pushl   %ebx            C  12(%esp)
+       pushl   %ebp            C   8(%esp)
+       pushl   %esi            C   4(%esp)
+       pushl   %edi            C    (%esp)
+
+       C load the state vector
+       movl    20(%esp),TMP
+       movl    (TMP),   SA
+       movl    4(TMP),  SB
+       movl    8(TMP),  SC
+       movl    12(TMP), SD
+
+       C Pointer to source data.
+       C Note that if unaligned, we suffer unaligned accesses
+       movl    24(%esp), INPUT
+
+       ROUND(<F1>, SA, SB, SC, SD, REF( 0), $0xd76aa478, 7)
+       ROUND(<F1>, SD, SA, SB, SC, REF( 1), $0xe8c7b756, 12)
+       ROUND(<F1>, SC, SD, SA, SB, REF( 2), $0x242070db, 17)
+       ROUND(<F1>, SB, SC, SD, SA, REF( 3), $0xc1bdceee, 22)
+       ROUND(<F1>, SA, SB, SC, SD, REF( 4), $0xf57c0faf, 7)
+       ROUND(<F1>, SD, SA, SB, SC, REF( 5), $0x4787c62a, 12)
+       ROUND(<F1>, SC, SD, SA, SB, REF( 6), $0xa8304613, 17)
+       ROUND(<F1>, SB, SC, SD, SA, REF( 7), $0xfd469501, 22)
+       ROUND(<F1>, SA, SB, SC, SD, REF( 8), $0x698098d8, 7)
+       ROUND(<F1>, SD, SA, SB, SC, REF( 9), $0x8b44f7af, 12)
+       ROUND(<F1>, SC, SD, SA, SB, REF(10), $0xffff5bb1, 17)
+       ROUND(<F1>, SB, SC, SD, SA, REF(11), $0x895cd7be, 22)
+       ROUND(<F1>, SA, SB, SC, SD, REF(12), $0x6b901122, 7)
+       ROUND(<F1>, SD, SA, SB, SC, REF(13), $0xfd987193, 12)
+       ROUND(<F1>, SC, SD, SA, SB, REF(14), $0xa679438e, 17)
+       ROUND(<F1>, SB, SC, SD, SA, REF(15), $0x49b40821, 22)
+       
+        ROUND(<F2>, SA, SB, SC, SD, REF( 1), $0xf61e2562, 5)
+        ROUND(<F2>, SD, SA, SB, SC, REF( 6), $0xc040b340, 9)
+        ROUND(<F2>, SC, SD, SA, SB, REF(11), $0x265e5a51, 14)
+        ROUND(<F2>, SB, SC, SD, SA, REF( 0), $0xe9b6c7aa, 20)
+        ROUND(<F2>, SA, SB, SC, SD, REF( 5), $0xd62f105d, 5)
+        ROUND(<F2>, SD, SA, SB, SC, REF(10), $0x02441453, 9)
+        ROUND(<F2>, SC, SD, SA, SB, REF(15), $0xd8a1e681, 14)
+        ROUND(<F2>, SB, SC, SD, SA, REF( 4), $0xe7d3fbc8, 20)
+        ROUND(<F2>, SA, SB, SC, SD, REF( 9), $0x21e1cde6, 5)
+        ROUND(<F2>, SD, SA, SB, SC, REF(14), $0xc33707d6, 9)
+        ROUND(<F2>, SC, SD, SA, SB, REF( 3), $0xf4d50d87, 14)
+        ROUND(<F2>, SB, SC, SD, SA, REF( 8), $0x455a14ed, 20)
+        ROUND(<F2>, SA, SB, SC, SD, REF(13), $0xa9e3e905, 5)
+        ROUND(<F2>, SD, SA, SB, SC, REF( 2), $0xfcefa3f8, 9)
+        ROUND(<F2>, SC, SD, SA, SB, REF( 7), $0x676f02d9, 14)
+        ROUND(<F2>, SB, SC, SD, SA, REF(12), $0x8d2a4c8a, 20)        
+
+        ROUND(<F3>, SA, SB, SC, SD, REF( 5), $0xfffa3942, 4)
+        ROUND(<F3>, SD, SA, SB, SC, REF( 8), $0x8771f681, 11)
+        ROUND(<F3>, SC, SD, SA, SB, REF(11), $0x6d9d6122, 16)
+        ROUND(<F3>, SB, SC, SD, SA, REF(14), $0xfde5380c, 23)
+        ROUND(<F3>, SA, SB, SC, SD, REF( 1), $0xa4beea44, 4)
+        ROUND(<F3>, SD, SA, SB, SC, REF( 4), $0x4bdecfa9, 11)
+        ROUND(<F3>, SC, SD, SA, SB, REF( 7), $0xf6bb4b60, 16)
+        ROUND(<F3>, SB, SC, SD, SA, REF(10), $0xbebfbc70, 23)
+        ROUND(<F3>, SA, SB, SC, SD, REF(13), $0x289b7ec6, 4)
+        ROUND(<F3>, SD, SA, SB, SC, REF( 0), $0xeaa127fa, 11)
+        ROUND(<F3>, SC, SD, SA, SB, REF( 3), $0xd4ef3085, 16)
+        ROUND(<F3>, SB, SC, SD, SA, REF( 6), $0x04881d05, 23)
+        ROUND(<F3>, SA, SB, SC, SD, REF( 9), $0xd9d4d039, 4)
+        ROUND(<F3>, SD, SA, SB, SC, REF(12), $0xe6db99e5, 11)
+        ROUND(<F3>, SC, SD, SA, SB, REF(15), $0x1fa27cf8, 16)
+        ROUND(<F3>, SB, SC, SD, SA, REF( 2), $0xc4ac5665, 23)        
+
+        ROUND(<F4>, SA, SB, SC, SD, REF( 0), $0xf4292244, 6)
+        ROUND(<F4>, SD, SA, SB, SC, REF( 7), $0x432aff97, 10)
+        ROUND(<F4>, SC, SD, SA, SB, REF(14), $0xab9423a7, 15)
+        ROUND(<F4>, SB, SC, SD, SA, REF( 5), $0xfc93a039, 21)
+        ROUND(<F4>, SA, SB, SC, SD, REF(12), $0x655b59c3, 6)
+        ROUND(<F4>, SD, SA, SB, SC, REF( 3), $0x8f0ccc92, 10)
+        ROUND(<F4>, SC, SD, SA, SB, REF(10), $0xffeff47d, 15)
+        ROUND(<F4>, SB, SC, SD, SA, REF( 1), $0x85845dd1, 21)
+        ROUND(<F4>, SA, SB, SC, SD, REF( 8), $0x6fa87e4f, 6)
+        ROUND(<F4>, SD, SA, SB, SC, REF(15), $0xfe2ce6e0, 10)
+        ROUND(<F4>, SC, SD, SA, SB, REF( 6), $0xa3014314, 15)
+        ROUND(<F4>, SB, SC, SD, SA, REF(13), $0x4e0811a1, 21)
+        ROUND(<F4>, SA, SB, SC, SD, REF( 4), $0xf7537e82, 6)
+        ROUND(<F4>, SD, SA, SB, SC, REF(11), $0xbd3af235, 10)
+        ROUND(<F4>, SC, SD, SA, SB, REF( 2), $0x2ad7d2bb, 15)
+        ROUND(<F4>, SB, SC, SD, SA, REF( 9), $0xeb86d391, 21)
+       
+       C Update the state vector
+       movl    20(%esp),TMP
+       addl    SA, (TMP) 
+       addl    SB, 4(TMP) 
+       addl    SC, 8(TMP) 
+       addl    SD, 12(TMP) 
+
+       popl    %edi
+       popl    %esi
+       popl    %ebp
+       popl    %ebx
+       ret
+EPILOGUE(_nettle_md5_compress)
diff --git a/x86/sha1-compress.asm b/x86/sha1-compress.asm
new file mode 100644 (file)
index 0000000..f6fa347
--- /dev/null
@@ -0,0 +1,1541 @@
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2004, Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+C Register usage
+define(<SA>,<%eax>)
+define(<SB>,<%ebx>)
+define(<SC>,<%ecx>)
+define(<SD>,<%edx>)
+define(<SE>,<%ebp>)
+define(<DATA>,<%esp>)
+define(<T1>,<%edi>)
+define(<T2>,<%esi>)
+       
+C Constants
+define(<K1VALUE>, <0x5A827999>)                C  Rounds  0-19
+define(<K2VALUE>, <0x6ED9EBA1>)                C  Rounds 20-39
+define(<K3VALUE>, <0x8F1BBCDC>)                C  Rounds 40-59
+define(<K4VALUE>, <0xCA62C1D6>)                C  Rounds 60-79
+       
+C Reads the input via T2 into register, byteswaps it, and stores it in the DATA array.
+C SWAP(index, register)
+define(<SWAP>, <
+       movl    OFFSET($1)(T2), $2
+       bswap   $2
+       movl    $2, OFFSET($1) (DATA)
+>)dnl
+
+C The f functions,
+C
+C  f1(x,y,z) = z ^ (x & (y ^ z))
+C  f2(x,y,z) = x ^ y ^ z
+C  f3(x,y,z) = (x & (y ^ z)) + (y & z)
+C  f4 = f2
+
+C This form for f3 was suggested by George Spelvin. The terms can be
+C added into the result one at a time, saving one temporary.
+
+C The form of one sha1 round is
+C
+C   a' = e + a <<< 5 + f( b, c, d ) + k + w;
+C   b' = a;
+C   c' = b <<< 30;
+C   d' = c;
+C   e' = d;
+C
+C where <<< denotes rotation. We permute our variables, so that we
+C instead get
+C
+C   e += a <<< 5 + f( b, c, d ) + k + w;
+C   b <<<= 30
+
+dnl ROUND_F1(a, b, c, d, e, i)
+define(<ROUND_F1>, <
+       mov     OFFSET(eval($6 % 16)) (DATA), T1
+       xor     OFFSET(eval(($6 +  2) % 16)) (DATA), T1
+       xor     OFFSET(eval(($6 +  8) % 16)) (DATA), T1
+       xor     OFFSET(eval(($6 + 13) % 16)) (DATA), T1
+       rol     <$>1, T1
+       mov     T1, OFFSET(eval($6 % 16)) (DATA)
+       mov     $4, T2
+       xor     $3, T2
+       and     $2, T2
+       xor     $4, T2
+       rol     <$>30, $2
+       lea     K1VALUE (T1, $5), $5
+       mov     $1, T1
+       rol     <$>5, T1
+       add     T1, $5
+       add     T2, $5
+>)
+
+dnl ROUND_F1_NOEXP(a, b, c, d, e, i)
+define(<ROUND_F1_NOEXP>, <
+       mov     $4, T2
+       xor     $3, T2
+       mov     $1, T1
+       and     $2, T2
+       add     OFFSET($6) (DATA), $5
+       xor     $4, T2
+       add     T2, $5
+       rol     <$>30, $2
+       rol     <$>5, T1
+       lea     K1VALUE (T1, $5), $5
+>)
+
+dnl ROUND_F2(a, b, c, d, e, i, k)
+define(<ROUND_F2>, <
+       mov     OFFSET(eval($6 % 16)) (DATA), T1
+       xor     OFFSET(eval(($6 +  2) % 16)) (DATA), T1
+       xor     OFFSET(eval(($6 +  8) % 16)) (DATA), T1
+       xor     OFFSET(eval(($6 + 13) % 16)) (DATA), T1
+       rol     <$>1, T1
+       mov     T1, OFFSET(eval($6 % 16)) (DATA)
+       mov     $4, T2
+       xor     $3, T2
+       xor     $2, T2
+       rol     <$>30, $2
+       lea     $7 (T1, $5), $5
+       mov     $1, T1
+       rol     <$>5, T1
+       add     T1, $5
+       add     T2, $5
+>)
+
+dnl ROUND_F3(a, b, c, d, e, i)
+define(<ROUND_F3>, <
+       mov     OFFSET(eval($6 % 16)) (DATA), T1
+       xor     OFFSET(eval(($6 +  2) % 16)) (DATA), T1
+       xor     OFFSET(eval(($6 +  8) % 16)) (DATA), T1
+       xor     OFFSET(eval(($6 + 13) % 16)) (DATA), T1
+       rol     <$>1, T1
+       mov     T1, OFFSET(eval($6 % 16)) (DATA)
+       mov     $4, T2
+       and     $3, T2
+       lea     K3VALUE (T1, $5), $5
+       mov     $4, T1
+       xor     $3, T1
+       and     $2, T1
+       add     T2, $5
+       rol     <$>30, $2
+       mov     $1, T2
+       rol     <$>5, T2
+       add     T1, $5
+       add     T2, $5
+>)
+
+       .file "sha1-compress.asm"
+
+       C _nettle_sha1_compress(uint32_t *state, uint8_t *data)
+       
+       .text
+
+PROLOGUE(_nettle_sha1_compress)
+       C save all registers that need to be saved
+       C                          88(%esp)  data
+       C                          84(%esp)  state
+       C                          80(%esp)  Return address
+       pushl   %ebx            C  76(%esp)
+       pushl   %ebp            C  72(%esp)
+       pushl   %esi            C  68(%esp)
+       pushl   %edi            C  64(%esp)
+
+       subl    $64, %esp       C  %esp = W
+
+       C Loop-mixed to 520 cycles (for the complete function call) on
+       C AMD K7.
+ALIGN(5)
+       mov     88(%esp), T2
+       mov     OFFSET(2)(T2), %ecx
+       mov     OFFSET(0)(T2), %eax
+       bswap   %ecx
+       bswap   %eax
+       mov     %ecx, OFFSET(2) (DATA)
+       mov     %eax, OFFSET(0) (DATA)
+       mov     OFFSET(3)(T2), %edx
+       mov     OFFSET(6)(T2), %ecx
+       mov     OFFSET(4)(T2), %eax
+       mov     OFFSET(1)(T2), %ebx
+       bswap   %ebx
+       bswap   %eax
+       bswap   %ecx
+       mov     %ecx, OFFSET(6) (DATA)
+       mov     %eax, OFFSET(4) (DATA)
+       bswap   %edx
+       mov     %edx, OFFSET(3) (DATA)
+       mov     %ebx, OFFSET(1) (DATA)
+       mov     OFFSET(10)(T2), %ecx
+       mov     OFFSET(8)(T2), %eax
+       mov     OFFSET(7)(T2), %edx
+       bswap   %eax
+       bswap   %edx
+       mov     %edx, OFFSET(7) (DATA)
+       mov     OFFSET(5)(T2), %ebx
+       mov     %eax, OFFSET(8) (DATA)
+       mov     OFFSET(11)(T2), %edx
+       bswap   %ecx
+       bswap   %edx
+       mov     OFFSET(12)(T2), %eax
+       bswap   %ebx
+       mov     %ecx, OFFSET(10) (DATA)
+       mov     %ebx, OFFSET(5) (DATA)
+       mov     %edx, OFFSET(11) (DATA)
+       mov     OFFSET(15)(T2), %edx
+       mov     84(%esp),T1
+       mov     OFFSET(9)(T2), %ebx
+       bswap   %edx
+       bswap   %ebx
+       bswap   %eax
+       mov     OFFSET(14)(T2), %ecx
+       mov     %edx, OFFSET(15) (DATA)
+       bswap   %ecx
+       mov     %ecx, OFFSET(14) (DATA)
+       mov     %ebx, OFFSET(9) (DATA)
+       mov     OFFSET(13)(T2), %ebx
+       mov     12(T1), SD
+       bswap   %ebx
+       mov     %ebx, OFFSET(13) (DATA)
+       mov     8(T1),  SC
+       mov     16(T1), SE
+       mov     4(T1),  SB
+       mov     SD, T2
+       add     OFFSET(0) (DATA), SE
+       xor     SC, T2
+       mov     %eax, OFFSET(12) (DATA)
+       mov     (T1),   SA
+       and     SB, T2
+       xor     SD, T2
+       rol     $30, SB
+       add     T2, SE
+       mov     SA, T1
+       mov     SC, T2
+       add     OFFSET(1) (DATA), SD
+       rol     $5, T1
+       xor     SB, T2
+       and     SA, T2
+       xor     SC, T2
+       lea     K1VALUE (T1, SE), SE
+       add     T2, SD
+       mov     SB, T2
+       rol     $30, SA
+       xor     SA, T2
+       and     SE, T2
+       mov     SE, T1
+       add     OFFSET(2) (DATA), SC
+       rol     $30, SE
+       xor     SB, T2
+       rol     $5, T1
+       lea     K1VALUE (T1, SD), SD
+       mov     SD, T1
+       rol     $5, T1
+       add     T2, SC
+       mov     SA, T2
+       xor     SE, T2
+       lea     K1VALUE (T1, SC), SC
+       and     SD, T2
+       xor     SA, T2
+       add     OFFSET(3) (DATA), SB
+       mov     SC, T1
+       add     T2, SB
+       mov     SE, T2
+       rol     $30, SD
+       xor     SD, T2
+       and     SC, T2
+       rol     $5, T1
+       xor     SE, T2
+       add     OFFSET(4) (DATA), SA
+       lea     K1VALUE (T1, SB), SB
+       add     T2, SA
+       rol     $30, SC
+       mov     SD, T2
+       xor     SC, T2
+       and     SB, T2
+       mov     SB, T1
+       rol     $5, T1
+       add     OFFSET(5) (DATA), SE
+       rol     $30, SB
+       xor     SD, T2
+       add     T2, SE
+       mov     SC, T2
+       xor     SB, T2
+       lea     K1VALUE (T1, SA), SA
+       mov     SA, T1
+       add     OFFSET(6) (DATA), SD
+       and     SA, T2
+       rol     $5, T1
+       xor     SC, T2
+       lea     K1VALUE (T1, SE), SE
+       rol     $30, SA
+       add     T2, SD
+       mov     SB, T2
+       mov     SE, T1
+       xor     SA, T2
+       and     SE, T2
+       rol     $5, T1
+       lea     K1VALUE (T1, SD), SD
+       xor     SB, T2
+       add     OFFSET(7) (DATA), SC
+       rol     $30, SE
+       add     OFFSET(8) (DATA), SB
+       mov     SD, T1
+       add     T2, SC
+       mov     SA, T2
+       xor     SE, T2
+       rol     $5, T1
+       and     SD, T2
+       lea     K1VALUE (T1, SC), SC
+       xor     SA, T2
+       add     T2, SB
+       mov     SE, T2
+       mov     SC, T1
+       rol     $30, SD
+       xor     SD, T2
+       rol     $5, T1
+       lea     K1VALUE (T1, SB), SB
+       and     SC, T2
+       xor     SE, T2
+       add     OFFSET(10) (DATA), SE
+       add     OFFSET(9) (DATA), SA
+       mov     SB, T1
+       add     T2, SA
+       rol     $5, T1
+       lea     K1VALUE (T1, SA), SA
+       mov     SD, T2
+       rol     $30, SC
+       xor     SC, T2
+       and     SB, T2
+       xor     SD, T2
+       rol     $30, SB
+       add     T2, SE
+       mov     SC, T2
+       mov     SA, T1
+       xor     SB, T2
+       add     OFFSET(11) (DATA), SD
+       and     SA, T2
+       rol     $30, SA
+       rol     $5, T1
+       xor     SC, T2
+       lea     K1VALUE (T1, SE), SE
+       add     T2, SD
+       mov     SB, T2
+       xor     SA, T2
+       mov     SE, T1
+       rol     $5, T1
+       and     SE, T2
+       lea     K1VALUE (T1, SD), SD
+       xor     SB, T2
+       add     OFFSET(12) (DATA), SC
+       add     T2, SC
+       rol     $30, SE
+       mov     SA, T2
+       xor     SE, T2
+       mov     SD, T1
+       rol     $5, T1
+       and     SD, T2
+       add     OFFSET(13) (DATA), SB
+       lea     K1VALUE (T1, SC), SC
+       xor     SA, T2
+       add     T2, SB
+       mov     SE, T2
+       rol     $30, SD
+       xor     SD, T2
+       and     SC, T2
+       mov     SC, T1
+       rol     $5, T1
+       rol     $30, SC
+       add     OFFSET(14) (DATA), SA
+       xor     SE, T2
+       add     T2, SA
+       mov     SD, T2
+       xor     SC, T2
+       lea     K1VALUE (T1, SB), SB
+       and     SB, T2
+       mov     SB, T1
+       rol     $5, T1
+       lea     K1VALUE (T1, SA), SA
+       mov     SA, T1
+       xor     SD, T2
+       add     OFFSET(15) (DATA), SE
+       add     T2, SE
+       rol     $5, T1
+       lea     K1VALUE (T1, SE), SE
+       mov     OFFSET(0) (DATA), T1
+       xor     OFFSET(2) (DATA), T1
+       mov     SC, T2
+       xor     OFFSET(8) (DATA), T1
+       xor     OFFSET(13) (DATA), T1
+       rol     $30, SB
+       xor     SB, T2
+       and     SA, T2
+       xor     SC, T2
+       rol     $1, T1
+       lea     K1VALUE (T1, T2), T2
+       mov     T1, OFFSET(0) (DATA)
+       mov     SE, T1
+       rol     $5, T1
+       add     T1, SD
+       mov     OFFSET(1) (DATA), T1
+       xor     OFFSET(3) (DATA), T1
+       rol     $30, SA
+       add     T2, SD
+       mov     SB, T2
+       xor     SA, T2
+       and     SE, T2
+       xor     OFFSET(9) (DATA), T1
+       xor     OFFSET(14) (DATA), T1
+       xor     SB, T2
+       rol     $1, T1
+       mov     T1, OFFSET(1) (DATA)
+       lea     K1VALUE (T1, T2), T2
+       mov     SD, T1
+       rol     $5, T1
+       add     T1, SC
+       mov     OFFSET(2) (DATA), T1
+       xor     OFFSET(4) (DATA), T1
+       rol     $30, SE
+       add     T2, SC
+       mov     SA, T2
+       xor     SE, T2
+       xor     OFFSET(10) (DATA), T1
+       xor     OFFSET(15) (DATA), T1
+       and     SD, T2
+       rol     $1, T1
+       xor     SA, T2
+       mov     T1, OFFSET(2) (DATA)
+       lea     K1VALUE (T1, T2), T2
+       mov     SC, T1
+       rol     $30, SD
+       rol     $5, T1
+       add     T1, SB
+       add     T2, SB
+       mov     SE, T2
+       mov     OFFSET(3) (DATA), T1
+       xor     SD, T2
+       xor     OFFSET(5) (DATA), T1
+       and     SC, T2
+       xor     SE, T2
+       xor     OFFSET(11) (DATA), T1
+       xor     OFFSET(0) (DATA), T1
+       rol     $1, T1
+       mov     T1, OFFSET(3) (DATA)
+       lea     K1VALUE (T1, T2), T2
+       mov     SB, T1
+       rol     $5, T1
+       add     T1, SA
+       mov     OFFSET(4) (DATA), T1
+       xor     OFFSET(6) (DATA), T1
+       rol     $30, SC
+       xor     OFFSET(12) (DATA), T1
+       add     T2, SA
+       xor     OFFSET(1) (DATA), T1
+       mov     SD, T2
+       xor     SC, T2
+       rol     $1, T1
+       xor     SB, T2
+       lea     K2VALUE (T1, T2), T2
+       mov     T1, OFFSET(4) (DATA)
+       mov     SA, T1
+       rol     $5, T1
+       add     T1, SE
+       mov     OFFSET(5) (DATA), T1
+       add     T2, SE
+       mov     SC, T2
+       xor     OFFSET(7) (DATA), T1
+       rol     $30, SB
+       xor     OFFSET(13) (DATA), T1
+       xor     SB, T2
+       xor     OFFSET(2) (DATA), T1
+       xor     SA, T2
+       rol     $1, T1
+       mov     T1, OFFSET(5) (DATA)
+       lea     K2VALUE (T1, T2), T2
+       mov     SE, T1
+       rol     $5, T1
+       add     T1, SD
+       mov     OFFSET(6) (DATA), T1
+       xor     OFFSET(8) (DATA), T1
+       add     T2, SD
+       rol     $30, SA
+       xor     OFFSET(14) (DATA), T1
+       mov     SB, T2
+       xor     OFFSET(3) (DATA), T1
+       xor     SA, T2
+       rol     $1, T1
+       xor     SE, T2
+       lea     K2VALUE (T1, T2), T2
+       mov     T1, OFFSET(6) (DATA)
+       mov     SD, T1
+       rol     $5, T1
+       add     T1, SC
+       add     T2, SC
+       mov     SA, T2
+       rol     $30, SE
+       mov     OFFSET(7) (DATA), T1
+       xor     OFFSET(9) (DATA), T1
+       xor     SE, T2
+       xor     OFFSET(15) (DATA), T1
+       xor     OFFSET(4) (DATA), T1
+       xor     SD, T2
+       rol     $1, T1
+       lea     K2VALUE (T1, T2), T2
+       mov     T1, OFFSET(7) (DATA)
+       mov     SC, T1
+       rol     $5, T1
+       add     T1, SB
+       mov     OFFSET(8) (DATA), T1
+       xor     OFFSET(10) (DATA), T1
+       add     T2, SB
+       rol     $30, SD
+       mov     SE, T2
+       xor     OFFSET(0) (DATA), T1
+       xor     OFFSET(5) (DATA), T1
+       xor     SD, T2
+       xor     SC, T2
+       rol     $1, T1
+       mov     T1, OFFSET(8) (DATA)
+       lea     K2VALUE (T1, T2), T2
+       mov     SB, T1
+       rol     $5, T1
+       add     T1, SA
+       mov     OFFSET(9) (DATA), T1
+       xor     OFFSET(11) (DATA), T1
+       xor     OFFSET(1) (DATA), T1
+       add     T2, SA
+       xor     OFFSET(6) (DATA), T1
+       mov     SD, T2
+       rol     $1, T1
+       rol     $30, SC
+       xor     SC, T2
+       mov     T1, OFFSET(9) (DATA)
+       xor     SB, T2
+       lea     K2VALUE (T1, T2), T2
+       mov     SA, T1
+       rol     $5, T1
+       add     T1, SE
+       mov     OFFSET(10) (DATA), T1
+       xor     OFFSET(12) (DATA), T1
+       xor     OFFSET(2) (DATA), T1
+       add     T2, SE
+       mov     SC, T2
+       rol     $30, SB
+       xor     OFFSET(7) (DATA), T1
+       xor     SB, T2
+       rol     $1, T1
+       xor     SA, T2
+       lea     K2VALUE (T1, T2), T2
+       mov     T1, OFFSET(10) (DATA)
+       mov     SE, T1
+       rol     $5, T1
+       add     T1, SD
+       mov     OFFSET(11) (DATA), T1
+       xor     OFFSET(13) (DATA), T1
+       rol     $30, SA
+       xor     OFFSET(3) (DATA), T1
+       add     T2, SD
+       xor     OFFSET(8) (DATA), T1
+       mov     SB, T2
+       xor     SA, T2
+       rol     $1, T1
+       mov     T1, OFFSET(11) (DATA)
+       xor     SE, T2
+       lea     K2VALUE (T1, T2), T2
+       mov     SD, T1
+       rol     $5, T1
+       add     T1, SC
+       mov     OFFSET(12) (DATA), T1
+       xor     OFFSET(14) (DATA), T1
+       rol     $30, SE
+       add     T2, SC
+       xor     OFFSET(4) (DATA), T1
+       mov     SA, T2
+       xor     OFFSET(9) (DATA), T1
+       xor     SE, T2
+       rol     $1, T1
+       xor     SD, T2
+       mov     T1, OFFSET(12) (DATA)
+       lea     K2VALUE (T1, T2), T2
+       mov     SC, T1
+       rol     $5, T1
+       add     T1, SB
+       rol     $30, SD
+       mov     OFFSET(13) (DATA), T1
+       xor     OFFSET(15) (DATA), T1
+       add     T2, SB
+       mov     SE, T2
+       xor     OFFSET(5) (DATA), T1
+       xor     SD, T2
+       xor     OFFSET(10) (DATA), T1
+       xor     SC, T2
+       rol     $1, T1
+       lea     K2VALUE (T1, T2), T2
+       mov     T1, OFFSET(13) (DATA)
+       mov     SB, T1
+       rol     $5, T1
+       add     T1, SA
+       add     T2, SA
+       mov     SD, T2
+       mov     OFFSET(14) (DATA), T1
+       xor     OFFSET(0) (DATA), T1
+       rol     $30, SC
+       xor     OFFSET(6) (DATA), T1
+       xor     OFFSET(11) (DATA), T1
+       xor     SC, T2
+       xor     SB, T2
+       rol     $1, T1
+       lea     K2VALUE (T1, T2), T2
+       mov     T1, OFFSET(14) (DATA)
+       mov     SA, T1
+       rol     $5, T1
+       add     T1, SE
+       mov     OFFSET(15) (DATA), T1
+       xor     OFFSET(1) (DATA), T1
+       add     T2, SE
+       mov     SC, T2
+       rol     $30, SB
+       xor     SB, T2
+       xor     OFFSET(7) (DATA), T1
+       xor     OFFSET(12) (DATA), T1
+       xor     SA, T2
+       rol     $1, T1
+       mov     T1, OFFSET(15) (DATA)
+       lea     K2VALUE (T1, T2), T2
+       mov     SE, T1
+       rol     $5, T1
+       add     T1, SD
+       mov     OFFSET(0) (DATA), T1
+       xor     OFFSET(2) (DATA), T1
+       xor     OFFSET(8) (DATA), T1
+       add     T2, SD
+       mov     SB, T2
+       rol     $30, SA
+       xor     SA, T2
+       xor     OFFSET(13) (DATA), T1
+       rol     $1, T1
+       xor     SE, T2
+       mov     T1, OFFSET(0) (DATA)
+       lea     K2VALUE (T1, T2), T2
+       mov     SD, T1
+       rol     $5, T1
+       add     T1, SC
+       mov     OFFSET(1) (DATA), T1
+       xor     OFFSET(3) (DATA), T1
+       add     T2, SC
+       mov     SA, T2
+       rol     $30, SE
+       xor     SE, T2
+       xor     OFFSET(9) (DATA), T1
+       xor     OFFSET(14) (DATA), T1
+       rol     $1, T1
+       xor     SD, T2
+       lea     K2VALUE (T1, T2), T2
+       mov     T1, OFFSET(1) (DATA)
+       mov     SC, T1
+       rol     $5, T1
+       add     T1, SB
+       mov     OFFSET(2) (DATA), T1
+       rol     $30, SD
+       xor     OFFSET(4) (DATA), T1
+       add     T2, SB
+       mov     SE, T2
+       xor     OFFSET(10) (DATA), T1
+       xor     OFFSET(15) (DATA), T1
+       xor     SD, T2
+       xor     SC, T2
+       rol     $1, T1
+       mov     T1, OFFSET(2) (DATA)
+       lea     K2VALUE (T1, T2), T2
+       mov     SB, T1
+       rol     $5, T1
+       add     T1, SA
+       mov     OFFSET(3) (DATA), T1
+       xor     OFFSET(5) (DATA), T1
+       xor     OFFSET(11) (DATA), T1
+       xor     OFFSET(0) (DATA), T1
+       add     T2, SA
+       rol     $30, SC
+       mov     SD, T2
+       xor     SC, T2
+       rol     $1, T1
+       xor     SB, T2
+       lea     K2VALUE (T1, T2), T2
+       mov     T1, OFFSET(3) (DATA)
+       mov     SA, T1
+       rol     $5, T1
+       rol     $30, SB
+       add     T1, SE
+       mov     OFFSET(4) (DATA), T1
+       add     T2, SE
+       xor     OFFSET(6) (DATA), T1
+       xor     OFFSET(12) (DATA), T1
+       xor     OFFSET(1) (DATA), T1
+       mov     SC, T2
+       xor     SB, T2
+       rol     $1, T1
+       xor     SA, T2
+       lea     K2VALUE (T1, T2), T2
+       mov     T1, OFFSET(4) (DATA)
+       mov     SE, T1
+       rol     $5, T1
+       add     T1, SD
+       add     T2, SD
+       mov     OFFSET(5) (DATA), T1
+       mov     SB, T2
+       rol     $30, SA
+       xor     SA, T2
+       xor     SE, T2
+       xor     OFFSET(7) (DATA), T1
+       xor     OFFSET(13) (DATA), T1
+       xor     OFFSET(2) (DATA), T1
+       rol     $1, T1
+       mov     T1, OFFSET(5) (DATA)
+       lea     K2VALUE (T1, T2), T2
+       mov     SD, T1
+       rol     $5, T1
+       add     T1, SC
+       mov     OFFSET(6) (DATA), T1
+       xor     OFFSET(8) (DATA), T1
+       add     T2, SC
+       xor     OFFSET(14) (DATA), T1
+       xor     OFFSET(3) (DATA), T1
+       rol     $1, T1
+       mov     T1, OFFSET(6) (DATA)
+       mov     SA, T2
+       rol     $30, SE
+       xor     SE, T2
+       xor     SD, T2
+       lea     K2VALUE (T1, T2), T2
+       mov     SC, T1
+       rol     $5, T1
+       add     T1, SB
+       add     T2, SB
+       mov     OFFSET(7) (DATA), T1
+       mov     SE, T2
+       rol     $30, SD
+       xor     OFFSET(9) (DATA), T1
+       xor     SD, T2
+       xor     SC, T2
+       xor     OFFSET(15) (DATA), T1
+       xor     OFFSET(4) (DATA), T1
+       rol     $1, T1
+       mov     T1, OFFSET(7) (DATA)
+       lea     K2VALUE (T1, T2), T2
+       mov     SB, T1
+       rol     $5, T1
+       add     T1, SA
+       mov     OFFSET(8) (DATA), T1
+       xor     OFFSET(10) (DATA), T1
+       rol     $30, SC
+       xor     OFFSET(0) (DATA), T1
+       add     T2, SA
+       mov     SD, T2
+       xor     OFFSET(5) (DATA), T1
+       rol     $1, T1
+       and     SC, T2
+       mov     T1, OFFSET(8) (DATA)
+       lea     K3VALUE (T1, T2), T1
+       add     T1, SE
+       mov     SA, T1
+       mov     SD, T2
+       xor     SC, T2
+       and     SB, T2
+       rol     $30, SB
+       rol     $5, T1
+       add     T1, SE
+       mov     OFFSET(9) (DATA), T1
+       xor     OFFSET(11) (DATA), T1
+       xor     OFFSET(1) (DATA), T1
+       add     T2, SE
+       mov     SC, T2
+       xor     OFFSET(6) (DATA), T1
+       rol     $1, T1
+       and     SB, T2
+       mov     T1, OFFSET(9) (DATA)
+       lea     K3VALUE (T1, T2), T1
+       add     T1, SD
+       mov     SC, T2
+       xor     SB, T2
+       mov     SE, T1
+       rol     $5, T1
+       add     T1, SD
+       mov     OFFSET(10) (DATA), T1
+       and     SA, T2
+       add     T2, SD
+       xor     OFFSET(12) (DATA), T1
+       xor     OFFSET(2) (DATA), T1
+       rol     $30, SA
+       mov     SB, T2
+       and     SA, T2
+       xor     OFFSET(7) (DATA), T1
+       rol     $1, T1
+       mov     T1, OFFSET(10) (DATA)
+       lea     K3VALUE (T1, T2), T1
+       add     T1, SC
+       mov     SD, T1
+       rol     $5, T1
+       mov     SB, T2
+       add     T1, SC
+       mov     OFFSET(11) (DATA), T1
+       xor     SA, T2
+       xor     OFFSET(13) (DATA), T1
+       xor     OFFSET(3) (DATA), T1
+       and     SE, T2
+       xor     OFFSET(8) (DATA), T1
+       add     T2, SC
+       rol     $1, T1
+       mov     SA, T2
+       mov     T1, OFFSET(11) (DATA)
+       rol     $30, SE
+       and     SE, T2
+       lea     K3VALUE (T1, T2), T1
+       add     T1, SB
+       mov     SA, T2
+       mov     SC, T1
+       xor     SE, T2
+       rol     $5, T1
+       add     T1, SB
+       mov     OFFSET(12) (DATA), T1
+       xor     OFFSET(14) (DATA), T1
+       xor     OFFSET(4) (DATA), T1
+       xor     OFFSET(9) (DATA), T1
+       and     SD, T2
+       rol     $30, SD
+       add     T2, SB
+       rol     $1, T1
+       mov     T1, OFFSET(12) (DATA)
+       mov     SE, T2
+       and     SD, T2
+       lea     K3VALUE (T1, T2), T1
+       add     T1, SA
+       mov     SB, T1
+       rol     $5, T1
+       add     T1, SA
+       mov     OFFSET(13) (DATA), T1
+       xor     OFFSET(15) (DATA), T1
+       mov     SE, T2
+       xor     OFFSET(5) (DATA), T1
+       xor     SD, T2
+       and     SC, T2
+       xor     OFFSET(10) (DATA), T1
+       add     T2, SA
+       rol     $1, T1
+       rol     $30, SC
+       mov     T1, OFFSET(13) (DATA)
+       mov     SD, T2
+       and     SC, T2
+       lea     K3VALUE (T1, T2), T1
+       mov     SD, T2
+       add     T1, SE
+       mov     SA, T1
+       rol     $5, T1
+       add     T1, SE
+       mov     OFFSET(14) (DATA), T1
+       xor     OFFSET(0) (DATA), T1
+       xor     SC, T2
+       and     SB, T2
+       xor     OFFSET(6) (DATA), T1
+       rol     $30, SB
+       xor     OFFSET(11) (DATA), T1
+       rol     $1, T1
+       add     T2, SE
+       mov     SC, T2
+       mov     T1, OFFSET(14) (DATA)
+       and     SB, T2
+       lea     K3VALUE (T1, T2), T1
+       mov     SC, T2
+       add     T1, SD
+       mov     SE, T1
+       xor     SB, T2
+       rol     $5, T1
+       add     T1, SD
+       mov     OFFSET(15) (DATA), T1
+       xor     OFFSET(1) (DATA), T1
+       and     SA, T2
+       xor     OFFSET(7) (DATA), T1
+       xor     OFFSET(12) (DATA), T1
+       add     T2, SD
+       rol     $30, SA
+       mov     SB, T2
+       rol     $1, T1
+       mov     T1, OFFSET(15) (DATA)
+       and     SA, T2
+       lea     K3VALUE (T1, T2), T1
+       add     T1, SC
+       mov     SD, T1
+       mov     SB, T2
+       rol     $5, T1
+       add     T1, SC
+       mov     OFFSET(0) (DATA), T1
+       xor     SA, T2
+       xor     OFFSET(2) (DATA), T1
+       xor     OFFSET(8) (DATA), T1
+       xor     OFFSET(13) (DATA), T1
+       and     SE, T2
+       add     T2, SC
+       rol     $30, SE
+       rol     $1, T1
+       mov     T1, OFFSET(0) (DATA)
+       mov     SA, T2
+       and     SE, T2
+       lea     K3VALUE (T1, T2), T1
+       add     T1, SB
+       mov     SC, T1
+       mov     SA, T2
+       xor     SE, T2
+       rol     $5, T1
+       add     T1, SB
+       mov     OFFSET(1) (DATA), T1
+       xor     OFFSET(3) (DATA), T1
+       xor     OFFSET(9) (DATA), T1
+       and     SD, T2
+       xor     OFFSET(14) (DATA), T1
+       add     T2, SB
+       rol     $30, SD
+       mov     SE, T2
+       rol     $1, T1
+       and     SD, T2
+       mov     T1, OFFSET(1) (DATA)
+       lea     K3VALUE (T1, T2), T1
+       add     T1, SA
+       mov     SB, T1
+       rol     $5, T1
+       add     T1, SA
+       mov     SE, T2
+       mov     OFFSET(2) (DATA), T1
+       xor     SD, T2
+       xor     OFFSET(4) (DATA), T1
+       xor     OFFSET(10) (DATA), T1
+       and     SC, T2
+       add     T2, SA
+       xor     OFFSET(15) (DATA), T1
+       rol     $30, SC
+       mov     SD, T2
+       rol     $1, T1
+       mov     T1, OFFSET(2) (DATA)
+       and     SC, T2
+       lea     K3VALUE (T1, T2), T1
+       add     T1, SE
+       mov     SA, T1
+       rol     $5, T1
+       add     T1, SE
+       mov     OFFSET(3) (DATA), T1
+       xor     OFFSET(5) (DATA), T1
+       xor     OFFSET(11) (DATA), T1
+       xor     OFFSET(0) (DATA), T1
+       mov     SD, T2
+       rol     $1, T1
+       xor     SC, T2
+       and     SB, T2
+       mov     T1, OFFSET(3) (DATA)
+       rol     $30, SB
+       add     T2, SE
+       mov     SC, T2
+       and     SB, T2
+       lea     K3VALUE (T1, T2), T1
+       add     T1, SD
+       mov     SE, T1
+       mov     SC, T2
+       rol     $5, T1
+       add     T1, SD
+       mov     OFFSET(4) (DATA), T1
+       xor     OFFSET(6) (DATA), T1
+       xor     SB, T2
+       and     SA, T2
+       add     T2, SD
+       mov     SB, T2
+       xor     OFFSET(12) (DATA), T1
+       rol     $30, SA
+       and     SA, T2
+       xor     OFFSET(1) (DATA), T1
+       rol     $1, T1
+       mov     T1, OFFSET(4) (DATA)
+       lea     K3VALUE (T1, T2), T1
+       add     T1, SC
+       mov     SD, T1
+       rol     $5, T1
+       add     T1, SC
+       mov     OFFSET(5) (DATA), T1
+       xor     OFFSET(7) (DATA), T1
+       mov     SB, T2
+       xor     OFFSET(13) (DATA), T1
+       xor     SA, T2
+       xor     OFFSET(2) (DATA), T1
+       and     SE, T2
+       rol     $30, SE
+       add     T2, SC
+       rol     $1, T1
+       mov     SA, T2
+       mov     T1, OFFSET(5) (DATA)
+       and     SE, T2
+       lea     K3VALUE (T1, T2), T1
+       add     T1, SB
+       mov     SA, T2
+       mov     SC, T1
+       rol     $5, T1
+       add     T1, SB
+       xor     SE, T2
+       and     SD, T2
+       mov     OFFSET(6) (DATA), T1
+       xor     OFFSET(8) (DATA), T1
+       xor     OFFSET(14) (DATA), T1
+       xor     OFFSET(3) (DATA), T1
+       rol     $1, T1
+       add     T2, SB
+       rol     $30, SD
+       mov     SE, T2
+       and     SD, T2
+       mov     T1, OFFSET(6) (DATA)
+       lea     K3VALUE (T1, T2), T1
+       add     T1, SA
+       mov     SB, T1
+       rol     $5, T1
+       add     T1, SA
+       mov     OFFSET(7) (DATA), T1
+       xor     OFFSET(9) (DATA), T1
+       mov     SE, T2
+       xor     SD, T2
+       xor     OFFSET(15) (DATA), T1
+       and     SC, T2
+       rol     $30, SC
+       add     T2, SA
+       mov     SD, T2
+       xor     OFFSET(4) (DATA), T1
+       rol     $1, T1
+       and     SC, T2
+       mov     T1, OFFSET(7) (DATA)
+       lea     K3VALUE (T1, T2), T1
+       add     T1, SE
+       mov     SA, T1
+       rol     $5, T1
+       mov     SD, T2
+       add     T1, SE
+       mov     OFFSET(8) (DATA), T1
+       xor     OFFSET(10) (DATA), T1
+       xor     SC, T2
+       xor     OFFSET(0) (DATA), T1
+       and     SB, T2
+       add     T2, SE
+       xor     OFFSET(5) (DATA), T1
+       rol     $30, SB
+       mov     SC, T2
+       and     SB, T2
+       rol     $1, T1
+       mov     T1, OFFSET(8) (DATA)
+       lea     K3VALUE (T1, T2), T1
+       add     T1, SD
+       mov     SE, T1
+       rol     $5, T1
+       mov     SC, T2
+       xor     SB, T2
+       add     T1, SD
+       and     SA, T2
+       mov     OFFSET(9) (DATA), T1
+       rol     $30, SA
+       xor     OFFSET(11) (DATA), T1
+       xor     OFFSET(1) (DATA), T1
+       add     T2, SD
+       mov     SB, T2
+       and     SA, T2
+       xor     OFFSET(6) (DATA), T1
+       rol     $1, T1
+       mov     T1, OFFSET(9) (DATA)
+       lea     K3VALUE (T1, T2), T1
+       add     T1, SC
+       mov     SD, T1
+       rol     $5, T1
+       mov     SB, T2
+       xor     SA, T2
+       and     SE, T2
+       add     T1, SC
+       mov     OFFSET(10) (DATA), T1
+       xor     OFFSET(12) (DATA), T1
+       xor     OFFSET(2) (DATA), T1
+       add     T2, SC
+       mov     SA, T2
+       rol     $30, SE
+       xor     OFFSET(7) (DATA), T1
+       rol     $1, T1
+       and     SE, T2
+       mov     T1, OFFSET(10) (DATA)
+       lea     K3VALUE (T1, T2), T1
+       mov     SA, T2
+       xor     SE, T2
+       add     T1, SB
+       mov     SC, T1
+       rol     $5, T1
+       add     T1, SB
+       mov     OFFSET(11) (DATA), T1
+       xor     OFFSET(13) (DATA), T1
+       xor     OFFSET(3) (DATA), T1
+       xor     OFFSET(8) (DATA), T1
+       and     SD, T2
+       add     T2, SB
+       mov     SE, T2
+       rol     $1, T1
+       mov     T1, OFFSET(11) (DATA)
+       rol     $30, SD
+       and     SD, T2
+       lea     K3VALUE (T1, T2), T1
+       mov     SE, T2
+       add     T1, SA
+       xor     SD, T2
+       mov     SB, T1
+       and     SC, T2
+       rol     $30, SC
+       rol     $5, T1
+       add     T1, SA
+       mov     OFFSET(12) (DATA), T1
+       xor     OFFSET(14) (DATA), T1
+       add     T2, SA
+       mov     SD, T2
+       xor     OFFSET(4) (DATA), T1
+       xor     OFFSET(9) (DATA), T1
+       rol     $1, T1
+       mov     T1, OFFSET(12) (DATA)
+       xor     SC, T2
+       xor     SB, T2
+       lea     K4VALUE (T1, T2), T2
+       mov     SA, T1
+       rol     $5, T1
+       add     T1, SE
+       mov     OFFSET(13) (DATA), T1
+       xor     OFFSET(15) (DATA), T1
+       add     T2, SE
+       rol     $30, SB
+       mov     SC, T2
+       xor     OFFSET(5) (DATA), T1
+       xor     SB, T2
+       xor     OFFSET(10) (DATA), T1
+       rol     $1, T1
+       mov     T1, OFFSET(13) (DATA)
+       xor     SA, T2
+       lea     K4VALUE (T1, T2), T2
+       mov     SE, T1
+       rol     $5, T1
+       add     T1, SD
+       mov     OFFSET(14) (DATA), T1
+       xor     OFFSET(0) (DATA), T1
+       rol     $30, SA
+       add     T2, SD
+       mov     SB, T2
+       xor     SA, T2
+       xor     SE, T2
+       xor     OFFSET(6) (DATA), T1
+       xor     OFFSET(11) (DATA), T1
+       rol     $1, T1
+       lea     K4VALUE (T1, T2), T2
+       mov     T1, OFFSET(14) (DATA)
+       mov     SD, T1
+       rol     $5, T1
+       add     T1, SC
+       add     T2, SC
+       mov     OFFSET(15) (DATA), T1
+       mov     SA, T2
+       rol     $30, SE
+       xor     OFFSET(1) (DATA), T1
+       xor     OFFSET(7) (DATA), T1
+       xor     SE, T2
+       xor     SD, T2
+       xor     OFFSET(12) (DATA), T1
+       rol     $1, T1
+       mov     T1, OFFSET(15) (DATA)
+       lea     K4VALUE (T1, T2), T2
+       mov     SC, T1
+       rol     $5, T1
+       add     T1, SB
+       mov     OFFSET(0) (DATA), T1
+       add     T2, SB
+       xor     OFFSET(2) (DATA), T1
+       mov     SE, T2
+       rol     $30, SD
+       xor     OFFSET(8) (DATA), T1
+       xor     SD, T2
+       xor     OFFSET(13) (DATA), T1
+       xor     SC, T2
+       rol     $1, T1
+       lea     K4VALUE (T1, T2), T2
+       mov     T1, OFFSET(0) (DATA)
+       mov     SB, T1
+       rol     $5, T1
+       add     T1, SA
+       mov     OFFSET(1) (DATA), T1
+       rol     $30, SC
+       xor     OFFSET(3) (DATA), T1
+       xor     OFFSET(9) (DATA), T1
+       xor     OFFSET(14) (DATA), T1
+       add     T2, SA
+       mov     SD, T2
+       xor     SC, T2
+       rol     $1, T1
+       xor     SB, T2
+       lea     K4VALUE (T1, T2), T2
+       mov     T1, OFFSET(1) (DATA)
+       mov     SA, T1
+       rol     $5, T1
+       add     T1, SE
+       mov     OFFSET(2) (DATA), T1
+       rol     $30, SB
+       xor     OFFSET(4) (DATA), T1
+       add     T2, SE
+       mov     SC, T2
+       xor     SB, T2
+       xor     OFFSET(10) (DATA), T1
+       xor     OFFSET(15) (DATA), T1
+       xor     SA, T2
+       rol     $1, T1
+       lea     K4VALUE (T1, T2), T2
+       mov     T1, OFFSET(2) (DATA)
+       mov     SE, T1
+       rol     $5, T1
+       add     T1, SD
+       mov     OFFSET(3) (DATA), T1
+       xor     OFFSET(5) (DATA), T1
+       xor     OFFSET(11) (DATA), T1
+       xor     OFFSET(0) (DATA), T1
+       rol     $30, SA
+       add     T2, SD
+       mov     SB, T2
+       rol     $1, T1
+       mov     T1, OFFSET(3) (DATA)
+       xor     SA, T2
+       xor     SE, T2
+       lea     K4VALUE (T1, T2), T2
+       mov     SD, T1
+       rol     $5, T1
+       add     T1, SC
+       mov     OFFSET(4) (DATA), T1
+       add     T2, SC
+       rol     $30, SE
+       xor     OFFSET(6) (DATA), T1
+       mov     SA, T2
+       xor     OFFSET(12) (DATA), T1
+       xor     SE, T2
+       xor     OFFSET(1) (DATA), T1
+       rol     $1, T1
+       xor     SD, T2
+       lea     K4VALUE (T1, T2), T2
+       mov     T1, OFFSET(4) (DATA)
+       mov     SC, T1
+       rol     $5, T1
+       add     T1, SB
+       rol     $30, SD
+       mov     OFFSET(5) (DATA), T1
+       add     T2, SB
+       xor     OFFSET(7) (DATA), T1
+       xor     OFFSET(13) (DATA), T1
+       mov     SE, T2
+       xor     SD, T2
+       xor     OFFSET(2) (DATA), T1
+       xor     SC, T2
+       rol     $1, T1
+       mov     T1, OFFSET(5) (DATA)
+       lea     K4VALUE (T1, T2), T2
+       mov     SB, T1
+       rol     $5, T1
+       add     T1, SA
+       mov     OFFSET(6) (DATA), T1
+       xor     OFFSET(8) (DATA), T1
+       xor     OFFSET(14) (DATA), T1
+       add     T2, SA
+       xor     OFFSET(3) (DATA), T1
+       mov     SD, T2
+       rol     $30, SC
+       rol     $1, T1
+       xor     SC, T2
+       mov     T1, OFFSET(6) (DATA)
+       xor     SB, T2
+       lea     K4VALUE (T1, T2), T2
+       mov     SA, T1
+       rol     $5, T1
+       add     T1, SE
+       add     T2, SE
+       mov     OFFSET(7) (DATA), T1
+       xor     OFFSET(9) (DATA), T1
+       xor     OFFSET(15) (DATA), T1
+       rol     $30, SB
+       xor     OFFSET(4) (DATA), T1
+       mov     SC, T2
+       rol     $1, T1
+       mov     T1, OFFSET(7) (DATA)
+       xor     SB, T2
+       xor     SA, T2
+       lea     K4VALUE (T1, T2), T2
+       mov     SE, T1
+       rol     $5, T1
+       add     T1, SD
+       rol     $30, SA
+       mov     OFFSET(8) (DATA), T1
+       xor     OFFSET(10) (DATA), T1
+       add     T2, SD
+       xor     OFFSET(0) (DATA), T1
+       xor     OFFSET(5) (DATA), T1
+       rol     $1, T1
+       mov     SB, T2
+       mov     T1, OFFSET(8) (DATA)
+       xor     SA, T2
+       xor     SE, T2
+       lea     K4VALUE (T1, T2), T2
+       mov     SD, T1
+       rol     $5, T1
+       add     T1, SC
+       add     T2, SC
+       mov     SA, T2
+       mov     OFFSET(9) (DATA), T1
+       rol     $30, SE
+       xor     OFFSET(11) (DATA), T1
+       xor     OFFSET(1) (DATA), T1
+       xor     OFFSET(6) (DATA), T1
+       xor     SE, T2
+       xor     SD, T2
+       rol     $1, T1
+       lea     K4VALUE (T1, T2), T2
+       mov     T1, OFFSET(9) (DATA)
+       mov     SC, T1
+       rol     $5, T1
+       add     T1, SB
+       rol     $30, SD
+       mov     OFFSET(10) (DATA), T1
+       xor     OFFSET(12) (DATA), T1
+       xor     OFFSET(2) (DATA), T1
+       add     T2, SB
+       mov     SE, T2
+       xor     SD, T2
+       xor     SC, T2
+       xor     OFFSET(7) (DATA), T1
+       rol     $1, T1
+       mov     T1, OFFSET(10) (DATA)
+       lea     K4VALUE (T1, T2), T2
+       mov     SB, T1
+       rol     $5, T1
+       add     T1, SA
+       mov     OFFSET(11) (DATA), T1
+       xor     OFFSET(13) (DATA), T1
+       xor     OFFSET(3) (DATA), T1
+       add     T2, SA
+       mov     SD, T2
+       rol     $30, SC
+       xor     SC, T2
+       xor     OFFSET(8) (DATA), T1
+       rol     $1, T1
+       xor     SB, T2
+       lea     K4VALUE (T1, T2), T2
+       mov     T1, OFFSET(11) (DATA)
+       mov     SA, T1
+       rol     $5, T1
+       add     T1, SE
+       mov     OFFSET(12) (DATA), T1
+       add     T2, SE
+       xor     OFFSET(14) (DATA), T1
+       rol     $30, SB
+       mov     SC, T2
+       xor     OFFSET(4) (DATA), T1
+       xor     SB, T2
+       xor     SA, T2
+       xor     OFFSET(9) (DATA), T1
+       rol     $1, T1
+       lea     K4VALUE (T1, T2), T2
+       mov     T1, OFFSET(12) (DATA)
+       mov     SE, T1
+       rol     $5, T1
+       add     T1, SD
+       add     T2, SD
+       rol     $30, SA
+       mov     OFFSET(13) (DATA), T1
+       xor     OFFSET(15) (DATA), T1
+       mov     SB, T2
+       xor     OFFSET(5) (DATA), T1
+       xor     SA, T2
+       xor     OFFSET(10) (DATA), T1
+       xor     SE, T2
+       rol     $1, T1
+       lea     K4VALUE (T1, T2), T2
+       mov     T1, OFFSET(13) (DATA)
+       mov     SD, T1
+       rol     $5, T1
+       add     T1, SC
+       mov     OFFSET(14) (DATA), T1
+       xor     OFFSET(0) (DATA), T1
+       xor     OFFSET(6) (DATA), T1
+       add     T2, SC
+       rol     $30, SE
+       mov     SA, T2
+       xor     SE, T2
+       xor     OFFSET(11) (DATA), T1
+       xor     SD, T2
+       rol     $1, T1
+       lea     K4VALUE (T1, T2), T2
+       mov     T1, OFFSET(14) (DATA)
+       mov     SC, T1
+       rol     $5, T1
+       add     T1, SB
+       mov     OFFSET(15) (DATA), T1
+       xor     OFFSET(1) (DATA), T1
+       xor     OFFSET(7) (DATA), T1
+       rol     $30, SD
+       add     T2, SB
+       xor     OFFSET(12) (DATA), T1
+       mov     SE, T2
+       xor     SD, T2
+       rol     $1, T1
+       xor     SC, T2
+       lea     K4VALUE (T1, T2), T2
+       rol     $30, SC
+       mov     T1, OFFSET(15) (DATA)
+       mov     SB, T1
+       rol     $5, T1
+       add     T1, SA
+       add     T2, SA
+
+C      C Load and byteswap data
+C      movl    88(%esp), T2
+C 
+C      SWAP( 0, %eax) SWAP( 1, %ebx) SWAP( 2, %ecx) SWAP( 3, %edx)
+C      SWAP( 4, %eax) SWAP( 5, %ebx) SWAP( 6, %ecx) SWAP( 7, %edx)
+C      SWAP( 8, %eax) SWAP( 9, %ebx) SWAP(10, %ecx) SWAP(11, %edx)
+C      SWAP(12, %eax) SWAP(13, %ebx) SWAP(14, %ecx) SWAP(15, %edx)
+C 
+C      C load the state vector
+C      movl    84(%esp),T1
+C      movl    (T1),   SA
+C      movl    4(T1),  SB
+C      movl    8(T1),  SC
+C      movl    12(T1), SD
+C      movl    16(T1), SE
+C 
+C      ROUND_F1_NOEXP(SA, SB, SC, SD, SE,  0)
+C      ROUND_F1_NOEXP(SE, SA, SB, SC, SD,  1)
+C      ROUND_F1_NOEXP(SD, SE, SA, SB, SC,  2)
+C      ROUND_F1_NOEXP(SC, SD, SE, SA, SB,  3)
+C      ROUND_F1_NOEXP(SB, SC, SD, SE, SA,  4)
+C 
+C      ROUND_F1_NOEXP(SA, SB, SC, SD, SE,  5)
+C      ROUND_F1_NOEXP(SE, SA, SB, SC, SD,  6)
+C      ROUND_F1_NOEXP(SD, SE, SA, SB, SC,  7)
+C      ROUND_F1_NOEXP(SC, SD, SE, SA, SB,  8)
+C      ROUND_F1_NOEXP(SB, SC, SD, SE, SA,  9)
+C 
+C      ROUND_F1_NOEXP(SA, SB, SC, SD, SE, 10)
+C      ROUND_F1_NOEXP(SE, SA, SB, SC, SD, 11)
+C      ROUND_F1_NOEXP(SD, SE, SA, SB, SC, 12)
+C      ROUND_F1_NOEXP(SC, SD, SE, SA, SB, 13)
+C      ROUND_F1_NOEXP(SB, SC, SD, SE, SA, 14)
+C 
+C      ROUND_F1_NOEXP(SA, SB, SC, SD, SE, 15)
+C      ROUND_F1(SE, SA, SB, SC, SD, 16)
+C      ROUND_F1(SD, SE, SA, SB, SC, 17)
+C      ROUND_F1(SC, SD, SE, SA, SB, 18)
+C      ROUND_F1(SB, SC, SD, SE, SA, 19)
+C 
+C      ROUND_F2(SA, SB, SC, SD, SE, 20, K2VALUE)
+C      ROUND_F2(SE, SA, SB, SC, SD, 21, K2VALUE)
+C      ROUND_F2(SD, SE, SA, SB, SC, 22, K2VALUE)
+C      ROUND_F2(SC, SD, SE, SA, SB, 23, K2VALUE)
+C      ROUND_F2(SB, SC, SD, SE, SA, 24, K2VALUE)
+C 
+C      ROUND_F2(SA, SB, SC, SD, SE, 25, K2VALUE)
+C      ROUND_F2(SE, SA, SB, SC, SD, 26, K2VALUE)
+C      ROUND_F2(SD, SE, SA, SB, SC, 27, K2VALUE)
+C      ROUND_F2(SC, SD, SE, SA, SB, 28, K2VALUE)
+C      ROUND_F2(SB, SC, SD, SE, SA, 29, K2VALUE)
+C 
+C      ROUND_F2(SA, SB, SC, SD, SE, 30, K2VALUE)
+C      ROUND_F2(SE, SA, SB, SC, SD, 31, K2VALUE)
+C      ROUND_F2(SD, SE, SA, SB, SC, 32, K2VALUE)
+C      ROUND_F2(SC, SD, SE, SA, SB, 33, K2VALUE)
+C      ROUND_F2(SB, SC, SD, SE, SA, 34, K2VALUE)
+C 
+C      ROUND_F2(SA, SB, SC, SD, SE, 35, K2VALUE)
+C      ROUND_F2(SE, SA, SB, SC, SD, 36, K2VALUE)
+C      ROUND_F2(SD, SE, SA, SB, SC, 37, K2VALUE)
+C      ROUND_F2(SC, SD, SE, SA, SB, 38, K2VALUE)
+C      ROUND_F2(SB, SC, SD, SE, SA, 39, K2VALUE)
+C 
+C      ROUND_F3(SA, SB, SC, SD, SE, 40)
+C      ROUND_F3(SE, SA, SB, SC, SD, 41)
+C      ROUND_F3(SD, SE, SA, SB, SC, 42)
+C      ROUND_F3(SC, SD, SE, SA, SB, 43)
+C      ROUND_F3(SB, SC, SD, SE, SA, 44)
+C 
+C      ROUND_F3(SA, SB, SC, SD, SE, 45)
+C      ROUND_F3(SE, SA, SB, SC, SD, 46)
+C      ROUND_F3(SD, SE, SA, SB, SC, 47)
+C      ROUND_F3(SC, SD, SE, SA, SB, 48)
+C      ROUND_F3(SB, SC, SD, SE, SA, 49)
+C 
+C      ROUND_F3(SA, SB, SC, SD, SE, 50)
+C      ROUND_F3(SE, SA, SB, SC, SD, 51)
+C      ROUND_F3(SD, SE, SA, SB, SC, 52)
+C      ROUND_F3(SC, SD, SE, SA, SB, 53)
+C      ROUND_F3(SB, SC, SD, SE, SA, 54)
+C 
+C      ROUND_F3(SA, SB, SC, SD, SE, 55)
+C      ROUND_F3(SE, SA, SB, SC, SD, 56)
+C      ROUND_F3(SD, SE, SA, SB, SC, 57)
+C      ROUND_F3(SC, SD, SE, SA, SB, 58)
+C      ROUND_F3(SB, SC, SD, SE, SA, 59)
+C 
+C      ROUND_F2(SA, SB, SC, SD, SE, 60, K4VALUE)
+C      ROUND_F2(SE, SA, SB, SC, SD, 61, K4VALUE)
+C      ROUND_F2(SD, SE, SA, SB, SC, 62, K4VALUE)
+C      ROUND_F2(SC, SD, SE, SA, SB, 63, K4VALUE)
+C      ROUND_F2(SB, SC, SD, SE, SA, 64, K4VALUE)
+C 
+C      ROUND_F2(SA, SB, SC, SD, SE, 65, K4VALUE)
+C      ROUND_F2(SE, SA, SB, SC, SD, 66, K4VALUE)
+C      ROUND_F2(SD, SE, SA, SB, SC, 67, K4VALUE)
+C      ROUND_F2(SC, SD, SE, SA, SB, 68, K4VALUE)
+C      ROUND_F2(SB, SC, SD, SE, SA, 69, K4VALUE)
+C 
+C      ROUND_F2(SA, SB, SC, SD, SE, 70, K4VALUE)
+C      ROUND_F2(SE, SA, SB, SC, SD, 71, K4VALUE)
+C      ROUND_F2(SD, SE, SA, SB, SC, 72, K4VALUE)
+C      ROUND_F2(SC, SD, SE, SA, SB, 73, K4VALUE)
+C      ROUND_F2(SB, SC, SD, SE, SA, 74, K4VALUE)
+C 
+C      ROUND_F2(SA, SB, SC, SD, SE, 75, K4VALUE)
+C      ROUND_F2(SE, SA, SB, SC, SD, 76, K4VALUE)
+C      ROUND_F2(SD, SE, SA, SB, SC, 77, K4VALUE)
+C      ROUND_F2(SC, SD, SE, SA, SB, 78, K4VALUE)
+C      ROUND_F2(SB, SC, SD, SE, SA, 79, K4VALUE)
+
+       C Update the state vector
+       movl    84(%esp),T1
+       addl    SA, (T1) 
+       addl    SB, 4(T1) 
+       addl    SC, 8(T1) 
+       addl    SD, 12(T1) 
+       addl    SE, 16(T1)
+
+       addl    $64, %esp
+       popl    %edi
+       popl    %esi
+       popl    %ebp
+       popl    %ebx
+       ret
+EPILOGUE(_nettle_sha1_compress)
+
+C TODO:
+
+C * Extend loopmixer so that it can exploit associativity, and for
+C   example reorder
+C
+C      add     %eax, %ebx
+C      add     %ecx, %ebx
+
+C * Use mmx instructions for the data expansion, doing two words at a
+C   time.
diff --git a/x86_64/aes-decrypt-internal.asm b/x86_64/aes-decrypt-internal.asm
new file mode 100644 (file)
index 0000000..8f0df73
--- /dev/null
@@ -0,0 +1,133 @@
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2001, 2002, 2005, 2008 Rafael R. Sevilla, Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+include_src(<x86_64/aes.m4>)
+
+C Register usage:
+
+C AES state, use two of them
+define(<SA>,<%eax>)
+define(<SB>,<%ebx>)
+define(<SC>,<%ecx>)
+define(<SD>,<%edx>)
+
+define(<TA>,<%r10d>)
+define(<TB>,<%r11d>)
+define(<TC>,<%r12d>)
+
+define(<CTX>,  <%rdi>)
+define(<TABLE>,        <%rsi>)
+define(<PARAM_LENGTH>,<%edx>)          C Length is only 32 bits
+define(<PARAM_DST>,    <%rcx>)
+define(<SRC>,  <%r8>)
+
+define(<DST>, <%r9>) 
+define(<KEY>,<%r14>)
+define(<COUNT>,        <%r15d>)
+define(<BLOCK_COUNT>, <%r13d>)
+
+C Must correspond to an old-style register, for movzb from %ah--%dh to
+C work.
+define(<TMP>,<%rbp>)
+
+       .file "aes-decrypt-internal.asm"
+       
+       C _aes_decrypt(struct aes_context *ctx, 
+       C              const struct aes_table *T,
+       C              unsigned length, uint8_t *dst,
+       C              uint8_t *src)
+       .text
+       ALIGN(4)
+PROLOGUE(_nettle_aes_decrypt)
+       test    PARAM_LENGTH, PARAM_LENGTH
+       jz      .Lend
+
+        C save all registers that need to be saved
+       push    %rbx
+       push    %rbp
+       push    %r12
+       push    %r13
+       push    %r14
+       push    %r15    
+
+       mov     PARAM_DST, DST
+       movl    PARAM_LENGTH, BLOCK_COUNT
+       shrl    $4, BLOCK_COUNT
+.Lblock_loop:
+       mov     CTX,KEY
+       
+       AES_LOAD(SA, SB, SC, SD, SRC, KEY)
+       add     $16, SRC        C Increment src pointer
+
+       C  get number of rounds to do from ctx struct   
+       movl    AES_NROUNDS (CTX), COUNT
+       subl    $1, COUNT
+
+       add     $16,KEY         C  point to next key
+       ALIGN(4)
+.Lround_loop:
+       AES_ROUND(TABLE, SA,SD,SC,SB, TA, TMP)
+       AES_ROUND(TABLE, SB,SA,SD,SC, TB, TMP)
+       AES_ROUND(TABLE, SC,SB,SA,SD, TC, TMP)
+       AES_ROUND(TABLE, SD,SC,SB,SA, SD, TMP)
+
+       movl    TA, SA
+       movl    TB, SB
+       movl    TC, SC
+
+       xorl    (KEY),SA        C  add current session key to plaintext
+       xorl    4(KEY),SB
+       xorl    8(KEY),SC
+       xorl    12(KEY),SD
+
+       add     $16,KEY C  point to next key
+       decl    COUNT
+       jnz     .Lround_loop
+
+       C last round
+       AES_FINAL_ROUND(SA,SD,SC,SB, TABLE, TA, TMP)
+       AES_FINAL_ROUND(SB,SA,SD,SC, TABLE, TB, TMP)
+       AES_FINAL_ROUND(SC,SB,SA,SD, TABLE, TC, TMP)
+       AES_FINAL_ROUND(SD,SC,SB,SA, TABLE, SD, TMP)
+
+       C Inverse S-box substitution
+       mov     $3, COUNT
+.Lsubst:
+       AES_SUBST_BYTE(TA,TB,TC,SD, TABLE, TMP)
+
+       decl    COUNT
+       jnz     .Lsubst
+
+       C Add last subkey, and store decrypted data
+       AES_STORE(TA,TB,TC,SD, KEY, DST)
+       
+       add     $16, DST
+       decl    BLOCK_COUNT
+
+       jnz     .Lblock_loop
+
+       pop     %r15    
+       pop     %r14
+       pop     %r13
+       pop     %r12
+       pop     %rbp
+       pop     %rbx
+.Lend:
+       ret
+EPILOGUE(_nettle_aes_decrypt)
diff --git a/x86_64/aes-encrypt-internal.asm b/x86_64/aes-encrypt-internal.asm
new file mode 100644 (file)
index 0000000..c23feb6
--- /dev/null
@@ -0,0 +1,133 @@
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2001, 2002, 2005, 2008 Rafael R. Sevilla, Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+include_src(<x86_64/aes.m4>)
+
+C Register usage:
+
+C AES state, use two of them
+define(<SA>,<%eax>)
+define(<SB>,<%ebx>)
+define(<SC>,<%ecx>)
+define(<SD>,<%edx>)
+
+define(<TA>,<%r10d>)
+define(<TB>,<%r11d>)
+define(<TC>,<%r12d>)
+
+define(<CTX>,  <%rdi>)
+define(<TABLE>,        <%rsi>)
+define(<PARAM_LENGTH>,<%edx>)          C Length is only 32 bits
+define(<PARAM_DST>,    <%rcx>)
+define(<SRC>,  <%r8>)
+
+define(<DST>, <%r9>) 
+define(<KEY>,<%r14>)
+define(<COUNT>,        <%r15d>)
+define(<BLOCK_COUNT>, <%r13d>)
+
+C Must correspond to an old-style register, for movzb from %ah--%dh to
+C work.
+define(<TMP>,<%rbp>)
+
+       .file "aes-encrypt-internal.asm"
+       
+       C _aes_encrypt(struct aes_context *ctx, 
+       C              const struct aes_table *T,
+       C              unsigned length, uint8_t *dst,
+       C              uint8_t *src)
+       .text
+       ALIGN(4)
+PROLOGUE(_nettle_aes_encrypt)
+       test    PARAM_LENGTH, PARAM_LENGTH
+       jz      .Lend
+
+        C save all registers that need to be saved
+       push    %rbx
+       push    %rbp
+       push    %r12
+       push    %r13
+       push    %r14
+       push    %r15    
+
+       mov     PARAM_DST, DST
+       movl    PARAM_LENGTH, BLOCK_COUNT
+       shrl    $4, BLOCK_COUNT
+.Lblock_loop:
+       mov     CTX,KEY
+       
+       AES_LOAD(SA, SB, SC, SD, SRC, KEY)
+       add     $16, SRC        C Increment src pointer
+
+       C  get number of rounds to do from ctx struct   
+       movl    AES_NROUNDS (CTX), COUNT
+       subl    $1, COUNT
+
+       add     $16,KEY         C  point to next key
+       ALIGN(4)
+.Lround_loop:
+       AES_ROUND(TABLE, SA,SB,SC,SD, TA, TMP)
+       AES_ROUND(TABLE, SB,SC,SD,SA, TB, TMP)
+       AES_ROUND(TABLE, SC,SD,SA,SB, TC, TMP)
+       AES_ROUND(TABLE, SD,SA,SB,SC, SD, TMP)
+
+       movl    TA, SA
+       movl    TB, SB
+       movl    TC, SC
+
+       xorl    (KEY),SA        C  add current session key to plaintext
+       xorl    4(KEY),SB
+       xorl    8(KEY),SC
+       xorl    12(KEY),SD
+
+       add     $16,KEY C  point to next key
+       decl    COUNT
+       jnz     .Lround_loop
+
+       C last round
+       AES_FINAL_ROUND(SA,SB,SC,SD, TABLE, TA, TMP)
+       AES_FINAL_ROUND(SB,SC,SD,SA, TABLE, TB, TMP)
+       AES_FINAL_ROUND(SC,SD,SA,SB, TABLE, TC, TMP)
+       AES_FINAL_ROUND(SD,SA,SB,SC, TABLE, SD, TMP)
+
+       C S-box substitution
+       mov     $3, COUNT
+.Lsubst:
+       AES_SUBST_BYTE(TA,TB,TC,SD, TABLE, TMP)
+
+       decl    COUNT
+       jnz     .Lsubst
+
+       C Add last subkey, and store encrypted data
+       AES_STORE(TA,TB,TC,SD, KEY, DST)
+       
+       add     $16, DST
+       decl    BLOCK_COUNT
+
+       jnz     .Lblock_loop
+
+       pop     %r15    
+       pop     %r14
+       pop     %r13
+       pop     %r12
+       pop     %rbp
+       pop     %rbx
+.Lend:
+       ret
+EPILOGUE(_nettle_aes_encrypt)
diff --git a/x86_64/aes.m4 b/x86_64/aes.m4
new file mode 100644 (file)
index 0000000..8034f77
--- /dev/null
@@ -0,0 +1,130 @@
+dnl LREG(reg) gives the 8-bit register corresponding to the given 32-bit register.
+define(<LREG>,<ifelse(
+       $1, %eax, %al,
+       $1, %ebx, %bl,
+       $1, %ecx, %cl,
+       $1, %edx, %dl,
+       $1, %esi, %sil,
+       $1, %edi, %dil,
+       $1, %ebp, %bpl,
+       $1, %esp, %spl,
+       $1, %r8d, %r8b,
+       $1, %r9d, %r9b,
+       $1, %r10d, %r10b,
+       $1, %r11d, %r11b,
+       $1, %r12d, %r12b,
+       $1, %r13d, %r13b,
+       $1, %r14d, %r14b,
+       $1, %r15d, %r15b)>)dnl
+
+define(<HREG>,<ifelse(
+       $1, %eax, %ah,
+       $1, %ebx, %bh,
+       $1, %ecx, %ch,
+       $1, %edx, %dh,
+       error)>)
+
+define(<XREG>,<ifelse(
+       $1, %rax, %eax,
+       $1, %rbx, %ebx,
+       $1, %rcx, %ecx,
+       $1, %rdx, %edx,
+       $1, %rsi, %esi,
+       $1, %rdi, %edi,
+       $1, %rbp, %ebp,
+       $1, %rsp, %esp,
+       $1, %r8, %r8d,
+       $1, %r9, %r9d,
+       $1, %r10,%r10d,
+       $1, %r11,%r11d,
+       $1, %r12,%r12d,
+       $1, %r13,%r13d,
+       $1, %r14,%r14d,
+       $1, %r15,%r15d)>)dnl
+
+dnl AES_LOAD(a, b, c, d, src, key)
+dnl Loads the next block of data from src, and add the subkey pointed
+dnl to by key.
+dnl Note that x86 allows unaligned accesses.
+dnl Would it be preferable to interleave the loads and stores?
+define(<AES_LOAD>, <
+       movl    ($5),$1
+       movl    4($5),$2
+       movl    8($5),$3
+       movl    12($5),$4
+       
+       xorl    ($6),$1
+       xorl    4($6),$2
+       xorl    8($6),$3
+       xorl    12($6),$4>)dnl
+
+dnl AES_STORE(a, b, c, d, key, dst)
+dnl Adds the subkey to a, b, c, d,
+dnl and stores the result in the area pointed to by dst.
+dnl Note that x86 allows unaligned accesses.
+dnl Would it be preferable to interleave the loads and stores?
+define(<AES_STORE>, <
+       xorl    ($5),$1
+       xorl    4($5),$2
+       xorl    8($5),$3
+       xorl    12($5),$4
+
+       movl    $1,($6)
+       movl    $2,4($6)
+       movl    $3,8($6)
+       movl    $4,12($6)>)dnl
+
+dnl AES_ROUND(table,a,b,c,d,out,ptr)
+dnl Computes one word of the AES round. Leaves result in $6.
+define(<AES_ROUND>, <
+       movzb   LREG($2), $7
+       movl    AES_TABLE0 ($1, $7, 4),$6
+       movzb   HREG($3), XREG($7)
+       xorl    AES_TABLE1 ($1, $7, 4),$6
+       movl    $4,XREG($7)
+       shr     <$>16,$7
+       and     <$>0xff,$7
+       xorl    AES_TABLE2 ($1, $7, 4),$6
+       movl    $5,XREG($7)
+       shr     <$>24,$7
+       xorl    AES_TABLE3 ($1, $7, 4),$6>)dnl
+
+dnl AES_FINAL_ROUND(a, b, c, d, table, out, tmp)
+dnl Computes one word of the final round. Leaves result in $6. Also
+dnl performs the first substitution step, on the least significant
+dnl byte, and rotates 8 bits.
+define(<AES_FINAL_ROUND>, <
+       movzb   LREG($1),$7
+       movzbl  ($5, $7), $6
+       movl    $2,XREG($7)
+       andl    <$>0x0000ff00,XREG($7)
+       orl     XREG($7), $6
+       movl    $3,XREG($7)
+       andl    <$>0x00ff0000,XREG($7)
+       orl     XREG($7), $6
+       movl    $4,XREG($7)
+       andl    <$>0xff000000,XREG($7)
+       orl     XREG($7), $6
+       roll    <$>8, $6>)dnl
+
+dnl AES_SUBST_BYTE(A, B, C, D, table, tmp)
+dnl Substitutes the least significant byte of
+dnl each of eax, ebx, ecx and edx, and also rotates
+dnl the words one byte to the left.
+dnl Uses that AES_SBOX == 0
+define(<AES_SUBST_BYTE>, <
+       movzb   LREG($1),$6
+       movb    ($5, $6),LREG($1)
+       roll    <$>8,$1
+
+       movzb  LREG($2),$6
+       movb    ($5, $6),LREG($2)
+       roll    <$>8,$2
+
+       movzb  LREG($3),$6
+       movb    ($5, $6),LREG($3)
+       roll    <$>8,$3
+
+       movzb  LREG($4),$6
+       movb    ($5, $6),LREG($4)
+       roll    <$>8,$4>)dnl
diff --git a/x86_64/arcfour-crypt.asm b/x86_64/arcfour-crypt.asm
new file mode 100644 (file)
index 0000000..92aa147
--- /dev/null
@@ -0,0 +1,69 @@
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2004, Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+define(<CTX>, <%rdi>)
+define(<N>, <%rsi>)
+define(<DST>, <%rdx>)
+define(<SRC>, <%rcx>)
+
+define(<I>, <%rax>)
+define(<J>, <%r8>)
+define(<SI>, <%r9>)
+define(<SJ>, <%r10>)
+
+       .file "arcfour-crypt.asm"
+
+       C arcfour_crypt(struct arcfour_ctx *ctx,
+       C               unsigned length, uint8_t *dst,
+       C               const uint8_t *src)
+       .text
+       ALIGN(4)
+PROLOGUE(nettle_arcfour_crypt)
+       C Offset pointers at end of areas
+       lea     (SRC, N), SRC
+       lea     (DST, N), DST
+       neg     N
+       jnc     .Ldone
+       
+       movzbl  256(CTX), XREG(I)
+       movzbl  257(CTX), XREG(J)
+
+       ALIGN(4)
+.Loop:
+       add     $1, XREG(I)
+       movzbl  LREG(I), XREG(I)
+       movzbl  (CTX, I), XREG(SI)
+       add     XREG(SI), XREG(J)
+       movzbl  LREG(J), XREG(J)
+       movzbl  (CTX, J), XREG(SJ)
+       mov     LREG(SI), (CTX, J)
+       mov     LREG(SJ), (CTX, I)
+       add     XREG(SI), XREG(SJ)
+       movzbl  LREG(SJ), XREG(SJ)
+       mov     (CTX, SJ), LREG(SI)
+       xor     (SRC, N), LREG(SI)
+       mov     LREG(SI), (DST, N)
+       add     $1, N
+       jnz     .Loop
+       
+       movb    LREG(I), 256(CTX)
+       movb    LREG(J), 257(CTX)
+.Ldone:
+       ret
+EPILOGUE(nettle_arcfour_crypt)
diff --git a/x86_64/camellia-crypt-internal.asm b/x86_64/camellia-crypt-internal.asm
new file mode 100644 (file)
index 0000000..e940342
--- /dev/null
@@ -0,0 +1,186 @@
+C -*- mode: asm; asm-comment-char: ?C; -*-  
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2010, Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+C Performance, cycles per block
+C
+C              Intel SU4100
+C                 C  asm
+C Camellia-128  415  347
+C Camellia-256  543  461
+
+C Register usage:
+
+define(<CTX>, <%rdi>)
+define(<TABLE>, <%rsi>)
+define(<LENGTH>, <%rdx>)
+define(<DST>, <%rcx>)
+define(<SRC>, <%r8>)
+
+C Camellia state
+define(<I0>, <%rax>)
+define(<I1>, <%rbx>) C callee-save
+define(<KEY>, <%r9>)
+define(<TMP>, <%rbp>) C callee-save
+define(<CNT>, <%r10>)
+define(<IL>,  <%r11>)
+define(<IR>,  <%r12>) C callee-save
+
+define(<SP1110>, <(TABLE,$1,4)>)
+define(<SP0222>, <1024(TABLE,$1,4)>)
+define(<SP3033>, <2048(TABLE,$1,4)>)
+define(<SP4404>, <3072(TABLE,$1,4)>)
+
+C ROUND(x, y, key-offset)
+define(<ROUND>, <
+       C Byte 0,1
+       movzbl  LREG($1), XREG(TMP)
+       movl    SP1110(TMP), XREG(IR)
+       movzbl  HREG($1), XREG(TMP)
+       xorl    SP4404(TMP), XREG(IR)
+       ror     <$>32, $1
+
+       C Byte 4,5
+       movzbl  LREG($1), XREG(TMP)
+       movl    SP4404(TMP), XREG(IL)
+       movzbl  HREG($1), XREG(TMP)
+       xorl    SP3033(TMP), XREG(IL)
+       rol     <$>16, $1
+
+       C Byte 2,3
+       movzbl  LREG($1), XREG(TMP)
+       xorl    SP3033(TMP), XREG(IR)
+       movzbl  HREG($1), XREG(TMP)
+       xorl    SP0222(TMP), XREG(IR)
+       ror     <$>32, $1
+
+       C Byte 6,7
+       movzbl  LREG($1), XREG(TMP)
+       xorl    SP0222(TMP), XREG(IL)
+       movzbl  HREG($1), XREG(TMP)
+       xorl    SP1110(TMP), XREG(IL)
+       ror     <$>16, $1
+
+       C 76543210
+       
+       xorl    XREG(IL), XREG(IR)
+       rorl    <$>8, XREG(IL)
+       xorl    XREG(IR), XREG(IL)
+       shl     <$>32, IR
+       or      IL, IR
+       xor     $3(KEY), $2
+       xor     IR, $2
+>)
+
+C FL(x, key-offset)
+define(<FL>, <
+       mov     $1, TMP
+       shr     <$>32, TMP
+       andl    $2 + 4(KEY), XREG(TMP)
+       roll    <$>1, XREG(TMP)
+C      xorl    XREG(TMP), XREG($1)
+       xor     TMP, $1
+       movl    $2(KEY), XREG(TMP)
+       orl     XREG($1), XREG(TMP)
+       shl     <$>32, TMP
+       xor     TMP, $1
+>)
+C FLINV(x0, key-offset)
+define(<FLINV>, <
+       movl    $2(KEY), XREG(TMP)
+       orl     XREG($1), XREG(TMP)
+       shl     <$>32, TMP
+       xor     TMP, $1
+       mov     $1, TMP
+       shr     <$>32, TMP
+       andl    $2 + 4(KEY), XREG(TMP)
+       roll    <$>1, XREG(TMP)
+C      xorl    XREG(TMP), XREG($1)
+       xor     TMP, $1 
+>)
+
+       .file "camellia-encrypt-internal.asm"
+       
+       C _camellia_crypt(struct camellia_context *ctx, 
+       C                 const struct camellia_table *T,
+       C                 unsigned length, uint8_t *dst,
+       C                 uint8_t *src)
+       .text
+       ALIGN(4)
+PROLOGUE(_nettle_camellia_crypt)
+
+       test    LENGTH, LENGTH
+       jz      .Lend
+
+       push    %rbx
+       push    %rbp
+       push    %r12
+       
+.Lblock_loop:
+       C Load data, note that we'll happily do unaligned loads
+       mov     (SRC), I0
+       bswap   I0
+       mov     8(SRC), I1
+       bswap   I1
+       add     $16, SRC
+       mov     CTX, KEY
+       movl    (KEY), XREG(CNT)
+       sub     $8, CNT
+
+       C       Whitening using first subkey 
+       xor     8(KEY), I0
+       add     $16, KEY
+
+       ROUND(I0, I1, 0)
+       ROUND(I1, I0, 8)
+       ROUND(I0, I1, 16)
+       ROUND(I1, I0, 24)
+       ROUND(I0, I1, 32) 
+       ROUND(I1, I0, 40)
+       
+.Lround_loop:
+       add     $64, KEY
+       FL(I0, -16)
+       FLINV(I1, -8)
+       ROUND(I0, I1, 0)
+       ROUND(I1, I0, 8)
+       ROUND(I0, I1, 16)
+       ROUND(I1, I0, 24)
+       ROUND(I0, I1, 32) 
+       ROUND(I1, I0, 40)
+
+       sub     $8, CNT 
+       ja      .Lround_loop
+
+       bswap   I0
+       mov     I0, 8(DST)
+       xor     48(KEY), I1
+       bswap   I1
+       mov     I1, (DST)
+       add     $16, DST
+       sub     $16, LENGTH
+
+       ja      .Lblock_loop
+
+       pop     %r12
+       pop     %rbp
+       pop     %rbx
+.Lend:
+       ret
+EPILOGUE(_nettle_camellia_crypt)
diff --git a/x86_64/machine.m4 b/x86_64/machine.m4
new file mode 100644 (file)
index 0000000..e3b3824
--- /dev/null
@@ -0,0 +1,44 @@
+C OFFSET(i)
+C Expands to 4*i, or to the empty string if i is zero
+define(<OFFSET>, <ifelse($1,0,,eval(4*$1))>)
+
+dnl LREG(reg) gives the 8-bit register corresponding to the given 64-bit register.
+define(<LREG>,<ifelse(
+       $1, %rax, %al,
+       $1, %rbx, %bl,
+       $1, %rcx, %cl,
+       $1, %rdx, %dl,
+       $1, %rsi, %sil,
+       $1, %rdi, %dil,
+       $1, %rbp, %bpl,
+       $1, %r8, %r8b,
+       $1, %r9, %r9b,
+       $1, %r10, %r10b,
+       $1, %r11, %r11b,
+       $1, %r12, %r12b,
+       $1, %r13, %r13b,
+       $1, %r14, %r14b,
+       $1, %r15, %r15b)>)dnl
+
+define(<HREG>,<ifelse(
+       $1, %rax, %ah,
+       $1, %rbx, %bh,
+       $1, %rcx, %ch,
+       $1, %rdx, %dh)>)dnl
+
+define(<XREG>,<ifelse(
+       $1, %rax, %eax,
+       $1, %rbx, %ebx,
+       $1, %rcx, %ecx,
+       $1, %rdx, %edx,
+       $1, %rsi, %esi,
+       $1, %rdi, %edi,
+       $1, %rbp, %ebp,
+       $1, %r8, %r8d,
+       $1, %r9, %r9d,
+       $1, %r10, %r10d,
+       $1, %r11, %r11d,
+       $1, %r12, %r12d,
+       $1, %r13, %r13d,
+       $1, %r14, %r14d,
+       $1, %r15, %r15d)>)dnl
diff --git a/x86_64/memxor.asm b/x86_64/memxor.asm
new file mode 100644 (file)
index 0000000..d9b05b1
--- /dev/null
@@ -0,0 +1,212 @@
+C -*- mode: asm; asm-comment-char: ?C; -*-  
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2010, Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+C Register usage:
+define(<DST>, <%rax>) C Originally in %rdi
+define(<AP>, <%rsi>)
+define(<BP>, <%rdx>)
+define(<N>, <%r10>)
+define(<TMP>, <%r8>)
+define(<TMP2>, <%r9>)
+define(<CNT>, <%rdi>)
+define(<S0>, <%r11>)
+define(<S1>, <%rdi>) C Overlaps with CNT 
+       
+       .file "memxor.asm"
+
+       .text
+
+       C memxor(uint8_t *dst, const uint8_t *src, size_t n)
+       C                 %rdi               %rsi      %rdx
+       ALIGN(4)
+
+PROLOGUE(memxor)
+       mov     %rdx, %r10
+       mov     %rdi, %rdx
+       jmp     .Lmemxor3_entry
+EPILOGUE(memxor)
+
+       C memxor3(uint8_t *dst, const uint8_t *a, const uint8_t *b, size_t n)
+       C                 %rdi              %rsi              %rdx      %rcx
+       ALIGN(4)
+       
+PROLOGUE(memxor3)
+       C %cl needed for shift count, so move away N
+       mov     %rcx, N
+.Lmemxor3_entry:
+       test    N, N
+       C Get number of unaligned bytes at the end
+       C %rdi is used as CNT, %rax as DST and as return value
+       mov     %rdi, %rax
+       jz      .Ldone
+       add     N, CNT
+       and     $7, CNT
+       
+       jz      .Laligned
+
+       cmp     $8, N
+       jc      .Lfinal_next
+
+       C FIXME: Instead of this loop, could try cmov with memory
+       C destination, as a sequence of one 8-bit, one 16-bit and one
+       C 32-bit operations. (Except that cmov can't do 8-bit ops, so
+       C that step has to use a conditional).
+.Lalign_loop:
+       
+       sub     $1, N
+       movb    (AP, N), LREG(TMP)
+       xorb    (BP, N), LREG(TMP)
+       movb    LREG(TMP), (DST, N)
+       sub     $1, CNT
+       jnz     .Lalign_loop
+
+.Laligned:
+       C Check for the case that AP and BP have the same alignment,
+       C but different from DST.
+       mov     AP, TMP
+       sub     BP, TMP
+       test    $7, TMP
+       jnz     .Lno_shift_case
+       mov     AP, %rcx
+       sub     DST, %rcx
+       and     $7, %rcx
+       jz      .Lno_shift_case
+       sub     %rcx, AP
+       sub     %rcx, BP
+       shl     $3, %rcx
+
+       C Unrolling, with aligned values alternating in S0 and S1
+       test    $8, N
+       jnz     .Lshift_odd
+       mov     (AP, N), S1
+       xor     (BP, N), S1
+       jmp     .Lshift_next
+
+.Lshift_odd:
+       mov     -8(AP, N), S1
+       mov     (AP, N), S0
+       xor     -8(BP, N), S1
+       xor     (BP, N), S0
+       mov     S1, TMP
+       shr     %cl, TMP
+       neg     %cl
+       shl     %cl, S0
+       neg     %cl
+       
+       or      S0, TMP
+       mov     TMP, -8(DST, N)
+       sub     $8, N
+       jz      .Ldone
+       jmp     .Lshift_next
+
+       ALIGN(4)
+
+.Lshift_loop:
+       mov     8(AP, N), S0
+       xor     8(BP, N), S0
+       mov     S0, TMP
+       shr     %cl, TMP
+       neg     %cl
+       shl     %cl, S1
+       neg     %cl
+       or      S1, TMP
+       mov     TMP, 8(DST, N)
+
+       mov     (AP, N), S1
+       xor     (BP, N), S1
+       mov     S1, TMP
+       shr     %cl, TMP
+       neg     %cl
+       shl     %cl, S0
+       neg     %cl
+       or      S0, TMP
+       mov     TMP, (DST, N)
+.Lshift_next:
+       sub     $16, N
+       C FIXME: Handle the case N == 16 specially,
+       C like in the non-shifted case? 
+C      ja      .Lshift_loop
+C      jz      .Ldone
+       jnc     .Lshift_loop
+
+       add     $15, N
+       jnc     .Ldone
+
+       shr     $3, %rcx
+       add     %rcx, AP
+       add     %rcx, BP
+       jmp     .Lfinal_loop
+       
+.Lno_shift_case:
+       C Next destination word is -8(DST, N)
+       C Setup for unrolling
+       test    $8, N
+       jz      .Lword_next
+
+       sub     $8, N
+       jz      .Lone_word
+
+       mov     (AP, N), TMP
+       xor     (BP, N), TMP
+       mov     TMP, (DST, N)
+       
+       jmp     .Lword_next
+
+       ALIGN(4)
+
+.Lword_loop:
+       mov     8(AP, N), TMP
+       mov     (AP, N), TMP2
+       xor     8(BP, N), TMP
+       xor     (BP, N), TMP2
+       mov     TMP, 8(DST, N)
+       mov     TMP2, (DST, N)
+
+.Lword_next:
+       sub     $16, N
+       ja      .Lword_loop     C Not zero and no carry
+       jnz     .Lfinal
+
+       C Final operation is word aligned
+       mov     8(AP, N), TMP
+       xor     8(BP, N), TMP
+       mov     TMP, 8(DST, N)
+       
+.Lone_word:
+       mov     (AP, N), TMP
+       xor     (BP, N), TMP
+       mov     TMP, (DST, N)
+
+       ret
+
+.Lfinal:
+       add     $15, N
+
+.Lfinal_loop:
+       movb    (AP, N), LREG(TMP)
+       xorb    (BP, N), LREG(TMP)
+       movb    LREG(TMP), (DST, N)
+.Lfinal_next:
+       sub     $1, N
+       jnc     .Lfinal_loop
+
+.Ldone:
+       ret
+EPILOGUE(memxor3)
diff --git a/x86_64/serpent-decrypt.asm b/x86_64/serpent-decrypt.asm
new file mode 100644 (file)
index 0000000..b2bca66
--- /dev/null
@@ -0,0 +1,700 @@
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2011 Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+include_src(<x86_64/serpent.m4>)
+
+C Register usage:
+
+C Single block serpent state, two copies
+define(<x0>, <%eax>)
+define(<x1>, <%ebx>)
+define(<x2>, <%ebp>)
+define(<x3>, <%r8d>)
+
+define(<y0>, <%r9d>)
+define(<y1>, <%r10d>)
+define(<y2>, <%r11d>)
+define(<y3>, <%r12d>)
+
+C Quadruple block serpent state, two copies
+define(<X0>, <%xmm0>)
+define(<X1>, <%xmm1>)
+define(<X2>, <%xmm2>)
+define(<X3>, <%xmm3>)
+
+define(<Y0>, <%xmm4>)
+define(<Y1>, <%xmm5>)
+define(<Y2>, <%xmm6>)
+define(<Y3>, <%xmm7>)
+
+define(<MINUS1>, <%xmm8>)
+define(<T0>, <%xmm9>)
+define(<T1>, <%xmm10>)
+define(<T2>, <%xmm11>)
+define(<T3>, <%xmm12>)
+
+C Arguments
+define(<CTX>, <%rdi>)
+define(<N>, <%rsi>)
+define(<DST>, <%rdx>)
+define(<SRC>, <%rcx>)
+
+define(<CNT>, <%r13>)
+define(<TMP32>, <%r14d>)
+
+C SBOX macros. Inputs $1 - $4 (destroyed), outputs $5 - $8
+
+define(<SBOX0I>, <
+       mov     $1, $5
+       xor     $3, $5
+       mov     $1, $7
+       or      $2, $7
+       mov     $3, $6
+       xor     $4, $6
+       xor     $6, $7
+       and     $3, $6
+       or      $2, $3
+       xor     $4, $2
+       or      $1, $6
+       and     $3, $2
+       xor     $2, $6
+       or      $7, $1
+       xor     $6, $1
+       mov     $7, $2
+       and     $1, $2
+       not     $7
+       or      $7, $4
+       xor     $3, $4
+       mov     $1, $8
+       xor     $4, $8
+       or      $4, $2
+       xor     $2, $5
+>)
+
+define(<SBOX1I>, <
+       mov     $2, $6
+       or      $4, $6
+       xor     $3, $6
+       mov     $1, $8
+       xor     $2, $8
+       mov     $1, $5
+       or      $6, $5
+       and     $8, $5
+       xor     $5, $2
+       xor     $6, $8
+       and     $4, $2
+       mov     $1, $7
+       and     $3, $7
+       or      $7, $6
+       or      $4, $7
+       xor     $5, $7
+       not     $7
+       xor     $2, $6
+       xor     $6, $5
+       xor     $3, $5
+       or      $7, $1
+       xor     $1, $5
+>)
+
+define(<SBOX2I>, <
+       mov     $1, $5
+       xor     $4, $5
+       mov     $3, $7
+       xor     $4, $7
+       mov     $2, $6
+       or      $7, $6
+       xor     $6, $5
+       mov     $4, $6
+       or      $5, $6
+       and     $2, $6
+       not     $4
+       mov     $1, $8
+       or      $3, $8
+       and     $8, $7
+       xor     $7, $6
+       and     $2, $8
+       and     $3, $1
+       or      $4, $1
+       xor     $1, $8
+       and     $8, $3
+       xor     $1, $3
+       mov     $5, $7
+       xor     $6, $7
+       xor     $3, $7
+>)
+
+define(<SBOX3I>, <
+       mov     $3, $8
+       or      $4, $8
+       mov     $2, $5
+       and     $8, $5
+       mov     $1, $7
+       or      $4, $7
+       mov     $3, $6
+       xor     $7, $6
+       xor     $6, $5
+       xor     $1, $4
+       xor     $4, $8
+       xor     $2, $7
+       and     $6, $7
+       xor     $4, $7
+       xor     $1, $6
+       or      $5, $4
+       and     $4, $6
+       xor     $2, $6
+       and     $7, $1
+       or      $2, $1
+       xor     $1, $8
+>)
+
+define(<SBOX4I>, <
+       mov     $3, $6
+       xor     $4, $6
+       mov     $3, $7
+       or      $4, $7
+       xor     $2, $7
+       or      $4, $2
+       mov     $1, $5
+       xor     $7, $5
+       xor     $7, $4
+       and     $1, $7
+       xor     $7, $6
+       xor     $1, $7
+       or      $3, $7
+       and     $2, $1
+       mov     $1, $8
+       xor     $4, $8
+       not     $1
+       or      $6, $1
+       xor     $1, $5
+       xor     $2, $1
+       xor     $1, $7
+>)
+
+define(<SBOX5I>, <
+       mov     $1, $6
+       and     $4, $6
+       mov     $3, $8
+       xor     $6, $8
+       mov     $2, $5
+       and     $8, $5
+       mov     $1, $7
+       xor     $4, $7
+       xor     $2, $4
+       xor     $7, $5
+       and     $1, $3
+       and     $5, $1
+       or      $2, $3
+       xor     $5, $6
+       xor     $3, $6
+       mov     $5, $7
+       or      $6, $7
+       xor     $8, $7
+       xor     $4, $7
+       not     $2
+       or      $1, $2
+       xor     $2, $8
+>)
+
+define(<SBOX6I>, <
+       mov     $1, $7
+       xor     $3, $7
+       not     $3
+       mov     $2, $5
+       xor     $4, $5
+       mov     $1, $6
+       or      $3, $6
+       xor     $5, $6
+       mov     $2, $8
+       and     $7, $8
+       or      $4, $8
+       or      $3, $4
+       or      $2, $3
+       and     $1, $3
+       mov     $3, $5
+       xor     $8, $5
+       not     $5
+       and     $7, $8
+       xor     $3, $8
+       xor     $6, $1
+       xor     $1, $8
+       and     $5, $2
+       xor     $2, $7
+       xor     $4, $7
+>)
+
+define(<SBOX7I>, <
+       mov     $1, $8
+       and     $2, $8
+       mov     $2, $7
+       xor     $4, $7
+       or      $8, $7
+       mov     $1, $6
+       or      $4, $6
+       and     $3, $6
+       xor     $6, $7
+       or      $3, $8
+       mov     $1, $5
+       or      $2, $5
+       and     $4, $5
+       xor     $5, $8
+       xor     $2, $5
+       mov     $4, $6
+       xor     $8, $6
+       not     $6
+       or      $5, $6
+       xor     $3, $5
+       xor     $1, $6
+       or      $6, $4
+       xor     $4, $5
+>)
+
+define(<LTI>, <
+       rol     <$>10, $3
+       rol     <$>27, $1
+       mov     $2, TMP32
+       shl     <$>7, TMP32
+       xor     $4, $3
+       xor     TMP32, $3
+       xor     $2, $1
+       xor     $4, $1
+       rol     <$>25, $4
+       rol     <$>31, $2
+       mov     $1, TMP32
+       shl     <$>3, TMP32
+       xor     $3, $4
+       xor     TMP32, $4
+       xor     $1, $2
+       xor     $3, $2
+       rol     <$>29, $3
+       rol     <$>19, $1
+>)
+
+define(<PNOT>, <
+       pxor    MINUS1, $1
+>)
+
+define(<WSBOX0I>, <
+       movdqa  $1, $5
+       pxor    $3, $5
+       movdqa  $1, $7
+       por     $2, $7
+       movdqa  $3, $6
+       pxor    $4, $6
+       pxor    $6, $7
+       pand    $3, $6
+       por     $2, $3
+       pxor    $4, $2
+       por     $1, $6
+       pand    $3, $2
+       pxor    $2, $6
+       por     $7, $1
+       pxor    $6, $1
+       movdqa  $7, $2
+       pand    $1, $2
+       PNOT($7)
+       por     $7, $4
+       pxor    $3, $4
+       movdqa  $1, $8
+       pxor    $4, $8
+       por     $4, $2
+       pxor    $2, $5
+>)
+
+define(<WSBOX1I>, <
+       movdqa  $2, $6
+       por     $4, $6
+       pxor    $3, $6
+       movdqa  $1, $8
+       pxor    $2, $8
+       movdqa  $1, $5
+       por     $6, $5
+       pand    $8, $5
+       pxor    $5, $2
+       pxor    $6, $8
+       pand    $4, $2
+       movdqa  $1, $7
+       pand    $3, $7
+       por     $7, $6
+       por     $4, $7
+       pxor    $5, $7
+       PNOT($7)
+       pxor    $2, $6
+       pxor    $6, $5
+       pxor    $3, $5
+       por     $7, $1
+       pxor    $1, $5
+>)
+
+define(<WSBOX2I>, <
+       movdqa  $1, $5
+       pxor    $4, $5
+       movdqa  $3, $7
+       pxor    $4, $7
+       movdqa  $2, $6
+       por     $7, $6
+       pxor    $6, $5
+       movdqa  $4, $6
+       por     $5, $6
+       pand    $2, $6
+       PNOT($4)
+       movdqa  $1, $8
+       por     $3, $8
+       pand    $8, $7
+       pxor    $7, $6
+       pand    $2, $8
+       pand    $3, $1
+       por     $4, $1
+       pxor    $1, $8
+       pand    $8, $3
+       pxor    $1, $3
+       movdqa  $5, $7
+       pxor    $6, $7
+       pxor    $3, $7
+>)
+
+define(<WSBOX3I>, <
+       movdqa  $3, $8
+       por     $4, $8
+       movdqa  $2, $5
+       pand    $8, $5
+       movdqa  $1, $7
+       por     $4, $7
+       movdqa  $3, $6
+       pxor    $7, $6
+       pxor    $6, $5
+       pxor    $1, $4
+       pxor    $4, $8
+       pxor    $2, $7
+       pand    $6, $7
+       pxor    $4, $7
+       pxor    $1, $6
+       por     $5, $4
+       pand    $4, $6
+       pxor    $2, $6
+       pand    $7, $1
+       por     $2, $1
+       pxor    $1, $8
+>)
+
+define(<WSBOX4I>, <
+       movdqa  $3, $6
+       pxor    $4, $6
+       movdqa  $3, $7
+       por     $4, $7
+       pxor    $2, $7
+       por     $4, $2
+       movdqa  $1, $5
+       pxor    $7, $5
+       pxor    $7, $4
+       pand    $1, $7
+       pxor    $7, $6
+       pxor    $1, $7
+       por     $3, $7
+       pand    $2, $1
+       movdqa  $1, $8
+       pxor    $4, $8
+       PNOT($1)
+       por     $6, $1
+       pxor    $1, $5
+       pxor    $2, $1
+       pxor    $1, $7
+>)
+
+define(<WSBOX5I>, <
+       movdqa  $1, $6
+       pand    $4, $6
+       movdqa  $3, $8
+       pxor    $6, $8
+       movdqa  $2, $5
+       pand    $8, $5
+       movdqa  $1, $7
+       pxor    $4, $7
+       pxor    $2, $4
+       pxor    $7, $5
+       pand    $1, $3
+       pand    $5, $1
+       por     $2, $3
+       pxor    $5, $6
+       pxor    $3, $6
+       movdqa  $5, $7
+       por     $6, $7
+       pxor    $8, $7
+       pxor    $4, $7
+       PNOT($2)
+       por     $1, $2
+       pxor    $2, $8
+>)
+
+define(<WSBOX6I>, <
+       movdqa  $1, $7
+       pxor    $3, $7
+       PNOT($3)
+       movdqa  $2, $5
+       pxor    $4, $5
+       movdqa  $1, $6
+       por     $3, $6
+       pxor    $5, $6
+       movdqa  $2, $8
+       pand    $7, $8
+       por     $4, $8
+       por     $3, $4
+       por     $2, $3
+       pand    $1, $3
+       movdqa  $3, $5
+       pxor    $8, $5
+       PNOT($5)
+       pand    $7, $8
+       pxor    $3, $8
+       pxor    $6, $1
+       pxor    $1, $8
+       pand    $5, $2
+       pxor    $2, $7
+       pxor    $4, $7
+>)
+
+define(<WSBOX7I>, <
+       movdqa  $1, $8
+       pand    $2, $8
+       movdqa  $2, $7
+       pxor    $4, $7
+       por     $8, $7
+       movdqa  $1, $6
+       por     $4, $6
+       pand    $3, $6
+       pxor    $6, $7
+       por     $3, $8
+       movdqa  $1, $5
+       por     $2, $5
+       pand    $4, $5
+       pxor    $5, $8
+       pxor    $2, $5
+       movdqa  $4, $6
+       pxor    $8, $6
+       PNOT($6)
+       por     $5, $6
+       pxor    $3, $5
+       pxor    $1, $6
+       por     $6, $4
+       pxor    $4, $5
+>)
+
+define(<WLTI>, <
+       WROL(10, $3)
+       WROL(27, $1)
+       movdqa  $2, T0
+       pslld   <$>7, T0
+       pxor    $4, $3
+       pxor    T0, $3
+       pxor    $2, $1
+       pxor    $4, $1
+       WROL(25, $4)
+       WROL(31, $2)
+       movdqa  $1, T0
+       pslld   <$>3, T0
+       pxor    $3, $4
+       pxor    T0, $4
+       pxor    $1, $2
+       pxor    $3, $2
+       WROL(29, $3)
+       WROL(19, $1)
+>)
+
+       .file "serpent-decrypt.asm"
+       
+       C serpent_decrypt(struct serpent_context *ctx, 
+       C                 unsigned length, uint8_t *dst,
+       C                 const uint8_t *src)
+       .text
+       ALIGN(4)
+PROLOGUE(nettle_serpent_decrypt)
+        C save all registers that need to be saved
+       push    %rbx
+       push    %rbp
+       push    %r12
+       push    %r13
+       push    %r14
+
+       lea     (SRC, N), SRC
+       lea     (DST, N), DST
+       neg     N
+       jz      .Lend
+
+       cmp     $-64, N
+       ja      .Lblock_loop
+
+       pcmpeqd MINUS1, MINUS1
+
+.Lwblock_loop:
+       movups  (SRC, N), X0
+       movups  16(SRC, N), X1
+       movups  32(SRC, N), X2
+       movups  48(SRC, N), X3
+
+       WTRANSPOSE(X0,X1,X2,X3)
+
+       mov     $384, CNT
+
+       C FIXME: CNT known, no index register needed
+       WKEYXOR(128, X0,X1,X2,X3)
+
+       jmp     .Lwround_start
+
+       ALIGN(4)
+
+.Lwround_loop:
+       WLTI(X0,X1,X2,X3)
+.Lwround_start:
+       WSBOX7I(X0,X1,X2,X3, Y0,Y1,Y2,Y3)
+       WKEYXOR(112, Y0,Y1,Y2,Y3)
+
+       WLTI(Y0,Y1,Y2,Y3)
+       WSBOX6I(Y0,Y1,Y2,Y3, X0,X1,X2,X3)
+       WKEYXOR(96, X0,X1,X2,X3)
+       
+       WLTI(X0,X1,X2,X3)
+       WSBOX5I(X0,X1,X2,X3, Y0,Y1,Y2,Y3)
+       WKEYXOR(80, Y0,Y1,Y2,Y3)
+
+       WLTI(Y0,Y1,Y2,Y3)
+       WSBOX4I(Y0,Y1,Y2,Y3, X0,X1,X2,X3)
+       WKEYXOR(64, X0,X1,X2,X3)
+       
+       WLTI(X0,X1,X2,X3)
+       WSBOX3I(X0,X1,X2,X3, Y0,Y1,Y2,Y3)
+       WKEYXOR(48, Y0,Y1,Y2,Y3)
+
+       WLTI(Y0,Y1,Y2,Y3)
+       WSBOX2I(Y0,Y1,Y2,Y3, X0,X1,X2,X3)
+       WKEYXOR(32, X0,X1,X2,X3)
+       
+       WLTI(X0,X1,X2,X3)
+       WSBOX1I(X0,X1,X2,X3, Y0,Y1,Y2,Y3)
+       WKEYXOR(16, Y0,Y1,Y2,Y3)
+
+       WLTI(Y0,Y1,Y2,Y3)
+       WSBOX0I(Y0,Y1,Y2,Y3, X0,X1,X2,X3)
+       WKEYXOR(, X0,X1,X2,X3)
+
+       sub     $128, CNT
+       jnc     .Lwround_loop
+
+       WTRANSPOSE(X0,X1,X2,X3)
+
+       movups  X0, (DST, N)
+       movups  X1, 16(DST, N)
+       movups  X2, 32(DST, N)
+       movups  X3, 48(DST, N)
+
+       C FIXME: Adjust N, so we can use just jnc without an extra cmp.
+       add     $64, N
+       jz      .Lend
+
+       cmp     $-64, N
+       jbe     .Lwblock_loop
+
+.Lblock_loop:
+       movl    (SRC, N), x0
+       movl    4(SRC, N), x1
+       movl    8(SRC, N), x2
+       movl    12(SRC, N), x3
+
+       xor     512(CTX), x0
+       xor     516(CTX), x1
+       xor     520(CTX), x2
+       xor     524(CTX), x3
+
+       mov     $384, CNT
+       jmp     .Lround_start
+
+       ALIGN(4)
+.Lround_loop:
+       LTI(x0,x1,x2,x3)
+.Lround_start:
+       SBOX7I(x0,x1,x2,x3, y0,y1,y2,y3)
+       xor     112(CTX, CNT), y0
+       xor     116(CTX, CNT), y1
+       xor     120(CTX, CNT), y2
+       xor     124(CTX, CNT), y3
+
+       LTI(y0,y1,y2,y3)
+       SBOX6I(y0,y1,y2,y3, x0,x1,x2,x3)
+       xor      96(CTX, CNT), x0
+       xor     100(CTX, CNT), x1
+       xor     104(CTX, CNT), x2
+       xor     108(CTX, CNT), x3
+
+       LTI(x0,x1,x2,x3)
+       SBOX5I(x0,x1,x2,x3, y0,y1,y2,y3)
+       xor     80(CTX, CNT), y0
+       xor     84(CTX, CNT), y1
+       xor     88(CTX, CNT), y2
+       xor     92(CTX, CNT), y3
+
+       LTI(y0,y1,y2,y3)
+       SBOX4I(y0,y1,y2,y3, x0,x1,x2,x3)
+       xor     64(CTX, CNT), x0
+       xor     68(CTX, CNT), x1
+       xor     72(CTX, CNT), x2
+       xor     76(CTX, CNT), x3
+
+       LTI(x0,x1,x2,x3)
+       SBOX3I(x0,x1,x2,x3, y0,y1,y2,y3)
+       xor     48(CTX, CNT), y0
+       xor     52(CTX, CNT), y1
+       xor     56(CTX, CNT), y2
+       xor     60(CTX, CNT), y3
+
+       LTI(y0,y1,y2,y3)
+       SBOX2I(y0,y1,y2,y3, x0,x1,x2,x3)
+       xor     32(CTX, CNT), x0
+       xor     36(CTX, CNT), x1
+       xor     40(CTX, CNT), x2
+       xor     44(CTX, CNT), x3
+
+       LTI(x0,x1,x2,x3)
+       SBOX1I(x0,x1,x2,x3, y0,y1,y2,y3)
+       xor     16(CTX, CNT), y0
+       xor     20(CTX, CNT), y1
+       xor     24(CTX, CNT), y2
+       xor     28(CTX, CNT), y3
+
+       LTI(y0,y1,y2,y3)
+       SBOX0I(y0,y1,y2,y3, x0,x1,x2,x3)
+       xor       (CTX, CNT), x0
+       xor      4(CTX, CNT), x1
+       xor      8(CTX, CNT), x2
+       xor     12(CTX, CNT), x3
+       sub     $128, CNT
+       jnc     .Lround_loop
+
+       movl    x0, (DST, N)
+       movl    x1, 4(DST, N)
+       movl    x2, 8(DST, N)
+       movl    x3, 12(DST, N)
+       add     $16, N
+       jnc     .Lblock_loop
+       
+.Lend:
+       pop     %r14
+       pop     %r13
+       pop     %r12
+       pop     %rbp
+       pop     %rbx
+       ret
diff --git a/x86_64/serpent-encrypt.asm b/x86_64/serpent-encrypt.asm
new file mode 100644 (file)
index 0000000..fe60f7c
--- /dev/null
@@ -0,0 +1,735 @@
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2011 Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+include_src(<x86_64/serpent.m4>)
+
+C Register usage:
+
+C Single block serpent state, two copies
+define(<x0>, <%eax>)
+define(<x1>, <%ebx>)
+define(<x2>, <%ebp>)
+define(<x3>, <%r8d>)
+
+define(<y0>, <%r9d>)
+define(<y1>, <%r10d>)
+define(<y2>, <%r11d>)
+define(<y3>, <%r12d>)
+
+C Quadruple block serpent state, two copies
+define(<X0>, <%xmm0>)
+define(<X1>, <%xmm1>)
+define(<X2>, <%xmm2>)
+define(<X3>, <%xmm3>)
+
+define(<Y0>, <%xmm4>)
+define(<Y1>, <%xmm5>)
+define(<Y2>, <%xmm6>)
+define(<Y3>, <%xmm7>)
+
+define(<MINUS1>, <%xmm8>)
+define(<T0>, <%xmm9>)
+define(<T1>, <%xmm10>)
+define(<T2>, <%xmm11>)
+define(<T3>, <%xmm12>)
+
+C Arguments
+define(<CTX>, <%rdi>)
+define(<N>, <%rsi>)
+define(<DST>, <%rdx>)
+define(<SRC>, <%rcx>)
+
+define(<CNT>, <%r13>)
+define(<TMP32>, <%r14d>)
+
+C SBOX macros. Inputs $1 - $4 (destroyed), outputs $5 - $8
+
+define(<SBOX0>, <
+       mov     $2, $8  C y3  = x1 ^ x2
+       xor     $3, $8
+       mov     $1, $5  C y0  = x0 | x3
+       or      $4, $5
+       mov     $1, $6  C y1  = x0 ^ x1
+       xor     $2, $6
+       xor     $5, $8  C y3 ^= y0
+       mov     $3, $7  C y2  = x2 | y3
+       or      $8, $7
+       xor     $4, $1  C x0 ^= x3
+       and     $4, $7  C y2 &= x3
+       xor     $3, $4  C x3 ^= x2
+       or      $2, $3  C x2 |= x1
+       mov     $6, $5  C y0  = y1 & x2
+       and     $3, $5
+       xor     $5, $7  C y2 ^= y0
+       and     $7, $5  C y0 &= y2
+       xor     $3, $5  C y0 ^= x2
+       and     $1, $2  C x1 &= x0
+       xor     $1, $5  C y0 ^= x0
+       not     $5      C y0  = ~y0
+       mov     $5, $6  C y1  = y0 ^ x1
+       xor     $2, $6
+       xor     $4, $6  C y1 ^= x3
+>)
+
+define(<SBOX1>, <
+       mov     $1, $6  C y1  = x0 | x3
+       or      $4, $6 
+       mov     $3, $7  C y2  = x2 ^ x3
+       xor     $4, $7
+       mov     $2, $5  C y0  = ~x1
+       not     $5
+       mov     $1, $8  C y3  = x0 ^ x2
+       xor     $3, $8
+       or      $1, $5  C y0 |= x0
+       and     $4, $8  C y3 &= x3
+       mov     $6, $1  C x0  = y1 & y2
+       and     $7, $1
+       or      $2, $8  C y3 |= x1
+       xor     $5, $7  C y2 ^= y0
+       xor     $1, $8  C y3 ^= x0
+       mov     $6, $1  C x0  = y1 ^ y3
+       xor     $8, $1
+       xor     $7, $1  C x0 ^= y2
+       mov     $2, $6  C y1  = x1 & x3
+       and     $4, $6
+       xor     $1, $6  C y1 ^= x0
+       mov     $6, $4  C x3  = y1 | y3
+       or      $8, $4
+       not     $8      C y3  = ~y3
+       and     $4, $5  C y0 &= x3
+       xor     $3, $5  C y0 ^= x2
+>)
+
+define(<SBOX2>, <
+       mov     $1, $7  C y2 = x1 | x2
+       or      $3, $7
+       mov     $1, $6
+       xor     $2, $6
+       mov     $4, $8
+       xor     $7, $8
+       mov     $6, $5
+       xor     $8, $5
+       or      $1, $4
+       xor     $5, $3
+       mov     $2, $1
+       xor     $3, $1
+       or      $2, $3
+       and     $7, $1
+       xor     $3, $8
+       or      $8, $6
+       xor     $1, $6
+       mov     $8, $7
+       xor     $6, $7
+       xor     $2, $7
+       not     $8
+       xor     $4, $7
+>)
+
+define(<SBOX3>, <
+       mov     $1, $6
+       xor     $3, $6
+       mov     $1, $5
+       or      $4, $5
+       mov     $1, $8
+       and     $4, $8
+       and     $5, $6
+       or      $2, $8
+       mov     $1, $7
+       and     $2, $7
+       or      $3, $7
+       mov     $4, $3
+       xor     $6, $3
+       xor     $8, $6
+       or      $3, $1
+       xor     $2, $3
+       and     $4, $8
+       xor     $8, $5
+       mov     $7, $8
+       xor     $3, $8
+       xor     $5, $7
+       or      $8, $4
+       and     $4, $2
+       mov     $1, $5
+       xor     $2, $5
+>)
+
+define(<SBOX4>, <
+       mov     $1, $8
+       or      $2, $8
+       mov     $2, $7
+       or      $3, $7
+       xor     $1, $7
+       and     $4, $8
+       mov     $2, $5
+       xor     $4, $5
+       or      $7, $4
+       and     $4, $1
+       and     $3, $2
+       xor     $8, $3
+       xor     $7, $8
+       or      $2, $7
+       mov     $8, $6
+       and     $5, $6
+       xor     $6, $7
+       xor     $5, $6
+       or      $2, $6
+       xor     $1, $6
+       and     $4, $5
+       xor     $3, $5
+       not     $5
+>)
+
+define(<SBOX5>, <
+       mov     $2, $5
+       or      $4, $5
+       xor     $3, $5
+       mov     $2, $3
+       xor     $4, $3
+       mov     $1, $7
+       xor     $3, $7
+       and     $3, $1
+       xor     $1, $5
+       mov     $2, $8
+       or      $7, $8
+       or      $5, $2
+       not     $5
+       or      $5, $1
+       xor     $3, $8
+       xor     $1, $8
+       mov     $4, $6
+       or      $5, $6
+       xor     $6, $4
+       xor     $7, $6
+       or      $4, $7
+       xor     $2, $7
+>)
+
+define(<SBOX6>, <
+       mov     $1, $5
+       xor     $4, $5
+       mov     $1, $6
+       and     $4, $6
+       mov     $1, $7
+       or      $3, $7
+       or      $2, $4
+       xor     $3, $4
+       xor     $2, $1
+       mov     $2, $8
+       or      $3, $8
+       xor     $2, $3
+       and     $5, $8
+       xor     $3, $6
+       not     $6
+       and     $6, $5
+       and     $6, $2
+       xor     $8, $2
+       xor     $4, $8
+       xor     $2, $7
+       not     $7
+       xor     $7, $5
+       xor     $1, $5
+>)
+
+define(<SBOX7>, <
+       mov     $1, $5
+       and     $3, $5
+       mov     $2, $8
+       or      $5, $8  C t04
+       xor     $3, $8
+       mov     $4, $6
+       not     $6      C t02   
+       and     $1, $6
+       xor     $6, $8
+       mov     $3, $6
+       or      $8, $6
+       xor     $1, $6
+       mov     $1, $7
+       and     $2, $7
+       xor     $7, $3
+       or      $4, $7
+       xor     $7, $6
+       mov     $2, $7
+       or      $5, $7  C t04
+       and     $8, $7
+       xor     $6, $2
+       or      $2, $7
+       xor     $1, $7
+       xor     $6, $5
+       not     $4      C t02
+       or      $4, $5
+       xor     $3, $5
+>)
+
+define(<LT>, <
+       rol     <$>13, $1
+       rol     <$>3, $3
+       xor     $1, $2
+       xor     $3, $2
+       mov     $1, TMP32
+       shl     <$>3, TMP32
+       xor     $3, $4
+       xor     TMP32, $4
+       rol     $2
+       rol     <$>7, $4
+       xor     $2, $1
+       xor     $4, $1
+       mov     $2, TMP32
+       shl     <$>7, TMP32
+       xor     $4, $3
+       xor     TMP32, $3
+       rol     <$>5, $1
+       rol     <$>22, $3
+>)
+
+C Parallel operation on four blocks at a time.
+
+C pnot instruction is missing. For lack of a spare register, XOR with
+C constant in memory.
+       
+define(<PNOT>, <
+       pxor    MINUS1, $1
+>)
+
+define(<WSBOX0>, <
+       movdqa  $2, $8  C y3  = x1 ^ x2
+       pxor    $3, $8
+       movdqa  $1, $5  C y0  = x0 | x3
+       por     $4, $5
+       movdqa  $1, $6  C y1  = x0 ^ x1
+       pxor    $2, $6
+       pxor    $5, $8  C y3 ^= y0
+       movdqa  $3, $7  C y2  = x2 | y3
+       por     $8, $7
+       pxor    $4, $1  C x0 ^= x3
+       pand    $4, $7  C y2 &= x3
+       pxor    $3, $4  C x3 ^= x2
+       por     $2, $3  C x2 |= x1
+       movdqa  $6, $5  C y0  = y1 & x2
+       pand    $3, $5
+       pxor    $5, $7  C y2 ^= y0
+       pand    $7, $5  C y0 &= y2
+       pxor    $3, $5  C y0 ^= x2
+       pand    $1, $2  C x1 &= x0
+       pxor    $1, $5  C y0 ^= x0
+       PNOT($5)        C y0  = ~y0
+       movdqa  $5, $6  C y1  = y0 ^ x1
+       pxor    $2, $6
+       pxor    $4, $6  C y1 ^= x3
+>)
+
+define(<WSBOX1>, <
+       movdqa  $1, $6  C y1  = x0 | x3
+       por     $4, $6 
+       movdqa  $3, $7  C y2  = x2 ^ x3
+       pxor    $4, $7
+       movdqa  $2, $5  C y0  = ~x1
+       PNOT($5)
+       movdqa  $1, $8  C y3  = x0 ^ x2
+       pxor    $3, $8
+       por     $1, $5  C y0 |= x0
+       pand    $4, $8  C y3 &= x3
+       movdqa  $6, $1  C x0  = y1 & y2
+       pand    $7, $1
+       por     $2, $8  C y3 |= x1
+       pxor    $5, $7  C y2 ^= y0
+       pxor    $1, $8  C y3 ^= x0
+       movdqa  $6, $1  C x0  = y1 ^ y3
+       pxor    $8, $1
+       pxor    $7, $1  C x0 ^= y2
+       movdqa  $2, $6  C y1  = x1 & x3
+       pand    $4, $6
+       pxor    $1, $6  C y1 ^= x0
+       movdqa  $6, $4  C x3  = y1 | y3
+       por     $8, $4
+       PNOT($8)        C y3  = ~y3
+       pand    $4, $5  C y0 &= x3
+       pxor    $3, $5  C y0 ^= x2
+>)
+
+define(<WSBOX2>, <
+       movdqa  $1, $7  C y2 = x1 | x2
+       por     $3, $7
+       movdqa  $1, $6
+       pxor    $2, $6
+       movdqa  $4, $8
+       pxor    $7, $8
+       movdqa  $6, $5
+       pxor    $8, $5
+       por     $1, $4
+       pxor    $5, $3
+       movdqa  $2, $1
+       pxor    $3, $1
+       por     $2, $3
+       pand    $7, $1
+       pxor    $3, $8
+       por     $8, $6
+       pxor    $1, $6
+       movdqa  $8, $7
+       pxor    $6, $7
+       pxor    $2, $7
+       PNOT($8)
+       pxor    $4, $7
+>)
+
+define(<WSBOX3>, <
+       movdqa  $1, $6
+       pxor    $3, $6
+       movdqa  $1, $5
+       por     $4, $5
+       movdqa  $1, $8
+       pand    $4, $8
+       pand    $5, $6
+       por     $2, $8
+       movdqa  $1, $7
+       pand    $2, $7
+       por     $3, $7
+       movdqa  $4, $3
+       pxor    $6, $3
+       pxor    $8, $6
+       por     $3, $1
+       pxor    $2, $3
+       pand    $4, $8
+       pxor    $8, $5
+       movdqa  $7, $8
+       pxor    $3, $8
+       pxor    $5, $7
+       por     $8, $4
+       pand    $4, $2
+       movdqa  $1, $5
+       pxor    $2, $5
+>)
+
+define(<WSBOX4>, <
+       movdqa  $1, $8
+       por     $2, $8
+       movdqa  $2, $7
+       por     $3, $7
+       pxor    $1, $7
+       pand    $4, $8
+       movdqa  $2, $5
+       pxor    $4, $5
+       por     $7, $4
+       pand    $4, $1
+       pand    $3, $2
+       pxor    $8, $3
+       pxor    $7, $8
+       por     $2, $7
+       movdqa  $8, $6
+       pand    $5, $6
+       pxor    $6, $7
+       pxor    $5, $6
+       por     $2, $6
+       pxor    $1, $6
+       pand    $4, $5
+       pxor    $3, $5
+       PNOT($5)
+>)
+
+define(<WSBOX5>, <
+       movdqa  $2, $5
+       por     $4, $5
+       pxor    $3, $5
+       movdqa  $2, $3
+       pxor    $4, $3
+       movdqa  $1, $7
+       pxor    $3, $7
+       pand    $3, $1
+       pxor    $1, $5
+       movdqa  $2, $8
+       por     $7, $8
+       por     $5, $2
+       PNOT($5)
+       por     $5, $1
+       pxor    $3, $8
+       pxor    $1, $8
+       movdqa  $4, $6
+       por     $5, $6
+       pxor    $6, $4
+       pxor    $7, $6
+       por     $4, $7
+       pxor    $2, $7
+>)
+
+define(<WSBOX6>, <
+       movdqa  $1, $5
+       pxor    $4, $5
+       movdqa  $1, $6
+       pand    $4, $6
+       movdqa  $1, $7
+       por     $3, $7
+       por     $2, $4
+       pxor    $3, $4
+       pxor    $2, $1
+       movdqa  $2, $8
+       por     $3, $8
+       pxor    $2, $3
+       pand    $5, $8
+       pxor    $3, $6
+       PNOT($6)
+       pand    $6, $5
+       pand    $6, $2
+       pxor    $8, $2
+       pxor    $4, $8
+       pxor    $2, $7
+       PNOT($7)
+       pxor    $7, $5
+       pxor    $1, $5
+>)
+
+define(<WSBOX7>, <
+       movdqa  $1, $5
+       pand    $3, $5
+       movdqa  $2, $8
+       por     $5, $8  C t04
+       pxor    $3, $8
+       movdqa  $4, $6
+       pandn   $1, $6  C t02 implicit
+       pxor    $6, $8
+       movdqa  $3, $6
+       por     $8, $6
+       pxor    $1, $6
+       movdqa  $1, $7
+       pand    $2, $7
+       pxor    $7, $3
+       por     $4, $7
+       pxor    $7, $6
+       movdqa  $2, $7
+       por     $5, $7  C t04
+       pand    $8, $7
+       pxor    $6, $2
+       por     $2, $7
+       pxor    $1, $7
+       pxor    $6, $5
+       PNOT($4)        C t02
+       por     $4, $5
+       pxor    $3, $5
+>)
+
+C WLT(x0, x1, x2, x3)
+define(<WLT>, <
+       WROL(13, $1)
+       WROL(3, $3)
+       pxor    $1, $2
+       pxor    $3, $2
+       movdqa  $1, T0
+       pslld   <$>3, T0
+       pxor    $3, $4
+       pxor    T0, $4
+       WROL(1, $2)
+       WROL(7, $4)
+       pxor    $2, $1
+       pxor    $4, $1
+       movdqa  $2, T0
+       pslld   <$>7, T0
+       pxor    $4, $3
+       pxor    T0, $3
+       WROL(5, $1)
+       WROL(22, $3)
+>)
+
+       .file "serpent-encrypt.asm"
+       
+       C serpent_encrypt(struct serpent_context *ctx, 
+       C                 unsigned length, uint8_t *dst,
+       C                 const uint8_t *src)
+       .text
+       ALIGN(4)
+PROLOGUE(nettle_serpent_encrypt)
+        C save all registers that need to be saved
+       push    %rbx
+       push    %rbp
+       push    %r12
+       push    %r13
+       push    %r14
+
+       lea     (SRC, N), SRC
+       lea     (DST, N), DST
+       neg     N
+       jz      .Lend
+
+       C Point at the final subkey.
+       lea     512(CTX), CTX
+
+       cmp     $-64, N
+       ja      .Lblock_loop
+
+       pcmpeqd MINUS1, MINUS1
+
+.Lwblock_loop:
+       movups  (SRC, N), X0
+       movups  16(SRC, N), X1
+       movups  32(SRC, N), X2
+       movups  48(SRC, N), X3
+
+       WTRANSPOSE(X0, X1, X2, X3)
+
+       mov     $-512, CNT
+       jmp     .Lwround_start
+
+       ALIGN(4)
+.Lwround_loop:
+       WLT(X0,X1,X2,X3)
+.Lwround_start:
+       WKEYXOR(, X0,X1,X2,X3)
+       WSBOX0(X0,X1,X2,X3, Y0,Y1,Y2,Y3)
+       WLT(Y0,Y1,Y2,Y3)
+
+       WKEYXOR(16, Y0,Y1,Y2,Y3)
+       WSBOX1(Y0,Y1,Y2,Y3, X0,X1,X2,X3)
+       WLT(X0,X1,X2,X3)
+
+       WKEYXOR(32, X0,X1,X2,X3)
+       WSBOX2(X0,X1,X2,X3, Y0,Y1,Y2,Y3)
+       WLT(Y0,Y1,Y2,Y3)
+
+       WKEYXOR(48, Y0,Y1,Y2,Y3)
+       WSBOX3(Y0,Y1,Y2,Y3, X0,X1,X2,X3)
+       WLT(X0,X1,X2,X3)
+
+       WKEYXOR(64, X0,X1,X2,X3)
+       WSBOX4(X0,X1,X2,X3, Y0,Y1,Y2,Y3)
+       WLT(Y0,Y1,Y2,Y3)
+
+       WKEYXOR(80, Y0,Y1,Y2,Y3)
+       WSBOX5(Y0,Y1,Y2,Y3, X0,X1,X2,X3)
+       WLT(X0,X1,X2,X3)
+
+       WKEYXOR(96, X0,X1,X2,X3)
+       WSBOX6(X0,X1,X2,X3, Y0,Y1,Y2,Y3)
+       WLT(Y0,Y1,Y2,Y3)
+
+       WKEYXOR(112, Y0,Y1,Y2,Y3)
+       WSBOX7(Y0,Y1,Y2,Y3, X0,X1,X2,X3)
+       add     $128, CNT
+       jnz     .Lwround_loop
+
+       C FIXME: CNT known to be zero, no index register needed
+       WKEYXOR(, X0,X1,X2,X3)
+
+       WTRANSPOSE(X0,X1,X2,X3)
+
+       movups  X0, (DST, N)
+       movups  X1, 16(DST, N)
+       movups  X2, 32(DST, N)
+       movups  X3, 48(DST, N)
+
+       C FIXME: Adjust N, so we can use just jnc without an extra cmp.
+       add     $64, N
+       jz      .Lend
+
+       cmp     $-64, N
+       jbe     .Lwblock_loop
+
+C The single-block loop here is slightly slower than the double-block
+C loop in serpent-encrypt.c.
+
+C FIXME: Should use non-sse2 code only if we have a single block left.
+C With two or three blocks, it should be better to do them in
+C parallell.
+       
+.Lblock_loop:
+       movl    (SRC, N), x0
+       movl    4(SRC, N), x1
+       movl    8(SRC, N), x2
+       movl    12(SRC, N), x3
+
+       mov     $-512, CNT
+       jmp     .Lround_start
+       
+       ALIGN(4)
+.Lround_loop:
+       LT(x0,x1,x2,x3)
+.Lround_start:
+       xor       (CTX, CNT), x0
+       xor      4(CTX, CNT), x1
+       xor      8(CTX, CNT), x2
+       xor     12(CTX, CNT), x3
+       SBOX0(x0,x1,x2,x3, y0,y1,y2,y3)
+       LT(y0,y1,y2,y3)
+       
+       xor     16(CTX, CNT), y0
+       xor     20(CTX, CNT), y1
+       xor     24(CTX, CNT), y2
+       xor     28(CTX, CNT), y3
+       SBOX1(y0,y1,y2,y3, x0,x1,x2,x3)
+       LT(x0,x1,x2,x3)
+
+       xor     32(CTX, CNT), x0
+       xor     36(CTX, CNT), x1
+       xor     40(CTX, CNT), x2
+       xor     44(CTX, CNT), x3
+       SBOX2(x0,x1,x2,x3, y0,y1,y2,y3)
+       LT(y0,y1,y2,y3)
+
+       xor     48(CTX, CNT), y0
+       xor     52(CTX, CNT), y1
+       xor     56(CTX, CNT), y2
+       xor     60(CTX, CNT), y3
+       SBOX3(y0,y1,y2,y3, x0,x1,x2,x3)
+       LT(x0,x1,x2,x3)
+
+       xor     64(CTX, CNT), x0
+       xor     68(CTX, CNT), x1
+       xor     72(CTX, CNT), x2
+       xor     76(CTX, CNT), x3
+       SBOX4(x0,x1,x2,x3, y0,y1,y2,y3)
+       LT(y0,y1,y2,y3)
+
+       xor     80(CTX, CNT), y0
+       xor     84(CTX, CNT), y1
+       xor     88(CTX, CNT), y2
+       xor     92(CTX, CNT), y3
+       SBOX5(y0,y1,y2,y3, x0,x1,x2,x3)
+       LT(x0,x1,x2,x3)
+
+       xor     96(CTX, CNT), x0
+       xor     100(CTX, CNT), x1
+       xor     104(CTX, CNT), x2
+       xor     108(CTX, CNT), x3
+       SBOX6(x0,x1,x2,x3, y0,y1,y2,y3)
+       LT(y0,y1,y2,y3)
+
+       xor     112(CTX, CNT), y0
+       xor     116(CTX, CNT), y1
+       xor     120(CTX, CNT), y2
+       xor     124(CTX, CNT), y3
+       SBOX7(y0,y1,y2,y3, x0,x1,x2,x3)
+       add     $128, CNT
+       jnz     .Lround_loop
+
+       C Apply final subkey.
+       xor       (CTX, CNT), x0
+       xor      4(CTX, CNT), x1
+       xor      8(CTX, CNT), x2
+       xor     12(CTX, CNT), x3
+
+       movl    x0, (DST, N)
+       movl    x1, 4(DST, N)
+       movl    x2, 8(DST, N)
+       movl    x3, 12(DST, N)
+       add     $16, N
+       jnc     .Lblock_loop
+
+.Lend:
+       pop     %r14
+       pop     %r13
+       pop     %r12
+       pop     %rbp
+       pop     %rbx
+       ret
diff --git a/x86_64/serpent.m4 b/x86_64/serpent.m4
new file mode 100644 (file)
index 0000000..c8dc40c
--- /dev/null
@@ -0,0 +1,81 @@
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2011 Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+       
+C WROL(count, w)
+define(<WROL>, <
+       movdqa  $2, T0
+       pslld   <$>$1, $2
+       psrld   <$>eval(32 - $1), T0
+       por     T0, $2
+>)
+
+C Note: Diagrams use little-endian representation, with least
+C significant word to the left.
+       
+C Transpose values from:
+C     +----+----+----+----+
+C x0: | a0 | a1 | a2 | a3 |
+C x1: | b0 | b1 | b2 | b3 |
+C x2: | c0 | c1 | c2 | c3 |
+C x3: | d0 | d1 | d2 | d3 |
+C     +----+----+----+----+
+C To:
+C     +----+----+----+----+
+C x0: | a0 | b0 | c0 | d0 |
+C x1: | a1 | b1 | c1 | d1 |
+C x2: | a2 | b2 | c2 | d2 |
+C x3: | a3 | b3 | c3 | d3 |
+C     +----+----+----+----+
+
+define(<WTRANSPOSE>, <
+       movdqa          $1, T0
+       punpcklqdq      $3, T0                  C |a0 a1 c0 c1|
+       punpckhqdq      $3, $1                  C |a2 a3 c2 c3|
+       pshufd          <$>0xd8, T0, T0         C |a0 c0 a1 c1|
+       pshufd          <$>0xd8, $1, T1         C |a2 c2 a3 c3|
+       
+       movdqa          $2, T2
+       punpcklqdq      $4, T2                  C |b0 b1 d0 11|
+       punpckhqdq      $4, $2                  C |b2 b3 d2 d3|
+       pshufd          <$>0xd8, T2, T2         C |b0 d0 b1 d1|
+       pshufd          <$>0xd8, $2, T3         C |b2 d2 b3 d3|
+
+       movdqa          T0, $1
+       punpckldq       T2, $1                  C |a0 b0 c0 d0|
+       movdqa          T0, $2
+       punpckhdq       T2, $2                  C |a1 b1 c1 d1|
+
+       movdqa          T1, $3
+       punpckldq       T3, $3                  C |a2 b2 c2 d2|
+       movdqa          T1, $4
+       punpckhdq       T3, $4                  C |a3 b3 c3 d3|
+>)
+
+C FIXME: Arrange 16-byte alignment, so we can use movaps?
+define(<WKEYXOR>, <
+       movups  $1(CTX, CNT), T0
+       pshufd  <$>0x55, T0, T1
+       pshufd  <$>0xaa, T0, T2
+       pxor    T1, $3
+       pxor    T2, $4
+       pshufd  <$>0xff, T0, T1
+       pshufd  <$>0x00, T0, T0
+       pxor    T1, $5
+       pxor    T0, $2
+>)
diff --git a/x86_64/sha1-compress.asm b/x86_64/sha1-compress.asm
new file mode 100644 (file)
index 0000000..a912ce0
--- /dev/null
@@ -0,0 +1,254 @@
+C nettle, low-level cryptographics library
+C 
+C Copyright (C) 2004, 2008 Niels Möller
+C  
+C The nettle library is free software; you can redistribute it and/or modify
+C it under the terms of the GNU Lesser General Public License as published by
+C the Free Software Foundation; either version 2.1 of the License, or (at your
+C option) any later version.
+C 
+C The nettle library is distributed in the hope that it will be useful, but
+C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+C or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+C License for more details.
+C 
+C You should have received a copy of the GNU Lesser General Public License
+C along with the nettle library; see the file COPYING.LIB.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+C MA 02111-1307, USA.
+
+C Register usage. KVALUE and INPUT share a register.
+define(<SA>,<%eax>)dnl
+define(<SB>,<%r8d>)dnl
+define(<SC>,<%ecx>)dnl
+define(<SD>,<%edx>)dnl
+define(<SE>,<%r9d>)dnl
+define(<DATA>,<%rsp>)dnl
+define(<TMP>,<%r10d>)dnl
+define(<TMP2>,<%r11d>)dnl                      C  Used by F3
+define(<KVALUE>, <%esi>)dnl                    
+
+C Arguments
+define(<STATE>,<%rdi>)dnl
+define(<INPUT>,<%rsi>)dnl
+
+C Constants
+define(<K1VALUE>, <<$>0x5A827999>)dnl          C  Rounds  0-19
+define(<K2VALUE>, <<$>0x6ED9EBA1>)dnl          C  Rounds 20-39
+define(<K3VALUE>, <<$>0x8F1BBCDC>)dnl          C  Rounds 40-59
+define(<K4VALUE>, <<$>0xCA62C1D6>)dnl          C  Rounds 60-79
+       
+C Reads the input into register, byteswaps it, and stores it in the DATA array.
+C SWAP(index, register)
+define(<SWAP>, <
+       movl    OFFSET($1)(INPUT), $2
+       bswap   $2
+       movl    $2, OFFSET($1) (DATA)
+>)dnl
+
+C expand(i) is the expansion function
+C
+C   W[i] = (W[i - 16] ^ W[i - 14] ^ W[i - 8] ^ W[i - 3]) <<< 1
+C
+C where W[i] is stored in DATA[i mod 16].
+C
+C Result is stored back in W[i], and also left in TMP, the only
+C register that is used.
+define(<EXPAND>, <
+       movl    OFFSET(eval($1 % 16)) (DATA), TMP
+       xorl    OFFSET(eval(($1 +  2) % 16)) (DATA), TMP
+       xorl    OFFSET(eval(($1 +  8) % 16)) (DATA), TMP
+       xorl    OFFSET(eval(($1 + 13) % 16)) (DATA), TMP
+       roll    <$>1, TMP
+       movl    TMP, OFFSET(eval($1 % 16)) (DATA)>)dnl
+define(<NOEXPAND>, <OFFSET($1) (DATA)>)dnl
+
+C The f functions,
+C
+C  f1(x,y,z) = z ^ (x & (y ^ z))
+C  f2(x,y,z) = x ^ y ^ z
+C  f3(x,y,z) = (x & y) | (z & (x | y))
+C  f4 = f2
+C
+C The macro Fk(x,y,z) computes = fk(x,y,z). 
+C Result is left in TMP.
+define(<F1>, <
+       movl    $3, TMP
+       xorl    $2, TMP
+       andl    $1, TMP
+       xorl    $3, TMP>)dnl
+define(<F2>, <
+       movl    $1, TMP
+       xorl    $2, TMP
+       xorl    $3, TMP>)dnl
+C Uses TMP2
+define(<F3>, <
+       movl    $1, TMP2
+       andl    $2, TMP2
+       movl    $1, TMP
+       orl     $2, TMP
+       andl    $3, TMP
+       orl     TMP2, TMP>)dnl
+
+C The form of one sha1 round is
+C
+C   a' = e + a <<< 5 + f( b, c, d ) + k + w;
+C   b' = a;
+C   c' = b <<< 30;
+C   d' = c;
+C   e' = d;
+C
+C where <<< denotes rotation. We permute our variables, so that we
+C instead get
+C
+C   e += a <<< 5 + f( b, c, d ) + k + w;
+C   b <<<= 30
+C
+C ROUND(a,b,c,d,e,f,w)
+define(<ROUND>, <
+       addl    KVALUE, $5
+       addl    ifelse($7,,TMP,$7), $5
+       $6($2,$3,$4)
+       addl    TMP, $5
+
+C Using the TMP register could be avoided, by rotating $1 in place,
+C adding, and then rotating back.
+       movl    $1, TMP
+       roll    <$>5, TMP
+       addl    TMP, $5
+       roll    <$>30, $2>)dnl
+
+       .file "sha1-compress.asm"
+
+       C _nettle_sha1_compress(uint32_t *state, uint8_t *input)
+       
+       .text
+       ALIGN(4)
+PROLOGUE(_nettle_sha1_compress)
+       C save all registers that need to be saved
+       
+       sub     $68, %rsp       C  %rsp = W
+
+       C Load and byteswap data
+       SWAP( 0, SA) SWAP( 1, SB) SWAP( 2, SC) SWAP( 3, SD)
+       SWAP( 4, SA) SWAP( 5, SB) SWAP( 6, SC) SWAP( 7, SD)
+       SWAP( 8, SA) SWAP( 9, SB) SWAP(10, SC) SWAP(11, SD)
+       SWAP(12, SA) SWAP(13, SB) SWAP(14, SC) SWAP(15, SD)
+
+       C Load the state vector
+       movl      (STATE), SA
+       movl     4(STATE), SB
+       movl     8(STATE), SC
+       movl    12(STATE), SD
+       movl    16(STATE), SE
+
+       movl    K1VALUE, KVALUE
+       ROUND(SA, SB, SC, SD, SE, <F1>, NOEXPAND( 0))
+       ROUND(SE, SA, SB, SC, SD, <F1>, NOEXPAND( 1))
+       ROUND(SD, SE, SA, SB, SC, <F1>, NOEXPAND( 2))
+       ROUND(SC, SD, SE, SA, SB, <F1>, NOEXPAND( 3))
+       ROUND(SB, SC, SD, SE, SA, <F1>, NOEXPAND( 4))
+
+       ROUND(SA, SB, SC, SD, SE, <F1>, NOEXPAND( 5))
+       ROUND(SE, SA, SB, SC, SD, <F1>, NOEXPAND( 6))
+       ROUND(SD, SE, SA, SB, SC, <F1>, NOEXPAND( 7))
+       ROUND(SC, SD, SE, SA, SB, <F1>, NOEXPAND( 8))
+       ROUND(SB, SC, SD, SE, SA, <F1>, NOEXPAND( 9))
+
+       ROUND(SA, SB, SC, SD, SE, <F1>, NOEXPAND(10))
+       ROUND(SE, SA, SB, SC, SD, <F1>, NOEXPAND(11))
+       ROUND(SD, SE, SA, SB, SC, <F1>, NOEXPAND(12))
+       ROUND(SC, SD, SE, SA, SB, <F1>, NOEXPAND(13))
+       ROUND(SB, SC, SD, SE, SA, <F1>, NOEXPAND(14))
+
+       ROUND(SA, SB, SC, SD, SE, <F1>, NOEXPAND(15))
+       EXPAND(16) ROUND(SE, SA, SB, SC, SD, <F1>)
+       EXPAND(17) ROUND(SD, SE, SA, SB, SC, <F1>)
+       EXPAND(18) ROUND(SC, SD, SE, SA, SB, <F1>)
+       EXPAND(19) ROUND(SB, SC, SD, SE, SA, <F1>)
+
+       movl    K2VALUE, KVALUE
+       EXPAND(20) ROUND(SA, SB, SC, SD, SE, <F2>)
+       EXPAND(21) ROUND(SE, SA, SB, SC, SD, <F2>)
+       EXPAND(22) ROUND(SD, SE, SA, SB, SC, <F2>)
+       EXPAND(23) ROUND(SC, SD, SE, SA, SB, <F2>)
+       EXPAND(24) ROUND(SB, SC, SD, SE, SA, <F2>)
+
+       EXPAND(25) ROUND(SA, SB, SC, SD, SE, <F2>)
+       EXPAND(26) ROUND(SE, SA, SB, SC, SD, <F2>)
+       EXPAND(27) ROUND(SD, SE, SA, SB, SC, <F2>)
+       EXPAND(28) ROUND(SC, SD, SE, SA, SB, <F2>)
+       EXPAND(29) ROUND(SB, SC, SD, SE, SA, <F2>)
+
+       EXPAND(30) ROUND(SA, SB, SC, SD, SE, <F2>)
+       EXPAND(31) ROUND(SE, SA, SB, SC, SD, <F2>)
+       EXPAND(32) ROUND(SD, SE, SA, SB, SC, <F2>)
+       EXPAND(33) ROUND(SC, SD, SE, SA, SB, <F2>)
+       EXPAND(34) ROUND(SB, SC, SD, SE, SA, <F2>)
+
+       EXPAND(35) ROUND(SA, SB, SC, SD, SE, <F2>)
+       EXPAND(36) ROUND(SE, SA, SB, SC, SD, <F2>)
+       EXPAND(37) ROUND(SD, SE, SA, SB, SC, <F2>)
+       EXPAND(38) ROUND(SC, SD, SE, SA, SB, <F2>)
+       EXPAND(39) ROUND(SB, SC, SD, SE, SA, <F2>)
+
+       movl    K3VALUE, KVALUE
+       EXPAND(40) ROUND(SA, SB, SC, SD, SE, <F3>)
+       EXPAND(41) ROUND(SE, SA, SB, SC, SD, <F3>)
+       EXPAND(42) ROUND(SD, SE, SA, SB, SC, <F3>)
+       EXPAND(43) ROUND(SC, SD, SE, SA, SB, <F3>)
+       EXPAND(44) ROUND(SB, SC, SD, SE, SA, <F3>)
+
+       EXPAND(45) ROUND(SA, SB, SC, SD, SE, <F3>)
+       EXPAND(46) ROUND(SE, SA, SB, SC, SD, <F3>)
+       EXPAND(47) ROUND(SD, SE, SA, SB, SC, <F3>)
+       EXPAND(48) ROUND(SC, SD, SE, SA, SB, <F3>)
+       EXPAND(49) ROUND(SB, SC, SD, SE, SA, <F3>)
+
+       EXPAND(50) ROUND(SA, SB, SC, SD, SE, <F3>)
+       EXPAND(51) ROUND(SE, SA, SB, SC, SD, <F3>)
+       EXPAND(52) ROUND(SD, SE, SA, SB, SC, <F3>)
+       EXPAND(53) ROUND(SC, SD, SE, SA, SB, <F3>)
+       EXPAND(54) ROUND(SB, SC, SD, SE, SA, <F3>)
+
+       EXPAND(55) ROUND(SA, SB, SC, SD, SE, <F3>)
+       EXPAND(56) ROUND(SE, SA, SB, SC, SD, <F3>)
+       EXPAND(57) ROUND(SD, SE, SA, SB, SC, <F3>)
+       EXPAND(58) ROUND(SC, SD, SE, SA, SB, <F3>)
+       EXPAND(59) ROUND(SB, SC, SD, SE, SA, <F3>)
+
+       movl    K4VALUE, KVALUE
+       EXPAND(60) ROUND(SA, SB, SC, SD, SE, <F2>)
+       EXPAND(61) ROUND(SE, SA, SB, SC, SD, <F2>)
+       EXPAND(62) ROUND(SD, SE, SA, SB, SC, <F2>)
+       EXPAND(63) ROUND(SC, SD, SE, SA, SB, <F2>)
+       EXPAND(64) ROUND(SB, SC, SD, SE, SA, <F2>)
+
+       EXPAND(65) ROUND(SA, SB, SC, SD, SE, <F2>)
+       EXPAND(66) ROUND(SE, SA, SB, SC, SD, <F2>)
+       EXPAND(67) ROUND(SD, SE, SA, SB, SC, <F2>)
+       EXPAND(68) ROUND(SC, SD, SE, SA, SB, <F2>)
+       EXPAND(69) ROUND(SB, SC, SD, SE, SA, <F2>)
+
+       EXPAND(70) ROUND(SA, SB, SC, SD, SE, <F2>)
+       EXPAND(71) ROUND(SE, SA, SB, SC, SD, <F2>)
+       EXPAND(72) ROUND(SD, SE, SA, SB, SC, <F2>)
+       EXPAND(73) ROUND(SC, SD, SE, SA, SB, <F2>)
+       EXPAND(74) ROUND(SB, SC, SD, SE, SA, <F2>)
+
+       EXPAND(75) ROUND(SA, SB, SC, SD, SE, <F2>)
+       EXPAND(76) ROUND(SE, SA, SB, SC, SD, <F2>)
+       EXPAND(77) ROUND(SD, SE, SA, SB, SC, <F2>)
+       EXPAND(78) ROUND(SC, SD, SE, SA, SB, <F2>)
+       EXPAND(79) ROUND(SB, SC, SD, SE, SA, <F2>)
+
+       C Update the state vector
+       addl    SA,   (STATE) 
+       addl    SB,  4(STATE) 
+       addl    SC,  8(STATE) 
+       addl    SD, 12(STATE) 
+       addl    SE, 16(STATE)
+
+       add     $68, %rsp
+       ret
+EPILOGUE(_nettle_sha1_compress)
diff --git a/yarrow.h b/yarrow.h
new file mode 100644 (file)
index 0000000..22676c2
--- /dev/null
+++ b/yarrow.h
@@ -0,0 +1,137 @@
+/* yarrow.h
+ *
+ * The yarrow pseudo-randomness generator.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_YARROW_H_INCLUDED
+#define NETTLE_YARROW_H_INCLUDED
+
+#include "aes.h"
+#include "sha.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define yarrow256_init nettle_yarrow256_init
+#define yarrow256_seed nettle_yarrow256_seed
+#define yarrow256_update nettle_yarrow256_update
+#define yarrow256_random nettle_yarrow256_random
+#define yarrow256_is_seeded nettle_yarrow256_is_seeded
+#define yarrow256_needed_sources nettle_yarrow256_needed_sources
+#define yarrow256_fast_reseed nettle_yarrow256_fast_reseed
+#define yarrow256_slow_reseed nettle_yarrow256_slow_reseed
+#define yarrow_key_event_init nettle_yarrow_key_event_init
+#define yarrow_key_event_estimate nettle_yarrow_key_event_estimate
+
+/* Obsolete alias for backwards compatibility. Will be deleted in some
+   later version. */
+#define yarrow256_force_reseed yarrow256_slow_reseed
+  
+enum yarrow_pool_id { YARROW_FAST = 0, YARROW_SLOW = 1 };
+
+struct yarrow_source
+{
+  /* Indexed by yarrow_pool_id */
+  uint32_t estimate[2];
+  
+  /* The pool next sample should go to. */
+  enum yarrow_pool_id next;
+};
+
+
+#define YARROW256_SEED_FILE_SIZE (2 * AES_BLOCK_SIZE)
+
+/* Yarrow-256, based on SHA-256 and AES-256 */
+struct yarrow256_ctx
+{
+  /* Indexed by yarrow_pool_id */
+  struct sha256_ctx pools[2];
+
+  int seeded;
+
+  /* The current key and counter block */
+  struct aes_ctx key;
+  uint8_t counter[AES_BLOCK_SIZE];
+
+  /* The entropy sources */
+  unsigned nsources;
+  struct yarrow_source *sources;
+};
+
+void
+yarrow256_init(struct yarrow256_ctx *ctx,
+              unsigned nsources,
+              struct yarrow_source *sources);
+
+void
+yarrow256_seed(struct yarrow256_ctx *ctx,
+              unsigned length,
+              const uint8_t *seed_file);
+
+/* Returns 1 on reseed */
+int
+yarrow256_update(struct yarrow256_ctx *ctx,
+                unsigned source, unsigned entropy,
+                unsigned length, const uint8_t *data);
+
+void
+yarrow256_random(struct yarrow256_ctx *ctx, unsigned length, uint8_t *dst);
+
+int
+yarrow256_is_seeded(struct yarrow256_ctx *ctx);
+
+unsigned
+yarrow256_needed_sources(struct yarrow256_ctx *ctx);
+
+void
+yarrow256_fast_reseed(struct yarrow256_ctx *ctx);
+
+void
+yarrow256_slow_reseed(struct yarrow256_ctx *ctx);
+
+
+/* Key event estimator */
+#define YARROW_KEY_EVENT_BUFFER 16
+
+struct yarrow_key_event_ctx
+{
+  /* Counter for initial priming of the state */
+  unsigned index;
+  unsigned chars[YARROW_KEY_EVENT_BUFFER];
+  unsigned previous;
+};
+
+void
+yarrow_key_event_init(struct yarrow_key_event_ctx *ctx);
+
+unsigned
+yarrow_key_event_estimate(struct yarrow_key_event_ctx *ctx,
+                         unsigned key, unsigned time);
+  
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_YARROW_H_INCLUDED */
diff --git a/yarrow256.c b/yarrow256.c
new file mode 100644 (file)
index 0000000..7645a72
--- /dev/null
@@ -0,0 +1,366 @@
+/* yarrow256.c
+ *
+ * The yarrow pseudo-randomness generator.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "yarrow.h"
+
+#include "macros.h"
+
+#ifndef YARROW_DEBUG
+#define YARROW_DEBUG 0
+#endif
+
+#if YARROW_DEBUG
+#include <stdio.h>
+#endif
+
+/* Parameters */
+
+/* An upper limit on the entropy (in bits) in one octet of sample
+ * data. */
+#define YARROW_MULTIPLIER 4
+
+/* Entropy threshold for reseeding from the fast pool */
+#define YARROW_FAST_THRESHOLD 100
+
+/* Entropy threshold for reseeding from the fast pool */
+#define YARROW_SLOW_THRESHOLD 160
+
+/* Number of sources that must exceed the threshold for slow reseed */
+#define YARROW_SLOW_K 2
+
+/* The number of iterations when reseeding, P_t in the yarrow paper.
+ * Should be chosen so that reseeding takes on the order of 0.1-1
+ * seconds. */
+#define YARROW_RESEED_ITERATIONS 1500
+
+/* Entropy estimates sticks to this value, it is treated as infinity
+ * in calculations. It should fit comfortably in an uint32_t, to avoid
+ * overflows. */
+#define YARROW_MAX_ENTROPY 0x100000
+
+/* Forward declarations */
+static void
+yarrow_gate(struct yarrow256_ctx *ctx);
+
+void
+yarrow256_init(struct yarrow256_ctx *ctx,
+              unsigned n,
+              struct yarrow_source *s)
+{
+  unsigned i;
+
+  sha256_init(&ctx->pools[0]);
+  sha256_init(&ctx->pools[1]);
+  
+  ctx->seeded = 0;
+
+  /* Not strictly necessary, but it makes it easier to see if the
+   * values are sane. */
+  memset(ctx->counter, 0, sizeof(ctx->counter));
+  
+  ctx->nsources = n;
+  ctx->sources = s;
+
+  for (i = 0; i<n; i++)
+    {
+      ctx->sources[i].estimate[YARROW_FAST] = 0;
+      ctx->sources[i].estimate[YARROW_SLOW] = 0;
+      ctx->sources[i].next = YARROW_FAST;
+    }
+}
+
+void
+yarrow256_seed(struct yarrow256_ctx *ctx,
+              unsigned length,
+              const uint8_t *seed_file)
+{
+  assert(length > 0);
+
+  sha256_update(&ctx->pools[YARROW_FAST], length, seed_file);
+  yarrow256_fast_reseed(ctx);
+}
+
+/* FIXME: Generalize so that it generates a few more blocks at a
+ * time. */
+static void
+yarrow_generate_block(struct yarrow256_ctx *ctx,
+                     uint8_t *block)
+{
+  unsigned i;
+
+  aes_encrypt(&ctx->key, sizeof(ctx->counter), block, ctx->counter);
+
+  /* Increment counter, treating it as a big-endian number. This is
+   * machine independent, and follows appendix B of the NIST
+   * specification of cipher modes of operation.
+   *
+   * We could keep a representation of the counter as 4 32-bit values,
+   * and write entire words (in big-endian byteorder) into the counter
+   * block, whenever they change. */
+  for (i = sizeof(ctx->counter); i--; )
+    {
+      if (++ctx->counter[i])
+       break;
+    }
+}
+
+static void
+yarrow_iterate(uint8_t *digest)
+{
+  uint8_t v0[SHA256_DIGEST_SIZE];
+  unsigned i;
+  
+  memcpy(v0, digest, SHA256_DIGEST_SIZE);
+  
+  /* When hashed inside the loop, i should run from 1 to
+   * YARROW_RESEED_ITERATIONS */
+  for (i = 0; ++i < YARROW_RESEED_ITERATIONS; )
+    {
+      uint8_t count[4];
+      struct sha256_ctx hash;
+  
+      sha256_init(&hash);
+
+      /* Hash v_i | v_0 | i */
+      WRITE_UINT32(count, i);
+      sha256_update(&hash, SHA256_DIGEST_SIZE, digest);
+      sha256_update(&hash, sizeof(v0), v0);
+      sha256_update(&hash, sizeof(count), count);
+
+      sha256_digest(&hash, SHA256_DIGEST_SIZE, digest);
+    }
+}
+
+/* NOTE: The SHA-256 digest size equals the AES key size, so we need
+ * no "size adaptor". */
+
+void
+yarrow256_fast_reseed(struct yarrow256_ctx *ctx)
+{
+  uint8_t digest[SHA256_DIGEST_SIZE];
+  unsigned i;
+  
+#if YARROW_DEBUG
+  fprintf(stderr, "yarrow256_fast_reseed\n");
+#endif
+  
+  /* We feed two block of output using the current key into the pool
+   * before emptying it. */
+  if (ctx->seeded)
+    {
+      uint8_t blocks[AES_BLOCK_SIZE * 2];
+      
+      yarrow_generate_block(ctx, blocks);
+      yarrow_generate_block(ctx, blocks + AES_BLOCK_SIZE);
+      sha256_update(&ctx->pools[YARROW_FAST], sizeof(blocks), blocks);
+    }
+  
+  sha256_digest(&ctx->pools[YARROW_FAST], sizeof(digest), digest);
+
+  /* Iterate */
+  yarrow_iterate(digest);
+
+  aes_set_encrypt_key(&ctx->key, sizeof(digest), digest);
+  ctx->seeded = 1;
+
+  /* Derive new counter value */
+  memset(ctx->counter, 0, sizeof(ctx->counter));
+  aes_encrypt(&ctx->key, sizeof(ctx->counter), ctx->counter, ctx->counter);
+  
+  /* Reset estimates. */
+  for (i = 0; i<ctx->nsources; i++)
+    ctx->sources[i].estimate[YARROW_FAST] = 0;
+}
+
+void
+yarrow256_slow_reseed(struct yarrow256_ctx *ctx)
+{
+  uint8_t digest[SHA256_DIGEST_SIZE];
+  unsigned i;
+
+#if YARROW_DEBUG
+  fprintf(stderr, "yarrow256_slow_reseed\n");
+#endif
+
+  /* Get digest of the slow pool*/
+  sha256_digest(&ctx->pools[YARROW_SLOW], sizeof(digest), digest);
+
+  /* Feed it into the fast pool */
+  sha256_update(&ctx->pools[YARROW_FAST], sizeof(digest), digest);
+
+  yarrow256_fast_reseed(ctx);
+  
+  /* Reset estimates. */
+  for (i = 0; i<ctx->nsources; i++)
+    ctx->sources[i].estimate[YARROW_SLOW] = 0;
+}
+
+int
+yarrow256_update(struct yarrow256_ctx *ctx,
+                unsigned source_index, unsigned entropy,
+                unsigned length, const uint8_t *data)
+{
+  enum yarrow_pool_id current;
+  struct yarrow_source *source;
+  
+  assert(source_index < ctx->nsources);
+
+  if (!length)
+    /* Nothing happens */
+    return 0;
+
+  source = &ctx->sources[source_index];
+  
+  if (!ctx->seeded)
+    /* While seeding, use the slow pool */
+    current = YARROW_SLOW;
+  else
+    {
+      current = source->next;
+      source->next = !source->next;
+    }
+
+  sha256_update(&ctx->pools[current], length, data);
+  /* NOTE: We should be careful to avoid overflows in the estimates. */
+  if (source->estimate[current] < YARROW_MAX_ENTROPY)
+    {
+      if (entropy > YARROW_MAX_ENTROPY)
+       entropy = YARROW_MAX_ENTROPY;
+
+      if ( (length < (YARROW_MAX_ENTROPY / YARROW_MULTIPLIER))
+          && (entropy > YARROW_MULTIPLIER * length) )
+       entropy = YARROW_MULTIPLIER * length;
+
+      entropy += source->estimate[current];
+      if (entropy > YARROW_MAX_ENTROPY)
+       entropy = YARROW_MAX_ENTROPY;
+
+      source->estimate[current] = entropy;
+    }
+
+  /* Check for seed/reseed */
+  switch(current)
+    {
+    case YARROW_FAST:
+#if YARROW_DEBUG
+      fprintf(stderr,
+              "yarrow256_update: source_index = %d,\n"
+              "            fast pool estimate = %d\n",
+              source_index, source->estimate[YARROW_FAST]);
+#endif
+      if (source->estimate[YARROW_FAST] >= YARROW_FAST_THRESHOLD)
+       {
+         yarrow256_fast_reseed(ctx);
+         return 1;
+       }
+      else
+       return 0;
+
+    case YARROW_SLOW:
+      {
+        if (!yarrow256_needed_sources(ctx))
+         {
+           yarrow256_slow_reseed(ctx);
+           return 1;
+         }
+       else
+         return 0;
+      }
+    default:
+      abort();
+    }
+}
+
+static void
+yarrow_gate(struct yarrow256_ctx *ctx)
+{
+  uint8_t key[AES_MAX_KEY_SIZE];
+  unsigned i;
+
+  for (i = 0; i < sizeof(key); i+= AES_BLOCK_SIZE)
+    yarrow_generate_block(ctx, key + i);
+
+  aes_set_encrypt_key(&ctx->key, sizeof(key), key);
+}
+
+void
+yarrow256_random(struct yarrow256_ctx *ctx, unsigned length, uint8_t *dst)
+{
+  assert(ctx->seeded);
+
+  while (length >= AES_BLOCK_SIZE)
+    {
+      yarrow_generate_block(ctx, dst);
+      dst += AES_BLOCK_SIZE;
+      length -= AES_BLOCK_SIZE;
+    }
+  if (length)
+    {
+      uint8_t buffer[AES_BLOCK_SIZE];
+      
+      assert(length < AES_BLOCK_SIZE);
+      yarrow_generate_block(ctx, buffer);
+      memcpy(dst, buffer, length);
+    }
+  yarrow_gate(ctx);
+}
+
+int
+yarrow256_is_seeded(struct yarrow256_ctx *ctx)
+{
+  return ctx->seeded;
+}
+
+unsigned
+yarrow256_needed_sources(struct yarrow256_ctx *ctx)
+{
+  /* FIXME: This is somewhat inefficient. It would be better to
+   * either maintain the count, or do this loop only if the
+   * current source just crossed the threshold. */
+  unsigned k, i;
+
+  for (i = k = 0; i < ctx->nsources; i++)
+    if (ctx->sources[i].estimate[YARROW_SLOW] >= YARROW_SLOW_THRESHOLD)
+      k++;
+
+#if YARROW_DEBUG
+  fprintf(stderr,
+          "yarrow256_needed_sources: source_index = %d,\n"
+          "                    slow pool estimate = %d,\n"
+          "     number of sources above threshold = %d\n",
+          source_index, source->estimate[YARROW_SLOW], k);
+#endif
+  
+  return (k < YARROW_SLOW_K) ? (YARROW_SLOW_K - k) : 0;
+}
diff --git a/yarrow_key_event.c b/yarrow_key_event.c
new file mode 100644 (file)
index 0000000..92360d9
--- /dev/null
@@ -0,0 +1,78 @@
+/* yarrow_key_event.c
+ *
+ * Exampel entropy estimator for key-like input events. */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2001 Niels Möller
+ *  
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "yarrow.h"
+
+void
+yarrow_key_event_init(struct yarrow_key_event_ctx *ctx)
+{
+  unsigned i;
+  
+  ctx->index = 0;
+  ctx->previous = 0;
+  
+  for (i = 0; i < YARROW_KEY_EVENT_BUFFER; i++)
+    ctx->chars[i] = 0;  
+}
+
+unsigned
+yarrow_key_event_estimate(struct yarrow_key_event_ctx *ctx,
+                         unsigned key, unsigned time)
+{
+  unsigned entropy = 0;
+  unsigned i;
+
+  /* Look at timing first. */
+  if (ctx->previous && (time > ctx->previous) )
+    {
+      if ( (time - ctx->previous) >= 256)
+        entropy++;
+    }
+  ctx->previous = time;
+
+  if (!key)
+    return entropy;
+  
+  for (i = 0; i < YARROW_KEY_EVENT_BUFFER; i++)
+    if (key == ctx->chars[i])
+      /* This is a recent character. Ignore it. */
+      return entropy;
+
+  /* Count one bit of entropy, unless this was one of the initial 16
+   * characters. */
+  if (ctx->chars[ctx->index])
+    entropy++;
+  
+  /* Remember the character. */
+  
+  ctx->chars[ctx->index] = key;
+  ctx->index = (ctx->index + 1) % YARROW_KEY_EVENT_BUFFER;
+
+  return entropy;
+}
+