From 047f1f6c89f3085129e12b3e1ae28371e67cd234 Mon Sep 17 00:00:00 2001 From: HyungKyu Song Date: Sat, 16 Feb 2013 00:08:52 +0900 Subject: [PATCH] Tizen 2.0 Release --- AUTHORS | 1 + COPYING | 340 ++ COPYING.LIB | 510 ++ ChangeLog | 4976 ++++++++++++++++ INSTALL | 234 + Makefile.in | 431 ++ NEWS | 410 ++ README | 53 + TODO | 29 + aclocal.m4 | 1062 ++++ aes-decrypt-internal.c | 83 + aes-decrypt.c | 347 ++ aes-encrypt-internal.c | 105 + aes-encrypt-table.c | 346 ++ aes-encrypt.c | 45 + aes-internal.h | 96 + aes-meta.c | 38 + aes-set-decrypt-key.c | 186 + aes-set-encrypt-key.c | 96 + aes.h | 85 + aesdata.c | 299 + arcfour-crypt.c | 53 + arcfour-meta.c | 38 + arcfour.c | 78 + arcfour.h | 71 + arctwo-meta.c | 48 + arctwo.c | 230 + arctwo.h | 82 + asm.m4 | 65 + asn1.h | 144 + base16-decode.c | 130 + base16-encode.c | 57 + base16-meta.c | 67 + base16.h | 106 + base64-decode.c | 151 + base64-encode.c | 229 + base64-meta.c | 45 + base64.h | 153 + bignum-next-prime.c | 162 + bignum-random-prime.c | 415 ++ bignum-random.c | 85 + bignum.c | 195 + bignum.h | 121 + blowfish.c | 409 ++ blowfish.h | 76 + buffer-init.c | 41 + buffer.c | 134 + buffer.h | 98 + camellia-crypt-internal.c | 139 + camellia-crypt.c | 45 + camellia-internal.h | 74 + camellia-meta.c | 38 + camellia-set-decrypt-key.c | 61 + camellia-set-encrypt-key.c | 331 ++ camellia-table.c | 310 + camellia.h | 82 + cast128-meta.c | 32 + cast128.c | 276 + cast128.h | 77 + cast128_sboxes.h | 545 ++ cbc.c | 161 + cbc.h | 75 + config.guess | 1439 +++++ config.h.in | 180 + config.m4.in | 8 + config.make.in | 93 + config.sub | 1549 +++++ configure | 11909 +++++++++++++++++++++++++++++++++++++ configure.ac | 539 ++ ctr.c | 84 + ctr.h | 62 + der-iterator.c | 272 + der2dsa.c | 119 + der2rsa.c | 133 + des-compat.c | 222 + des-compat.h | 154 + des.c | 296 + des.h | 111 + des3.c | 74 + desCode.h | 412 ++ descore.README | 313 + desdata.c | 198 + desinfo.h | 96 + dsa-keygen.c | 125 + dsa-sha1-sign.c | 56 + dsa-sha1-verify.c | 51 + dsa-sha256-sign.c | 55 + dsa-sha256-verify.c | 51 + dsa-sign.c | 90 + dsa-verify.c | 101 + dsa.c | 78 + dsa.h | 295 + dsa2sexp.c | 54 + examples/Makefile.in | 98 + examples/eratosthenes.c | 388 ++ examples/getopt.c | 1067 ++++ examples/getopt.h | 179 + examples/getopt1.c | 187 + examples/io.c | 189 + examples/io.h | 73 + examples/nettle-benchmark.c | 440 ++ examples/nettle-openssl.c | 372 ++ examples/next-prime.c | 158 + examples/random-prime.c | 143 + examples/read_rsa_key.c | 50 + examples/rsa-decrypt.c | 243 + examples/rsa-encrypt-test | 27 + examples/rsa-encrypt.c | 240 + examples/rsa-keygen.c | 156 + examples/rsa-session.h | 66 + examples/rsa-sign-test | 17 + examples/rsa-sign.c | 87 + examples/rsa-verify-test | 29 + examples/rsa-verify.c | 102 + examples/run-tests | 104 + examples/setup-env | 7 + examples/teardown-env | 6 + hmac-md5.c | 51 + hmac-sha1.c | 51 + hmac-sha224.c | 44 + hmac-sha256.c | 51 + hmac-sha384.c | 44 + hmac-sha512.c | 51 + hmac.c | 109 + hmac.h | 181 + install-sh | 507 ++ keymap.h | 138 + knuth-lfib.c | 162 + knuth-lfib.h | 75 + macros.h | 122 + md2-meta.c | 32 + md2.c | 167 + md2.h | 69 + md4-meta.c | 32 + md4.c | 272 + md4.h | 72 + md5-compat.c | 48 + md5-compat.h | 50 + md5-compress.c | 167 + md5-meta.c | 32 + md5.c | 169 + md5.h | 76 + memxor.c | 35 + memxor.h | 22 + nettle-internal.c | 85 + nettle-internal.h | 77 + nettle-meta.h | 217 + nettle-types.h | 87 + nettle-write.h | 44 + nettle.html | 5286 ++++++++++++++++ nettle.info | 2768 +++++++++ nettle.manifest | 5 + nettle.pdf | Bin 0 -> 313370 bytes nettle.texinfo | 2744 +++++++++ packaging/nettle.spec | 59 + pgp-encode.c | 413 ++ pgp.h | 240 + pkcs1-rsa-md5.c | 100 + pkcs1-rsa-sha1.c | 100 + pkcs1-rsa-sha256.c | 98 + pkcs1-rsa-sha512.c | 99 + pkcs1.c | 64 + pkcs1.h | 87 + prime-list.h | 656 ++ realloc.c | 50 + realloc.h | 43 + rotors.h | 82 + rsa-compat.c | 157 + rsa-compat.h | 131 + rsa-decrypt.c | 80 + rsa-encrypt.c | 83 + rsa-keygen.c | 204 + rsa-md5-sign.c | 73 + rsa-md5-verify.c | 73 + rsa-sha1-sign.c | 73 + rsa-sha1-verify.c | 73 + rsa-sha256-sign.c | 73 + rsa-sha256-verify.c | 73 + rsa-sha512-sign.c | 73 + rsa-sha512-verify.c | 73 + rsa-sign.c | 136 + rsa-verify.c | 56 + rsa.c | 73 + rsa.h | 384 ++ rsa2openpgp.c | 102 + rsa2sexp.c | 52 + serpent-meta.c | 38 + serpent.c | 374 ++ serpent.h | 81 + serpent_sboxes.h | 511 ++ sexp-format.c | 333 ++ sexp-transport-format.c | 85 + sexp-transport.c | 128 + sexp.c | 391 ++ sexp.h | 212 + sexp2bignum.c | 53 + sexp2dsa.c | 120 + sexp2rsa.c | 108 + sha-example.c | 41 + sha.h | 193 + sha1-compress.c | 249 + sha1-meta.c | 32 + sha1.c | 173 + sha224-meta.c | 32 + sha256-compress.c | 168 + sha256-meta.c | 32 + sha256.c | 214 + sha384-meta.c | 32 + sha512-compress.c | 164 + sha512-meta.c | 32 + sha512.c | 298 + shadata.c | 50 + sparc32/aes-decrypt-internal.asm | 132 + sparc32/aes-encrypt-internal.asm | 156 + sparc32/aes.m4 | 83 + sparc32/arcfour-crypt.asm | 230 + sparc32/machine.m4 | 0 sparc64/aes-decrypt-internal.asm | 138 + sparc64/aes-encrypt-internal.asm | 149 + sparc64/arcfour-crypt.asm | 217 + sparc64/machine.m4 | 4 + stamp-h.in | 1 + testsuite/.test-rules.make | 126 + testsuite/Makefile.in | 109 + testsuite/aes-test.c | 171 + testsuite/arcfour-test.c | 97 + testsuite/arctwo-test.c | 115 + testsuite/base16-test.c | 27 + testsuite/base64-test.c | 50 + testsuite/bignum-test.c | 97 + testsuite/blowfish-test.c | 89 + testsuite/buffer-test.c | 29 + testsuite/camellia-test.c | 84 + testsuite/cast128-test.c | 30 + testsuite/cbc-test.c | 329 + testsuite/ctr-test.c | 204 + testsuite/cxx-test.cxx | 108 + testsuite/des-compat-test.c | 874 +++ testsuite/des-test.c | 122 + testsuite/des3-test.c | 21 + testsuite/dsa-keygen-test.c | 46 + testsuite/dsa-test.c | 105 + testsuite/gold-bug.txt | 1598 +++++ testsuite/hmac-test.c | 831 +++ testsuite/knuth-lfib-test.c | 22 + testsuite/md2-test.c | 27 + testsuite/md4-test.c | 38 + testsuite/md5-compat-test.c | 60 + testsuite/md5-test.c | 120 + testsuite/pkcs1-conv-test | 51 + testsuite/pkcs1-test.c | 18 + testsuite/random-prime-test.c | 28 + testsuite/rsa-encrypt-test.c | 67 + testsuite/rsa-keygen-test.c | 79 + testsuite/rsa-test.c | 182 + testsuite/rsa2sexp-test.c | 107 + testsuite/run-tests | 104 + testsuite/serpent-test.c | 57 + testsuite/sexp-conv-test | 124 + testsuite/sexp-format-test.c | 160 + testsuite/sexp-test.c | 99 + testsuite/sexp2rsa-test.c | 46 + testsuite/sha1-huge-test.c | 15 + testsuite/sha1-test.c | 67 + testsuite/sha224-test.c | 48 + testsuite/sha256-test.c | 55 + testsuite/sha384-test.c | 57 + testsuite/sha512-test.c | 66 + testsuite/symbols-test | 42 + testsuite/teardown-env | 3 + testsuite/testutils.c | 961 +++ testsuite/testutils.h | 210 + testsuite/twofish-test.c | 28 + testsuite/yarrow-test.c | 221 + texinfo.tex | 9287 +++++++++++++++++++++++++++++ tools/Makefile.in | 80 + tools/getopt.c | 1067 ++++ tools/getopt.h | 179 + tools/getopt1.c | 187 + tools/input.c | 442 ++ tools/input.h | 76 + tools/misc.c | 73 + tools/misc.h | 75 + tools/nettle-lfib-stream.c | 81 + tools/output.c | 303 + tools/output.h | 93 + tools/parse.c | 164 + tools/parse.h | 65 + tools/pkcs1-conv.c | 649 ++ tools/sexp-conv.c | 442 ++ twofish-meta.c | 38 + twofish.c | 464 ++ twofish.h | 78 + write-be32.c | 68 + x86/aes-decrypt-internal.asm | 166 + x86/aes-encrypt-internal.asm | 166 + x86/aes.m4 | 85 + x86/arcfour-crypt.asm | 112 + x86/camellia-crypt-internal.asm | 213 + x86/machine.m4 | 16 + x86/md5-compress.asm | 174 + x86/sha1-compress.asm | 1541 +++++ x86_64/aes-decrypt-internal.asm | 133 + x86_64/aes-encrypt-internal.asm | 133 + x86_64/aes.m4 | 130 + x86_64/machine.m4 | 3 + x86_64/sha1-compress.asm | 254 + yarrow.h | 137 + yarrow256.c | 366 ++ yarrow_key_event.c | 78 + 310 files changed, 88719 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 COPYING.LIB create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 README create mode 100644 TODO create mode 100644 aclocal.m4 create mode 100644 aes-decrypt-internal.c create mode 100644 aes-decrypt.c create mode 100644 aes-encrypt-internal.c create mode 100644 aes-encrypt-table.c create mode 100644 aes-encrypt.c create mode 100644 aes-internal.h create mode 100644 aes-meta.c create mode 100644 aes-set-decrypt-key.c create mode 100644 aes-set-encrypt-key.c create mode 100644 aes.h create mode 100644 aesdata.c create mode 100644 arcfour-crypt.c create mode 100644 arcfour-meta.c create mode 100644 arcfour.c create mode 100644 arcfour.h create mode 100644 arctwo-meta.c create mode 100644 arctwo.c create mode 100644 arctwo.h create mode 100644 asm.m4 create mode 100644 asn1.h create mode 100644 base16-decode.c create mode 100644 base16-encode.c create mode 100644 base16-meta.c create mode 100644 base16.h create mode 100644 base64-decode.c create mode 100644 base64-encode.c create mode 100644 base64-meta.c create mode 100644 base64.h create mode 100644 bignum-next-prime.c create mode 100644 bignum-random-prime.c create mode 100644 bignum-random.c create mode 100644 bignum.c create mode 100644 bignum.h create mode 100644 blowfish.c create mode 100644 blowfish.h create mode 100644 buffer-init.c create mode 100644 buffer.c create mode 100644 buffer.h create mode 100644 camellia-crypt-internal.c create mode 100644 camellia-crypt.c create mode 100644 camellia-internal.h create mode 100644 camellia-meta.c create mode 100644 camellia-set-decrypt-key.c create mode 100644 camellia-set-encrypt-key.c create mode 100644 camellia-table.c create mode 100644 camellia.h create mode 100644 cast128-meta.c create mode 100644 cast128.c create mode 100644 cast128.h create mode 100644 cast128_sboxes.h create mode 100644 cbc.c create mode 100644 cbc.h create mode 100755 config.guess create mode 100644 config.h.in create mode 100644 config.m4.in create mode 100644 config.make.in create mode 100755 config.sub create mode 100755 configure create mode 100644 configure.ac create mode 100644 ctr.c create mode 100644 ctr.h create mode 100644 der-iterator.c create mode 100644 der2dsa.c create mode 100644 der2rsa.c create mode 100644 des-compat.c create mode 100644 des-compat.h create mode 100644 des.c create mode 100644 des.h create mode 100644 des3.c create mode 100644 desCode.h create mode 100644 descore.README create mode 100644 desdata.c create mode 100644 desinfo.h create mode 100644 dsa-keygen.c create mode 100644 dsa-sha1-sign.c create mode 100644 dsa-sha1-verify.c create mode 100644 dsa-sha256-sign.c create mode 100644 dsa-sha256-verify.c create mode 100644 dsa-sign.c create mode 100644 dsa-verify.c create mode 100644 dsa.c create mode 100644 dsa.h create mode 100644 dsa2sexp.c create mode 100644 examples/Makefile.in create mode 100644 examples/eratosthenes.c create mode 100644 examples/getopt.c create mode 100644 examples/getopt.h create mode 100644 examples/getopt1.c create mode 100644 examples/io.c create mode 100644 examples/io.h create mode 100644 examples/nettle-benchmark.c create mode 100644 examples/nettle-openssl.c create mode 100644 examples/next-prime.c create mode 100644 examples/random-prime.c create mode 100644 examples/read_rsa_key.c create mode 100644 examples/rsa-decrypt.c create mode 100755 examples/rsa-encrypt-test create mode 100644 examples/rsa-encrypt.c create mode 100644 examples/rsa-keygen.c create mode 100644 examples/rsa-session.h create mode 100755 examples/rsa-sign-test create mode 100644 examples/rsa-sign.c create mode 100755 examples/rsa-verify-test create mode 100644 examples/rsa-verify.c create mode 100755 examples/run-tests create mode 100755 examples/setup-env create mode 100755 examples/teardown-env create mode 100644 hmac-md5.c create mode 100644 hmac-sha1.c create mode 100644 hmac-sha224.c create mode 100644 hmac-sha256.c create mode 100644 hmac-sha384.c create mode 100644 hmac-sha512.c create mode 100644 hmac.c create mode 100644 hmac.h create mode 100755 install-sh create mode 100644 keymap.h create mode 100644 knuth-lfib.c create mode 100644 knuth-lfib.h create mode 100644 macros.h create mode 100644 md2-meta.c create mode 100644 md2.c create mode 100644 md2.h create mode 100644 md4-meta.c create mode 100644 md4.c create mode 100644 md4.h create mode 100644 md5-compat.c create mode 100644 md5-compat.h create mode 100644 md5-compress.c create mode 100644 md5-meta.c create mode 100644 md5.c create mode 100644 md5.h create mode 100644 memxor.c create mode 100644 memxor.h create mode 100644 nettle-internal.c create mode 100644 nettle-internal.h create mode 100644 nettle-meta.h create mode 100644 nettle-types.h create mode 100644 nettle-write.h create mode 100644 nettle.html create mode 100644 nettle.info create mode 100644 nettle.manifest create mode 100644 nettle.pdf create mode 100644 nettle.texinfo create mode 100644 packaging/nettle.spec create mode 100644 pgp-encode.c create mode 100644 pgp.h create mode 100644 pkcs1-rsa-md5.c create mode 100644 pkcs1-rsa-sha1.c create mode 100644 pkcs1-rsa-sha256.c create mode 100644 pkcs1-rsa-sha512.c create mode 100644 pkcs1.c create mode 100644 pkcs1.h create mode 100644 prime-list.h create mode 100644 realloc.c create mode 100644 realloc.h create mode 100644 rotors.h create mode 100644 rsa-compat.c create mode 100644 rsa-compat.h create mode 100644 rsa-decrypt.c create mode 100644 rsa-encrypt.c create mode 100644 rsa-keygen.c create mode 100644 rsa-md5-sign.c create mode 100644 rsa-md5-verify.c create mode 100644 rsa-sha1-sign.c create mode 100644 rsa-sha1-verify.c create mode 100644 rsa-sha256-sign.c create mode 100644 rsa-sha256-verify.c create mode 100644 rsa-sha512-sign.c create mode 100644 rsa-sha512-verify.c create mode 100644 rsa-sign.c create mode 100644 rsa-verify.c create mode 100644 rsa.c create mode 100644 rsa.h create mode 100644 rsa2openpgp.c create mode 100644 rsa2sexp.c create mode 100644 serpent-meta.c create mode 100644 serpent.c create mode 100644 serpent.h create mode 100644 serpent_sboxes.h create mode 100644 sexp-format.c create mode 100644 sexp-transport-format.c create mode 100644 sexp-transport.c create mode 100644 sexp.c create mode 100644 sexp.h create mode 100644 sexp2bignum.c create mode 100644 sexp2dsa.c create mode 100644 sexp2rsa.c create mode 100644 sha-example.c create mode 100644 sha.h create mode 100644 sha1-compress.c create mode 100644 sha1-meta.c create mode 100644 sha1.c create mode 100644 sha224-meta.c create mode 100644 sha256-compress.c create mode 100644 sha256-meta.c create mode 100644 sha256.c create mode 100644 sha384-meta.c create mode 100644 sha512-compress.c create mode 100644 sha512-meta.c create mode 100644 sha512.c create mode 100644 shadata.c create mode 100644 sparc32/aes-decrypt-internal.asm create mode 100644 sparc32/aes-encrypt-internal.asm create mode 100644 sparc32/aes.m4 create mode 100644 sparc32/arcfour-crypt.asm create mode 100644 sparc32/machine.m4 create mode 100644 sparc64/aes-decrypt-internal.asm create mode 100644 sparc64/aes-encrypt-internal.asm create mode 100644 sparc64/arcfour-crypt.asm create mode 100644 sparc64/machine.m4 create mode 100644 stamp-h.in create mode 100644 testsuite/.test-rules.make create mode 100644 testsuite/Makefile.in create mode 100644 testsuite/aes-test.c create mode 100644 testsuite/arcfour-test.c create mode 100644 testsuite/arctwo-test.c create mode 100644 testsuite/base16-test.c create mode 100644 testsuite/base64-test.c create mode 100644 testsuite/bignum-test.c create mode 100644 testsuite/blowfish-test.c create mode 100644 testsuite/buffer-test.c create mode 100644 testsuite/camellia-test.c create mode 100644 testsuite/cast128-test.c create mode 100644 testsuite/cbc-test.c create mode 100644 testsuite/ctr-test.c create mode 100644 testsuite/cxx-test.cxx create mode 100644 testsuite/des-compat-test.c create mode 100644 testsuite/des-test.c create mode 100644 testsuite/des3-test.c create mode 100644 testsuite/dsa-keygen-test.c create mode 100644 testsuite/dsa-test.c create mode 100644 testsuite/gold-bug.txt create mode 100644 testsuite/hmac-test.c create mode 100644 testsuite/knuth-lfib-test.c create mode 100644 testsuite/md2-test.c create mode 100644 testsuite/md4-test.c create mode 100644 testsuite/md5-compat-test.c create mode 100644 testsuite/md5-test.c create mode 100755 testsuite/pkcs1-conv-test create mode 100644 testsuite/pkcs1-test.c create mode 100644 testsuite/random-prime-test.c create mode 100644 testsuite/rsa-encrypt-test.c create mode 100644 testsuite/rsa-keygen-test.c create mode 100644 testsuite/rsa-test.c create mode 100644 testsuite/rsa2sexp-test.c create mode 100755 testsuite/run-tests create mode 100644 testsuite/serpent-test.c create mode 100755 testsuite/sexp-conv-test create mode 100644 testsuite/sexp-format-test.c create mode 100644 testsuite/sexp-test.c create mode 100644 testsuite/sexp2rsa-test.c create mode 100644 testsuite/sha1-huge-test.c create mode 100644 testsuite/sha1-test.c create mode 100644 testsuite/sha224-test.c create mode 100644 testsuite/sha256-test.c create mode 100644 testsuite/sha384-test.c create mode 100644 testsuite/sha512-test.c create mode 100755 testsuite/symbols-test create mode 100755 testsuite/teardown-env create mode 100644 testsuite/testutils.c create mode 100644 testsuite/testutils.h create mode 100644 testsuite/twofish-test.c create mode 100644 testsuite/yarrow-test.c create mode 100644 texinfo.tex create mode 100644 tools/Makefile.in create mode 100644 tools/getopt.c create mode 100644 tools/getopt.h create mode 100644 tools/getopt1.c create mode 100644 tools/input.c create mode 100644 tools/input.h create mode 100644 tools/misc.c create mode 100644 tools/misc.h create mode 100644 tools/nettle-lfib-stream.c create mode 100644 tools/output.c create mode 100644 tools/output.h create mode 100644 tools/parse.c create mode 100644 tools/parse.h create mode 100644 tools/pkcs1-conv.c create mode 100644 tools/sexp-conv.c create mode 100644 twofish-meta.c create mode 100644 twofish.c create mode 100644 twofish.h create mode 100644 write-be32.c create mode 100644 x86/aes-decrypt-internal.asm create mode 100644 x86/aes-encrypt-internal.asm create mode 100644 x86/aes.m4 create mode 100644 x86/arcfour-crypt.asm create mode 100644 x86/camellia-crypt-internal.asm create mode 100644 x86/machine.m4 create mode 100644 x86/md5-compress.asm create mode 100644 x86/sha1-compress.asm create mode 100644 x86_64/aes-decrypt-internal.asm create mode 100644 x86_64/aes-encrypt-internal.asm create mode 100644 x86_64/aes.m4 create mode 100644 x86_64/machine.m4 create mode 100644 x86_64/sha1-compress.asm create mode 100644 yarrow.h create mode 100644 yarrow256.c create mode 100644 yarrow_key_event.c diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..b021b48 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Please see the Nettle manual. diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..623b625 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, 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. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/COPYING.LIB b/COPYING.LIB new file mode 100644 index 0000000..2d2d780 --- /dev/null +++ b/COPYING.LIB @@ -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. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs must +be allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + + Copyright (C) + + 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. + + , 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 index 0000000..7df4d23 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,4976 @@ +2010-07-25 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * testsuite/dsa-test.c (test_main): Added test for dsa-sha256. + +2010-06-02 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * bignum-random-prime.c (miller_rabin_pocklington): Fixed broken + logic when Miller-rabin succeeds early. + +2010-04-09 Niels Möller + + * 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 + + * examples/nettle-benchmark.c (main): Benchmark sha224. + +2010-03-30 Niels Möller + + * 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 + + * 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 + + * configure.ac (asm_path): For x86_64, check if compiler is + generating 32-bit code. + +2010-03-27 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * Makefile.in (distdir): Include x86_64 assembler files. + +2010-01-20 Niels Möller + + * configure.ac: Check for mpz_powm_sec. + +2010-01-13 Niels Möller + + * 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 + + * tools/Makefile.in (pkcs1-conv$(EXEEXT)): Added dependency on + ../libhogweed.a. + +2009-10-19 Niels Möller + + * 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 + + * 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 + + * rsa2sexp.c (rsa_keypair_to_sexp): Changed default algorithm name + to "rsa-pkcs1". + +2009-09-20 Niels Möller + + * x86/sha1-compress.asm: Improved performance by 17% on AMD K7, + by letting loopmix scramble the instruction order. + +2009-09-15 Niels Möller + + * 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 + + * 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 + + * Released nettle-2.0. + +2009-06-04 Niels Möller + + * configure.ac: Set version to 2.0 + +2009-05-30 Niels Möller + + * 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 + + * nettle.texinfo: Changed license to public domain. + +2009-05-11 Niels Möller + + * nettle.texinfo: Fixes from Karl Berry. Added some more index + terms. + +2009-03-06 Niels Möller + + * 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 + + * 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 + + * Makefile.in ($(des_headers)): Create files in $(srcdir). + +2008-11-28 Niels Möller + + * testsuite/cxx-test.cxx: Include . + +2008-11-22 Niels Möller + + * 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 + + * examples/next-prime.c (main): Avoid using gmp_fprintf, to stay + compatible with gmp-3.1. + +2008-11-01 Niels Möller + + * 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 + + * 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 + + * tools/sexp-conv.c (main): Fixed file locking. + +2008-10-25 Niels Möller + + * configure.ac: Set version to 2.0rc1. + + * examples/Makefile.in (next-prime$(EXEEXT)): Added -lnettle to + linker. + +2008-10-24 Niels Möller + + * 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 + + * x86/arcfour-crypt.asm: Improved loop logic, and unrolled + loop twice. Gave a modest speedup. + +2008-09-15 Niels Möller + + * 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 + + * 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 + + * x86_64/sha1-compress.asm: Avoid using registers %rbx and %rbp, + which must be preserved. + +2008-09-08 Niels Möller + + * 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 + + * examples/eratosthenes.c (main): Rewrote block-wise sieving to + use less memory. New options -s and -v. + +2008-08-27 Niels Möller + + * 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 + + * 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 + + * examples/Makefile.in (SOURCES): Added next-prime.c. + +2008-01-05 Niels Möller + + * 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 + + * 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 + + * 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 + + * examples/read_rsa_key.c: Include stdlib.h. + +2007-06-02 Niels Möller + + * Makefile.in: Typo fixes to install targets, spotted by Magnus + Holmgren. + +2007-05-14 Niels Möller + + * 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 + + * Moved in CVS tree. Also renamed directory sparc to sparc32. + +2007-02-24 Niels Möller + + * Makefile.in (clean-here): Remove .lib directory. + (distclean-here): Remove machine.m4. + +2006-12-05 Niels Möller + + * 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 + + * configure.ac: Bumped version to 1.16. + + * Released nettle-1.15. + +2006-11-27 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * index.html: Added section on language bindings. + +2006-06-10 Niels Möller + + * configure.ac: Darwin shared library support, from Grant + Robinsson. + +2006-05-18 Niels Möller + + * 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 + Merged from the lsh experimental branch. + +2006-04-26 Niels Möller + + * 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 + + * 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 + + * tools/pkcs1-conv.c (read_pem): Fixed c99-style declaration. + Reported by Henrik Grubbström. + +2006-01-31 Niels Möller + + * examples/rsa-verify.c: Fixed typo in usage message. + +2005-12-05 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * testsuite/Makefile.in: Avoid using single-suffix rule to build + executables. + +2005-11-24 Niels Möller + + * 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 + + * testsuite/Makefile.in (DISTFILES): Added teardown-env. + * testsuite/teardown-env: New file. Delete files created by the + testsuite. + +2005-11-21 Niels Möller + + * testsuite/testutils.c (main): Fixed check for -v option. Spotted + by Goran K. + +2005-11-21 Niels Möller + + * ctr.h (CTR_CTX, CTR_CRYPT): Fixed bugs, spotted by Goran K. + +2005-11-20 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * testsuite/arcfour-test.c (test_main): New testcase with 512 + bytes of data. + +2005-10-19 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * x86/md5-compress.asm (REF): Fixed calculation of offset. + +2005-10-12 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * nettle.texinfo (RSA): Improved text about the RSA patent. + Use @documentencoding ISO-8859-1. + +2005-09-07 Niels Möller + + * 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 + + * tools/sexp-conv.c (main): With --hash, output a newline after + each hash. + +2005-07-02 Niels Möller + + * 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 + + * config.guess: Support Solaris on x86_64. Fix by Henrik + Grubbström. + +2005-01-03 Niels Möller + + * examples/io.h: Include RSA declarations only when public key + algorithms are enabled. Problem reported by Meilof Veeningen + . + +2004-12-07 Niels Möller + + * Makefile.in: Install directories, using $(INSTALL) -d, only if + they don't exist already. + +2004-12-05 Niels Möller + + * 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 + + * 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 + + * Makefile.in (aesdata, desdata): Commented out the explicit + targets. + (shadata): Avoid using $< in non-pattern rule. + +2004-12-01 Niels Möller + + * config.make.in: Added a default target. + +2004-11-29 Niels Möller + + * testsuite/Makefile.in: Use .$(OBJEXT). Explicitly set .SUFFIXES. + + * Makefile.in: Use .$(OBJEXT). + +2004-11-28 Niels Möller + + * 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 + + * configure.ac: Fixed typo, preventing the creation of dependency + files. + +2004-11-23 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * configure.ac: Bumped version to 1.13. + + * Released nettle-1.12. + +2004-11-04 Niels Möller + + * nettle.texinfo (UPDATED-FOR): Bumped to 1.12. + +2004-11-02 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + 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 + + * 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 + + * examples/rsa-encrypt-test: Avoid reading and executing a file at + the same time. + * examples/setup-env: Likewise. + +2004-10-06 Niels Möller + + * testsuite/symbols-test: Ignore __i686.get_pc_thunk.bx and + similar symbols. + +2004-10-05 Niels Möller + + * 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 + + * configure.ac (SHLIBLINK, SHLIBLIBS): On cygwin, linking needs + -Wl,--whole-archive $(OBJECTS) -Wl,--no-whole-archive $(LIBS). + +2004-09-22 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * testsuite/md5-test.c (test_main): Added collision, found in 2004. + (test_main): Added second collision. + +2004-08-23 Niels Möller + + * 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 + + * aesdata.c: Renamed log and ilog to gf2_log and gf2_exp. + +2004-04-07 Niels Möller + + * 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 + + * configure.ac: Use AC_CONFIG_AUX_DIR([.]). + +2004-03-18 Niels Möller + + * examples/io.c (read_file): Display a message if fopen fails. + +2004-03-05 Niels Möller + + * Released nettle-1.10. + + * configure.ac (SHLIBMINOR): Shared library version is now 2.2. + +2004-03-04 Niels Möller + + * testsuite/symbols-test: Pass -g flag to nm. + +2004-03-02 Niels Möller + + * configure.ac: Fixed EXEEXT workaround. + +2004-03-02 Niels Möller + + * configure.ac: Added workaround to get the correct $(EXEEXT)='' + when compiling with rntcl. + +2004-03-02 Niels Möller + + * 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 + + * examples/rsa-keygen.c, examples/rsa-encrypt.c, + examples/rsa-decrypt.c: Include "getopt.h" instead of . + + * 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 . + + * testsuite/testutils.c (main): Don't use getopt. Then we don't + need to include . + +2004-03-01 Niels Möller + + * 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 + + * 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 + + * 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 + + * pgp.h: Include nettle-types.h. + +2004-02-24 Niels Möller + + * testsuite/symbols-test: Allow symbols starting with double + underscores, like on darwin. + +2004-02-17 Niels Möller + + * 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 + + * Makefile.am (%.o: %.asm): Added comment about OSF1 make problem. + +2004-02-15 Niels Möller + + * testsuite/testutils.h: #include nettle-types.h instead of + inttypes.h. + +2004-02-12 Niels Möller + + * 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 + + * 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 + + * configure.ac: Bumped version number to 1.10. + +2004-02-07 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * configure.ac (AX_CREATE_STDINT_H): Also look for uint32_t and + friends in sys/types.h. + +2004-01-11 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * nettle-types.h: New (generated) file, to be used instead of + including 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 + + * yarrow256.c (yarrow256_seed): Use const for the seed_file input. + +2003-11-12 Niels Möller + + * 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 + + * 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 + + * 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 + + * testsuite/testutils.c (print_hex): Use const. + +2003-08-30 Niels Möller + + * md2.c, md2.h: Added reference to RFC 1319. + * md4.c, md4.h: Added reference to RFC 1320 + +2003-08-26 Niels Möller + + * 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 + + * 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 + + * rsa-encrypt.c (rsa_encrypt): Bugfix contributed by + leg@terra.com.br. + +2003-06-10 Niels Möller + + * Makefile.am (EXTRA_DIST): Distribute sha-example.c. + +2003-06-05 Niels Möller + + * Makefile.am (DISTCLEANFILES): Delete .s files. + +2003-05-27 Niels Möller + + * 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 + + * testsuite/symbols-test: Allow symbols to start with a dot. + +2003-05-14 Niels Möller + + * 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 + + * 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 + + * 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 . + + * Reordered includes in most or all .c-files. All should now + include config.h. + +2003-05-12 Niels Möller + + * configure.ac: Use LSH_FUNC_ALLOCA. + +2003-04-25 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * examples/nettle-benchmark.c (time_cipher): Don't use GNU C + non-constant initializers. + +2003-02-23 Niels Moller + + * configure.ac: Use LSH_GCC_ATTRIBUTES. + +2003-02-19 Niels Möller + + * acinclude.m4: Deleted file from cvs, use a link to lsh's + acinclude.m4 instead. + +2003-02-16 Niels Möller + + * Makefile.am (libnettleinclude_HEADERS): Added macros.h. + + * tools/Makefile.am (EXTRA_DIST): Added getopt.h. + +2003-02-14 Niels Möller + + * 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 + + * buffer.c (nettle_buffer_copy): Bug fix, it didn't return any + value. + +2003-02-11 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * tools/Makefile.am (LDADD): Add libnettle.a, for the dependency. + +2003-01-27 Niels Möller + + * 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 + + * 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 + + * 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 + + * testsuite/Makefile.am (CLEANFILES): Delete test.in, test1.out + and test2.out. + +2003-01-17 Niels Möller + + * examples/Makefile.am (AM_CPPFLAGS): Use AM_CPPFLAGS instead of + AM_CFLAGS. + * testsuite/Makefile.am (AM_CPPFLAGS): Likewise. + +2003-01-16 Niels Möller + + * testsuite/Makefile.am (check): Can't use quotes around + $(srcdir). + +2003-01-14 Niels Möller + + * 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 + + * 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 + + * tools/sexp-conv.c (parse_options): Initialize prefer_hex. + +2003-01-07 Niels Möller + + * Makefile.am (des_headers): Refer to the desdata binary using + $(EXEEXT). + +2003-01-01 Niels Möller + + * 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 + + * 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 + + * testsuite/Makefile.am (LDADD): Added path to ../libnettle.a, + which is redundant except for the dependency. + +2002-12-04 Niels Möller + + * 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 + + * buffer.c: Include assert.h. + +2002-11-21 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * testsuite/testutils.c (test_dsa_key): Bugfix for renamed DSA + constant (noted by James Ralston). + +2002-11-07 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * configure.ac: Fixed definitions using SHLIBMAJOR and SHLIBMINOR. + Also AC_SUBST SHLIBMAJOR and SHLIBMINOR. Reported by James + Ralston. + +2002-10-31 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * base64-encode.c (base64_encode_raw): Fixed null statement + amongst variable declarations, broke compilation for non C99 + compilers. + +2002-10-21 Niels Möller + + * examples/sexp-conv.c: New sexp conversion program. + +2002-10-21 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * examples/rsa-keygen.c: Use malloc, instead of asprintf. + +2002-10-03 Niels Möller + + * 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 + + * 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 + + * Makefile.am: Fixed assembler rules, and shared libraries. + + * configure.ac: Fixed the enable-shared option. + +2002-10-01 Niels Möller + + * 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 + + * 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 + + * 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 + + * sexp_format.c (sexp_format): Don't mix code and declarations. + +2002-09-29 Niels Möller + + * 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 + + * 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 + + * Makefile.am (DISTCLEANFILES): make distclean should delete the + assembler-related symlinks. + +2002-08-26 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * configure.ac (CFLAGS): Don't enable -Waggregate-return. + +2002-05-05 Niels Möller + + * configure.ac: Pass no arguments to AM_INIT_AUTOMAKE. + +2002-05-05 Niels Möller + + * configure.ac: Update for automake-1.6. + + * configure.ac: Renamed file, used to be configure.in. + +2002-03-20 Niels Möller + + * testsuite/run-tests (test_program): Added missing single quote. + +2002-03-20 Niels Möller + + * testsuite/run-tests (test_program): Test the exit status of the + right process. + +2002-03-19 Pontus Sköld + + * testsuite/run-tests: Removed /bin/bashisms to use with /bin/sh. + +2002-03-18 Niels Möller + + * 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 + + * configure.in (asm_path): AC_CONFIG_LINKS adds $srcdir + automatically. + +2002-03-14 Niels Möller + + * 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 + + * 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 + + * 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 + + * configure.in (asm_path): Renamed "path" to "asm_path". Also look + for a machine.m4. + +2002-02-16 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * x86/aes.asm, x86/aes_tables.asm: New assembler implementation by + Rafael Sevilla. + +2002-02-06 Niels Möller + + 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 + + * Released nettle-1.5. + +2002-01-31 Niels Möller + + * acinclude.m4: Commented out gmp-related macros, they're probably + not needed anymore. + +2002-01-31 Niels Möller + + * 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 + + * nettle.texinfo (Randomness): New subsection on Yarrow. + +2002-01-30 Niels Möller + + * nettle.texinfo (Randomness): New chapter. + Spell checking and ispell configuration. + + * md5.c: Added reference to RFC 1321. + +2002-01-24 Niels Möller + + * nettle.texinfo (Public-key algorithms): Minor fixes. + +2002-01-22 Niels Möller + + * 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 + + * 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 + + * hmac-sha1.c: New file. + +2002-01-14 Niels Möller + + * 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 + + * 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 + + 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 + + * 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 + + * 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 + + * 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 + + * bignum.c (nettle_mpz_get_str_256): Fixed handling of leading + zeroes. + +2001-12-05 Niels Möller + + * 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 + + * yarrow256.c (yarrow256_force_reseed): New function. + +2001-11-14 Niels Möller + + * 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 + + * 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 + + * yarrow.h: Deleted yarrow160 declarations. + +2001-11-02 Niels Möller + + * yarrow256.c (yarrow256_init): Fixed order of code and + declarations. + +2001-10-30 Niels Möller + + * 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 + + * testsuite/Makefile.am (EXTRA_DIST): Include rfc1750.txt in the + distribution. + +2001-10-14 Niels Möller + + * 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 + + * 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 + + * examples/nettle-benchmark.c: New benchmarking program. + +2001-10-10 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * testsuite/aes-test.m4: Added a comment with NIST test vectors. + +2001-10-04 Niels Möller + + * rsa.h, rsa-compat.h, yarrow.h: New files. + +2001-09-25 Niels Möller + + * Released version 1.0. + +2001-09-25 Niels Möller + + * 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 + + * des-compat.c (des_cbc_cksum): Bug fix, local variable was + declared in the middle of a block. + +2001-09-19 Niels Möller + + * nettle.texinfo (Compatibility functions): New section, + mentioning md5-compat.h and des-compat.h. + +2001-09-18 Niels Möller + + * index.html: New file. + +2001-09-16 Niels Möller + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * cbc.c, cbc.h: New files, for general CBC encryption. + + * des-compat.h: Added some prototypes. + +2001-09-05 Niels Möller + + * 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 + + * twofish.c (twofish_decrypt): Fixed for();-bug in the block-loop. + Spotted by Jean-Pierre. + (twofish_encrypt): Likewise. + +2001-07-03 Niels Möller + + * testsuite/testutils.c: Include string.h. + + * twofish.c: Include string.h. + +2001-06-17 Niels Möller + + * 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 , + not . + Include . + +2001-06-17 Niels Möller + + * Use , not . + + * 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 + + * 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 + + * 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 + + * Makefile.am (libnettle_a_SOURCES): Added serpent files. + +2001-06-12 Niels Möller + + * 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 + + * 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 + + * Initial checkin. diff --git a/INSTALL b/INSTALL new file mode 100644 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 index 0000000..ff15d74 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,431 @@ +# 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) \ + $(LIBTARGETS) @IF_SHARED@ $(SHLIBTARGETS) + +DOCTARGETS = nettle.info nettle.html nettle.pdf + +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 \ + des.c \ + des3.c des-compat.c \ + hmac.c hmac-md5.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 \ + 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.c serpent-meta.c \ + twofish.c twofish-meta.c \ + yarrow256.c yarrow_key_event.c \ + buffer.c buffer-init.c realloc.c \ + nettle-internal.c write-be32.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 \ + 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 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 + +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 COPYING.LIB INSTALL NEWS TODO ChangeLog \ + memxor.c $(des_headers) descore.README \ + aes-internal.h camellia-internal.h cast128_sboxes.h desinfo.h desCode.h \ + serpent_sboxes.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)) + +# FIXME: Do we really need to delete the archive first? +libnettle.a: $(nettle_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ $(nettle_OBJS) + $(RANLIB) $@ + +# FIXME: Do we really need to delete the archive first? +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) + +# .$(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 $@ + +# Installation +install-here: install-info install-headers install-static \ + @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_PROGRAM) $(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_PROGRAM) $(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 + +# Uninstall +uninstall-here: uninstall-info uninstall-headers uninstall-static \ + @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) + +# 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 *.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 index 0000000..e219630 --- /dev/null +++ b/NEWS @@ -0,0 +1,410 @@ +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 + + rather than + + #extern "C" { + #include + } + + 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 index 0000000..6e5efbb --- /dev/null +++ b/README @@ -0,0 +1,53 @@ +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 General Public License as published by the Free +Software Foundation. See the file COPYING for details. Most, but not +all, of Nettle can also be used under the terms of the GNU Lesser +General Public License; please read the Copyright section of the +manual if you want to exercise this option. + +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, using + + cvs -d :pserver:anonymous@cvs.lysator.liu.se:/cvsroot/lsh login + [ empty password ] + cvs -d :pserver:anonymous@cvs.lysator.liu.se:/cvsroot/lsh co nettle + +If you get it from cvs, you need to build it with + + ./.bootstrap && ./configure && make && make check + +You may want to subscribe to the nettle-bugs mailing list. See +. + + +Happy hacking, +/Niels Möller diff --git a/TODO b/TODO new file mode 100644 index 0000000..4d788b1 --- /dev/null +++ b/TODO @@ -0,0 +1,29 @@ +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. + + +Change the convention for declaring function pointers. Instead of for +example + + typedef void * + nettle_realloc_func(void *ctx, void *p, unsigned length); + +use + + typedef void + nettle_realloc_func(void *ctx, void *p, unsigned length); + +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 index 0000000..7263307 --- /dev/null +++ b/aclocal.m4 @@ -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 +#include + +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 + +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 +# 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 +# endif +# endif +#else /* defined __GNUC__ */ +# if HAVE_ALLOCA_H +# include +# 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 <&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 " section requires the +dnl existence of an include file 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 . In other enviroments +dnl we can use the inet-types in 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 " +dnl or "#include ", 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 " to obtain the stdint-types. +dnl +dnl Remember, if the system already had a valid , 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 + +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 ],[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 < +#else +#include + +/* .................... 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 <= 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 index 0000000..9dff166 --- /dev/null +++ b/aes-decrypt-internal.c @@ -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 + +#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 index 0000000..39b79c6 --- /dev/null +++ b/aes-decrypt.c @@ -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 + +#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 index 0000000..84ed6cf --- /dev/null +++ b/aes-encrypt-internal.c @@ -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 + +#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 index 0000000..000498d --- /dev/null +++ b/aes-encrypt-table.c @@ -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 index 0000000..19fe071 --- /dev/null +++ b/aes-encrypt.c @@ -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 + +#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 index 0000000..a1e8d02 --- /dev/null +++ b/aes-internal.h @@ -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 index 0000000..7b6fc5a --- /dev/null +++ b/aes-meta.c @@ -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 index 0000000..ec44118 --- /dev/null +++ b/aes-set-decrypt-key.c @@ -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 */ + +#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 index 0000000..9c60c03 --- /dev/null +++ b/aes-set-encrypt-key.c @@ -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 */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#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; ikeys[i] = key[i*4] + (key[i*4+1]<<8) + (key[i*4+2]<<16) + + (key[i*4+3]<<24); + } + + for (i=nk; ikeys[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 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 index 0000000..9077c54 --- /dev/null +++ b/aesdata.c @@ -0,0 +1,299 @@ +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#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 + +#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 index 0000000..d5f1467 --- /dev/null +++ b/arcfour-meta.c @@ -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 index 0000000..d833422 --- /dev/null +++ b/arcfour.c @@ -0,0 +1,78 @@ +/* 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 + +#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; +} + +void +arcfour_stream(struct arcfour_ctx *ctx, + unsigned length, uint8_t *dst) +{ + 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++ = ctx->S[ (si + sj) & 0xff ]; + } + ctx->i = i; ctx->j = j; +} + diff --git a/arcfour.h b/arcfour.h new file mode 100644 index 0000000..f8e6689 --- /dev/null +++ b/arcfour.h @@ -0,0 +1,71 @@ +/* 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 +#define arcfour_stream nettle_arcfour_stream + +/* 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 index 0000000..3401b9d --- /dev/null +++ b/arctwo-meta.c @@ -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 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 + +#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 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 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(, < +dnl>)dnl + +dnl Including files from the srcdir +define(, )dnl + +dnl Pseudo ops + +define(, +, +<.globl C_NAME($1) +C_NAME($1):>)>) + +define(, +,<>)>) + +dnl Argument to ALIGN is always logarithmic +dnl Can't use << operator with our choice of quote characters... +define(, +<.align ifelse(ALIGN_LOG,yes,$1,eval(2 ** $1))>) + +dnl Struct defining macros + +dnl STRUCTURE(prefix) +define(, , 0)define(, <$1>)>)dnl + +dnl STRUCT(name, size) +define(, +$1, SOFFSET)dnl + define(, eval(SOFFSET + ($2)))>)dnl + +dnl UCHAR(name) +define(, , 1)>)dnl + +dnl UNSIGNED(name) +define(, , 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 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 index 0000000..2689411 --- /dev/null +++ b/base16-decode.c @@ -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 +#include + +#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; ibits == 0; +} diff --git a/base16-encode.c b/base16-encode.c new file mode 100644 index 0000000..b2267ab --- /dev/null +++ b/base16-encode.c @@ -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 +#include + +#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<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; ibits == 0; +} diff --git a/base64-encode.c b/base64-encode.c new file mode 100644 index 0000000..6fc5e6b --- /dev/null +++ b/base64-encode.c @@ -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 +#include + +#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 index 0000000..608e7b6 --- /dev/null +++ b/base64-meta.c @@ -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 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 index 0000000..91ba8fd --- /dev/null +++ b/bignum-next-prime.c @@ -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 +/* Needed for alloca on freebsd */ +#include + +#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 index 0000000..bc2938f --- /dev/null +++ b/bignum-random-prime.c @@ -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 +#include + +#if RANDOM_PRIME_VERBOSE +#include +#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 index 0000000..dc2fd1c --- /dev/null +++ b/bignum-random.c @@ -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 + +#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 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 +#include + +#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>= 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 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 +#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 index 0000000..25c99c2 --- /dev/null +++ b/blowfish.c @@ -0,0 +1,409 @@ +/* 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. + */ + +/* NOTE: This file is distributed under the GPL, not the LGPL. */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 1998, 2001 + * Free Software Foundation, Inc, Ray Dassen, Niels Möller + * + * This file is part of GNUPG. + * + * GNUPG 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. + * + * GNUPG is distributed in the hope that 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 + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "blowfish.h" + +#include "macros.h" + +/* Initial keysetup state */ +static const struct blowfish_ctx +initial_ctx = +{ /* precomputed S boxes */ + { + { + 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 + }, { + 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 + }, { + 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 + }, { + 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 + } + }, + /* p constants */ + { + 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 code stored took the address of x, and + * then read the individual bytes depending on the endianness. But xr + * and xl ought to live in registers, so I'm not sure that really is a + * good way to do it. */ + +#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 *bc, uint32_t *ret_xl, uint32_t *ret_xr) +{ + uint32_t xl, xr; + + xl = *ret_xl; + xr = *ret_xr; + R(bc, xl, xr, 0); + R(bc, xr, xl, 1); + R(bc, xl, xr, 2); + R(bc, xr, xl, 3); + R(bc, xl, xr, 4); + R(bc, xr, xl, 5); + R(bc, xl, xr, 6); + R(bc, xr, xl, 7); + R(bc, xl, xr, 8); + R(bc, xr, xl, 9); + R(bc, xl, xr, 10); + R(bc, xr, xl, 11); + R(bc, xl, xr, 12); + R(bc, xr, xl, 13); + R(bc, xl, xr, 14); + R(bc, xr, xl, 15); + + xl ^= bc->p[_BLOWFISH_ROUNDS]; + xr ^= bc->p[_BLOWFISH_ROUNDS+1]; + + *ret_xl = xr; + *ret_xr = xl; +} + +static void +decrypt(const struct blowfish_ctx *bc, uint32_t *ret_xl, uint32_t *ret_xr ) +{ + uint32_t xl, xr; + + xl = *ret_xl; + xr = *ret_xr; + + R(bc, xl, xr, 17); + R(bc, xr, xl, 16); + R(bc, xl, xr, 15); + R(bc, xr, xl, 14); + R(bc, xl, xr, 13); + R(bc, xr, xl, 12); + R(bc, xl, xr, 11); + R(bc, xr, xl, 10); + R(bc, xl, xr, 9); + R(bc, xr, xl, 8); + R(bc, xl, xr, 7); + R(bc, xr, xl, 6); + R(bc, xl, xr, 5); + R(bc, xr, xl, 4); + R(bc, xl, xr, 3); + R(bc, xr, xl, 2); + + xl ^= bc->p[1]; + xr ^= bc->p[0]; + + *ret_xl = xr; + *ret_xr = xl; +} + +#undef F +#undef R + +void +blowfish_encrypt(const struct blowfish_ctx *bc, unsigned length, + uint8_t *outbuf, const uint8_t *inbuf) +{ + uint32_t d1, d2; + + FOR_BLOCKS(length, outbuf, inbuf, BLOWFISH_BLOCK_SIZE) + { + d1 = READ_UINT32(inbuf); + d2 = READ_UINT32(inbuf+ 4); + + encrypt( bc, &d1, &d2 ); + + WRITE_UINT32(outbuf, d1); + WRITE_UINT32(outbuf + 4, d2); + } +} + + +void +blowfish_decrypt(const struct blowfish_ctx *bc, unsigned length, + uint8_t *outbuf, const uint8_t *inbuf ) +{ + uint32_t d1, d2; + + FOR_BLOCKS(length, outbuf, inbuf, BLOWFISH_BLOCK_SIZE) + { + d1 = READ_UINT32(inbuf); + d2 = READ_UINT32(inbuf+ 4); + + decrypt( bc, &d1, &d2 ); + + WRITE_UINT32(outbuf, d1); + WRITE_UINT32(outbuf + 4, d2); + } +} + +int +blowfish_set_key(struct blowfish_ctx *ctx, + unsigned keylen, 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) % keylen] <<16 + | key[(j+2)%keylen] << 8 | key[(j+3)%keylen]; + + ctx->p[i] ^= data; + j = (j+4) % keylen; + } + + 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(i=0; i < 256; i += 2 ) + { + encrypt( ctx, &datal, &datar ); + ctx->s[0][i] = datal; + ctx->s[0][i+1] = datar; + } + for(i=0; i < 256; i += 2 ) + { + encrypt( ctx, &datal, &datar ); + ctx->s[1][i] = datal; + ctx->s[1][i+1] = datar; + } + for(i=0; i < 256; i += 2 ) + { + encrypt( ctx, &datal, &datar ); + ctx->s[2][i] = datal; + ctx->s[2][i+1] = datar; + } + for(i=0; i < 256; i += 2 ) + { + encrypt( ctx, &datal, &datar ); + ctx->s[3][i] = datal; + ctx->s[3][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 index 0000000..3775b4b --- /dev/null +++ b/blowfish.h @@ -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 index 0000000..1eccd7f --- /dev/null +++ b/buffer-init.c @@ -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 + +#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 index 0000000..4e96b55 --- /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 +#include +#include + +#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 index 0000000..466ad92 --- /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 index 0000000..c38c225 --- /dev/null +++ b/camellia-crypt-internal.c @@ -0,0 +1,139 @@ +/* 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 + +#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) + +#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) + +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 index 0000000..62c3435 --- /dev/null +++ b/camellia-crypt.c @@ -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 + +#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 index 0000000..f9d40fc --- /dev/null +++ b/camellia-internal.h @@ -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 index 0000000..68eef3d --- /dev/null +++ b/camellia-meta.c @@ -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 index 0000000..cd49c11 --- /dev/null +++ b/camellia-set-decrypt-key.c @@ -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 index 0000000..500128f --- /dev/null +++ b/camellia-set-encrypt-key.c @@ -0,0 +1,331 @@ +/* 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 + +#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) + +#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) + +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]; + + 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]); + } +} diff --git a/camellia-table.c b/camellia-table.c new file mode 100644 index 0000000..9245bc9 --- /dev/null +++ b/camellia-table.c @@ -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 index 0000000..f4f3e1e --- /dev/null +++ b/camellia.h @@ -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 index 0000000..5c15a08 --- /dev/null +++ b/cast128-meta.c @@ -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, 128); diff --git a/cast128.c b/cast128.c new file mode 100644 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 + * 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 + +#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 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 + * 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 index 0000000..4a1f10e --- /dev/null +++ b/cast128_sboxes.h @@ -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 + * 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 index 0000000..6bd9f9a --- /dev/null +++ b/cbc.c @@ -0,0 +1,161 @@ +/* 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 +#include +#include + +#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); + } +} + +/* Requires that dst != src */ +static void +cbc_decrypt_internal(void *ctx, nettle_crypt_func f, + unsigned block_size, uint8_t *iv, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + assert(length); + assert( !(length % block_size) ); + assert(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); +} + +/* Don't allocate any more space than this on the stack */ +#define CBC_BUFFER_LIMIT 4096 + +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) + cbc_decrypt_internal(ctx, f, block_size, iv, + length, dst, src); + else + { + /* We need a copy of the ciphertext, so we can't ECB decrypt in + * place. + * + * If length is small, we allocate a complete copy of src on the + * stack. Otherwise, we allocate a block 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. */ + + unsigned buffer_size; + + if (length <= CBC_BUFFER_LIMIT) + buffer_size = length; + else + buffer_size + = CBC_BUFFER_LIMIT - (CBC_BUFFER_LIMIT % block_size); + + { + TMP_DECL(buffer, uint8_t, CBC_BUFFER_LIMIT); + TMP_ALLOC(buffer, buffer_size); + + for ( ; length > buffer_size; + length -= buffer_size, dst += buffer_size, src += buffer_size) + { + memcpy(buffer, src, buffer_size); + cbc_decrypt_internal(ctx, f, block_size, iv, + buffer_size, dst, buffer); + } + /* Now, we have at most CBC_BUFFER_LIMIT octets left */ + memcpy(buffer, src, length); + + cbc_decrypt_internal(ctx, f, block_size, iv, + length, dst, buffer); + } + } +} + +#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 index 0000000..81a0525 --- /dev/null +++ b/cbc.h @@ -0,0 +1,75 @@ +/* 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)) + +#define CBC_ENCRYPT(self, f, length, dst, src) \ +(0 ? ((f)(&(self)->ctx, 0, NULL, NULL)) \ + : 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, NULL, NULL)) \ + : 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 index 0000000..c3bae20 --- /dev/null +++ b/config.guess @@ -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 . +# Please send patches to . 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 ." + +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 /* 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 + + 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 + #include + + 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 + 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 + #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 + #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' /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 + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # 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 < +# include +#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 + 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 +# 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 < 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 index 0000000..a45ad2a --- /dev/null +++ b/config.h.in @@ -0,0 +1,180 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* 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 and it should be used (not on Ultrix). + */ +#undef HAVE_ALLOCA_H + +/* 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 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 header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the 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 header file. */ +#undef HAVE_OPENSSL_AES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_BLOWFISH_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_CAST_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_DES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the 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 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 and . */ +#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 to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `int' if 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 does not define. */ +#undef size_t + +/* Define to `int' if doesn't define. */ +#undef uid_t + +/* AIX requires this to be the first thing in the file. */ +#ifndef __GNUC__ +# if HAVE_ALLOCA_H +# include +# 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 +# endif +# endif +#else /* defined __GNUC__ */ +# if HAVE_ALLOCA_H +# include +# endif +#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 + diff --git a/config.m4.in b/config.m4.in new file mode 100644 index 0000000..ec62573 --- /dev/null +++ b/config.m4.in @@ -0,0 +1,8 @@ +define(, <<@srcdir@>>)dnl +define(, <@ASM_SYMBOL_PREFIX@><$1>)dnl +define(, <@ASM_ELF_STYLE@>)dnl +define(, <@ASM_TYPE_FUNCTION@>)dnl +define(, <@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 index 0000000..152b42e --- /dev/null +++ b/config.make.in @@ -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 index 0000000..ba33103 --- /dev/null +++ b/config.sub @@ -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 . 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 ." + +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 index 0000000..f7d6767 --- /dev/null +++ b/configure @@ -0,0 +1,11909 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.61 for nettle 2.1. +# +# Report bugs to . +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 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=: + # Zsh 3.x and 4.x performs 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 + + + + +# PATH needs CR +# 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 + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +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.) +as_nl=' +' +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 + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +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 + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs 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 + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs 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_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. 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" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); 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 +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +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 +fi +echo >conf$$.file +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 +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=: +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 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, 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= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME='nettle' +PACKAGE_TARNAME='nettle' +PACKAGE_VERSION='2.1' +PACKAGE_STRING='nettle 2.1' +PACKAGE_BUGREPORT='nettle-bugs@lists.lysator.liu.se' + +ac_unique_file="arcfour.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +build +build_cpu +build_vendor +build_os +host +host_cpu +host_vendor +host_os +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +CXX +CXXFLAGS +ac_ct_CXX +CXX_TESTS +SET_MAKE +RANLIB +NM +OBJDUMP +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +DEP_INCLUDE +DEP_FLAGS +DEP_PROCESS +CCPIC +CCPIC_MAYBE +ASM_SYMBOL_PREFIX +ASM_ELF_STYLE +ASM_TYPE_FUNCTION +ASM_MARK_NOEXEC_STACK +ASM_ALIGN_LOG +SHLIBCFLAGS +LIBNETTLE_MAJOR +LIBNETTLE_MINOR +LIBNETTLE_FORLINK +LIBNETTLE_SONAME +LIBNETTLE_FILE +LIBNETTLE_LINK +LIBNETTLE_LIBS +LIBHOGWEED_MAJOR +LIBHOGWEED_MINOR +LIBHOGWEED_FORLINK +LIBHOGWEED_SONAME +LIBHOGWEED_FILE +LIBHOGWEED_LINK +LIBHOGWEED_LIBS +M4 +CPP +GREP +EGREP +ALLOCA +LIBOBJS +IF_HOGWEED +IF_SHARED +OPENSSL_LIBFLAGS +LTLIBOBJS' +ac_subst_files='' + 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 +# 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=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_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=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_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$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_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=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 ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + 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'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +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 + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +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 + 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 .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# 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 -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + 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 .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + 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.1 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.1:";; + esac + cat <<\_ACEOF + +Optional Features: + --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 + --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 if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + 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 . +_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" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`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 + 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.1 +generated by GNU Autoconf 2.61 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 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 +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.1, which was +generated by GNU Autoconf 2.61. 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=. + 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=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$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 + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export 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 + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + 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_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_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 + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + 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'; { (exit 1); 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 + +# 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 + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +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,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +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 + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`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. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +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 + + + + +# 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 + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in . \"$srcdir\"/." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in . \"$srcdir\"/." >&2;} + { (exit 1); exit 1; }; } +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=0 + +LIBHOGWEED_MAJOR=2 +LIBHOGWEED_MINOR=0 + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 +echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} + { (exit 1); exit 1; }; } + +{ echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6; } +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 +echo "$as_me: error: invalid value of canonical build" >&2;} + { (exit 1); exit 1; }; };; +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 + + +{ echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6; } +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 +echo "$as_me: error: invalid value of canonical host" >&2;} + { (exit 1); exit 1; }; };; +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 + + +{ echo "$as_me:$LINENO: checking for -R flag" >&5 +echo $ECHO_N "checking for -R flag... $ECHO_C" >&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 + { echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6; } +else + { echo "$as_me:$LINENO: result: using $RPATHFLAG" >&5 +echo "${ECHO_T}using $RPATHFLAG" >&6; } +fi + +RPATH_CANDIDATE_REAL_DIRS='' +RPATH_CANDIDATE_DIRS='' + +{ echo "$as_me:$LINENO: result: Searching for libraries" >&5 +echo "${ECHO_T}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 + { echo "$as_me:$LINENO: checking $d" >&5 +echo $ECHO_N "checking $d... $ECHO_C" >&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 + { echo "$as_me:$LINENO: result: already added" >&5 +echo "${ECHO_T}already added" >&6; } + else + { echo "$as_me:$LINENO: result: added" >&5 +echo "${ECHO_T}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 + { echo "$as_me:$LINENO: result: not found" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out 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. +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; 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 | *.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 + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; 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 | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; 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 ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$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 +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* 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" + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +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) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +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 + + +# 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 + { echo "$as_me:$LINENO: Compiling with rntcl; clearing EXEEXT and disabling assembler" >&5 +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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $CXX" >&5 +echo "${ECHO_T}$CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 +echo "${ECHO_T}$ac_ct_CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C++ compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; } +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 +{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; } +GXX=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 +echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CXXFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 +echo "${ECHO_T}$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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + CXX_TESTS='cxx-test$(EXEEXT)' +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + + +{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } +set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&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 + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + SET_MAKE= +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $NM" >&5 +echo "${ECHO_T}$NM" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $ac_ct_NM" >&5 +echo "${ECHO_T}$ac_ct_NM" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_NM" = x; then + NM="strings" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_OBJDUMP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $OBJDUMP" >&5 +echo "${ECHO_T}$OBJDUMP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $ac_ct_OBJDUMP" >&5 +echo "${ECHO_T}$ac_ct_OBJDUMP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&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 + { { echo "$as_me:$LINENO: error: the C compiler doesn't handle ANSI-C" >&5 +echo "$as_me: error: the C compiler doesn't handle ANSI-C" >&2;} + { (exit 1); exit 1; }; } #' +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. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +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 +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$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. +{ echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5 +echo $ECHO_N "checking for a thread-safe mkdir -p... $ECHO_C" >&6; } +if test -z "$MKDIR_P"; then + if test "${ac_cv_path_mkdir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 + + 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. + test -d ./--version && rmdir ./--version + MKDIR_P="$ac_install_sh -d" + fi +fi +{ echo "$as_me:$LINENO: result: $MKDIR_P" >&5 +echo "${ECHO_T}$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 + { echo "$as_me:$LINENO: WARNING: Dependency tracking disabled, gcc-3.x is needed" >&5 +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 + { echo "$as_me:$LINENO: WARNING: Dependency tracking disabled" >&5 +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 be setting CFLAGS. +ABI=standard + +case "$host_cpu" in + x86_64 | amd64) + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#if defined(__x86_64__) || defined(__arch64__) +#error 64-bit x86 +#endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + + ABI=32 + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + + ABI=64 + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + *sparc*) + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#if defined(__sparcv9) || defined(__arch64__) +#error 64-bit sparc +#endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + + ABI=32 + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + + ABI=64 + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; +esac + +if test "x$ABI" != xstandard ; then + { echo "$as_me:$LINENO: Compiler uses $ABI-bit ABI. To change, set CC." >&5 +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' + ;; + # According to the fhs, all architectures except IA64 + # puts 32-bit libraries in lib, and 64-bit in lib64. + *:linux*:32) + libdir='${exec_prefix}/lib' + ;; + *:linux*:64) + libdir='${exec_prefix}/lib64' + ;; + # 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' + ;; + *) + { echo "$as_me:$LINENO: WARNING: Don't know where to install $ABI-bit libraries on this system." >&5 +echo "$as_me: WARNING: Don't know where to install $ABI-bit libraries on this system." >&2;}; #' + + esac + { echo "$as_me:$LINENO: Libraries to be installed in $libdir." >&5 +echo "$as_me: Libraries to be installed in $libdir." >&6;} + fi +fi + +# Select assembler code +asm_path= +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 + +# echo "enable_assembler: $enable_assembler, asm_path: $asm_path" + +if test "x$enable_assembler" = xyes ; then + if test -n "$asm_path"; then + { echo "$as_me:$LINENO: Looking for assembler files in $asm_path/." >&5 +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 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 + { echo "$as_me:$LINENO: WARNING: No assembler files found." >&5 +echo "$as_me: WARNING: No assembler files found." >&2;} + fi + fi +fi + +{ echo "$as_me:$LINENO: checking CCPIC" >&5 +echo $ECHO_N "checking CCPIC... $ECHO_C" >&6; } +if test "${lsh_cv_sys_ccpic+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +exit(0); + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + lsh_cv_sys_ccpic="$CCPIC" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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" +{ echo "$as_me:$LINENO: result: $CCPIC" >&5 +echo "${ECHO_T}$CCPIC" >&6; } + + +SHLIBCFLAGS="$CCPIC" + +case "$host_os" in + 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_LIBFILE) -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_LIBFILE) -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='' + ;; + *) + 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 + { echo "$as_me:$LINENO: checking if globals are prefixed by underscore" >&5 +echo $ECHO_N "checking if globals are prefixed by underscore... $ECHO_C" >&6; } +if test "${nettle_cv_asm_underscore+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Default is no underscore + nettle_cv_asm_underscore=no + cat >conftest.$ac_ext <<_ACEOF +int a_global_symbol; +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; 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 + { echo "$as_me:$LINENO: WARNING: nm doesn't list a_global_symbol at all" >&5 +echo "$as_me: WARNING: nm doesn't list a_global_symbol at all" >&2;} + fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: WARNING: test program with a single global could not be compiled!?" >&5 +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 +{ echo "$as_me:$LINENO: result: $nettle_cv_asm_underscore" >&5 +echo "${ECHO_T}$nettle_cv_asm_underscore" >&6; } + if test x$nettle_cv_asm_underscore = xyes ; then + ASM_SYMBOL_PREFIX='_' + fi + + { echo "$as_me:$LINENO: checking if we should use a .note.GNU-stack section" >&5 +echo $ECHO_N "checking if we should use a .note.GNU-stack section... $ECHO_C" >&6; } +if test "${nettle_cv_asm_gnu_stack+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Default + nettle_cv_asm_gnu_stack=no + + cat >conftest.c <&5 + (eval $nettle_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; 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 +{ echo "$as_me:$LINENO: result: $nettle_cv_asm_gnu_stack" >&5 +echo "${ECHO_T}$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 + + { echo "$as_me:$LINENO: checking for ELF-style .type,%function pseudo-ops" >&5 +echo $ECHO_N "checking for ELF-style .type,%function pseudo-ops... $ECHO_C" >&6; } +if test "${nettle_cv_asm_type_percent_function+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.s <&5 + (eval $gmp_assemble) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; 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 +{ echo "$as_me:$LINENO: result: $nettle_cv_asm_type_percent_function" >&5 +echo "${ECHO_T}$nettle_cv_asm_type_percent_function" >&6; } + + { echo "$as_me:$LINENO: checking for ELF-style .type,#function pseudo-ops" >&5 +echo $ECHO_N "checking for ELF-style .type,#function pseudo-ops... $ECHO_C" >&6; } +if test "${nettle_cv_asm_type_hash_function+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.s <&5 + (eval $gmp_assemble) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; 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 +{ echo "$as_me:$LINENO: result: $nettle_cv_asm_type_hash_function" >&5 +echo "${ECHO_T}$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 + { echo "$as_me:$LINENO: checking if .align assembly directive is logarithmic" >&5 +echo $ECHO_N "checking if .align assembly directive is logarithmic... $ECHO_C" >&6; } +if test "${nettle_cv_asm_align_log+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.s <&5 + (eval $gmp_assemble) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; 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 +{ echo "$as_me:$LINENO: result: $nettle_cv_asm_align_log" >&5 +echo "${ECHO_T}$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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_M4+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $M4" >&5 +echo "${ECHO_T}$M4" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + +# Checks for typedefs, structures, and compiler characteristics. +{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_const=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for inline" >&5 +echo $ECHO_N "checking for inline... $ECHO_C" >&6; } +if test "${ac_cv_c_inline+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_inline=$ac_kw +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 +echo "${ECHO_T}$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 +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&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 + echo $ECHO_N "(cached) $ECHO_C" >&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 to if __STDC__ is defined, since + # 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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f 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 +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$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 to if __STDC__ is defined, since + # 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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +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 + + +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + 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 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + 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 + ac_count=`expr $ac_count + 1` + 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 + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + 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 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + 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 + ac_count=`expr $ac_count + 1` + 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 + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_EGREP=$EGREP +fi + + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5 +echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6; } +if test "${ac_cv_type_uid_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_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 +{ echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 +echo "${ECHO_T}$ac_cv_type_uid_t" >&6; } +if test $ac_cv_type_uid_t = no; then + +cat >>confdefs.h <<\_ACEOF +#define uid_t int +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define gid_t int +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#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 +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +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=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +{ echo "$as_me:$LINENO: checking for size_t" >&5 +echo $ECHO_N "checking for size_t... $ECHO_C" >&6; } +if test "${ac_cv_type_size_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef size_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_size_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_size_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6; } +if test $ac_cv_type_size_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 +echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6; } +if test "${ac_cv_header_time+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_time=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_time=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 +echo "${ECHO_T}$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +cat >>confdefs.h <<\_ACEOF +#define TIME_WITH_SYS_TIME 1 +_ACEOF + +fi + +# Used by eratosthenes.c +{ echo "$as_me:$LINENO: checking for long" >&5 +echo $ECHO_N "checking for long... $ECHO_C" >&6; } +if test "${ac_cv_type_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef long ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_long=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_long=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5 +echo "${ECHO_T}$ac_cv_type_long" >&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. +{ echo "$as_me:$LINENO: checking size of long" >&5 +echo $ECHO_N "checking size of long... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_long=$ac_lo;; +'') if test "$ac_cv_type_long" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (long) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (long) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_long=0 + fi ;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_long=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_long" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (long) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (long) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_long=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 +echo "${ECHO_T}$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=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ----------------------------------------------- ## +## Report this to nettle-bugs@lists.lysator.liu.se ## +## ----------------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `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! +{ echo "$as_me:$LINENO: checking for working alloca.h" >&5 +echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6; } +if test "${ac_cv_working_alloca_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +char *p = (char *) alloca (2 * sizeof (int)); + if (p) return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_working_alloca_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_working_alloca_h=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5 +echo "${ECHO_T}$ac_cv_working_alloca_h" >&6; } +if test $ac_cv_working_alloca_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ALLOCA_H 1 +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for alloca" >&5 +echo $ECHO_N "checking for alloca... $ECHO_C" >&6; } +if test "${ac_cv_func_alloca_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# ifdef _MSC_VER +# include +# define alloca _alloca +# else +# ifdef HAVE_ALLOCA_H +# include +# 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 +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_alloca_works=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_alloca_works=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5 +echo "${ECHO_T}$ac_cv_func_alloca_works" >&6; } + +if test $ac_cv_func_alloca_works = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ALLOCA 1 +_ACEOF + +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 + +cat >>confdefs.h <<\_ACEOF +#define C_ALLOCA 1 +_ACEOF + + +{ echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5 +echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6; } +if test "${ac_cv_os_cray+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 +{ echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5 +echo "${ECHO_T}$ac_cv_os_cray" >&6; } +if test $ac_cv_os_cray = yes; then + for ac_func in _getb67 GETB67 getb67; do + as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* 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 $ac_func (); +/* 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_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + +cat >>confdefs.h <<_ACEOF +#define CRAY_STACKSEG_END $ac_func +_ACEOF + + break +fi + + done +fi + +{ echo "$as_me:$LINENO: checking stack direction for C alloca" >&5 +echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6; } +if test "${ac_cv_c_stack_direction+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_c_stack_direction=0 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_stack_direction=1 +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_c_stack_direction=-1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5 +echo "${ECHO_T}$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 +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ----------------------------------------------- ## +## Report this to nettle-bugs@lists.lysator.liu.se ## +## ----------------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + +# Needed by the supplied memcmp.c +{ echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 +echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6; } +if test "${ac_cv_c_bigendian+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # See if sys/param.h defines the BYTE_ORDER macro. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +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 +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + # It does; now see whether it defined to BIG_ENDIAN or not. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian +#endif + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_bigendian=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_bigendian=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # It does not; compile a test program. +if test "$cross_compiling" = yes; then + # try to guess the endianness by grepping values into an object file + ac_cv_c_bigendian=unknown + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 }; +void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } +short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } +int +main () +{ + _ascii (); _ebcdic (); + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; 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 +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 +echo "${ECHO_T}$ac_cv_c_bigendian" >&6; } +case $ac_cv_c_bigendian in + yes) + +cat >>confdefs.h <<\_ACEOF +#define WORDS_BIGENDIAN 1 +_ACEOF + ;; + no) + ;; + *) + { { echo "$as_me:$LINENO: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&5 +echo "$as_me: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} + { (exit 1); exit 1; }; } ;; +esac + + +for ac_func in memxor +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* 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 $ac_func (); +/* 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_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + case " $LIBOBJS " in + *" $ac_func.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" + ;; +esac + +fi +done + + + +{ echo "$as_me:$LINENO: checking for __attribute__" >&5 +echo $ECHO_N "checking for __attribute__... $ECHO_C" >&6; } +if test "${lsh_cv_c_attribute+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include + +static void foo(void) __attribute__ ((noreturn)); + +static void __attribute__ ((noreturn)) +foo(void) +{ + exit(1); +} + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + lsh_cv_c_attribute=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + lsh_cv_c_attribute=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $lsh_cv_c_attribute" >&5 +echo "${ECHO_T}$lsh_cv_c_attribute" >&6; } + + + +if test "x$lsh_cv_c_attribute" = "xyes"; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_GCC_ATTRIBUTE 1 +_ACEOF + +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 ------------------------------------- +{ echo "$as_me:$LINENO: checking for stdint types" >&5 +echo $ECHO_N "checking for stdint types... $ECHO_C" >&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 + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS="" +old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS="" +old_CFLAGS="$CFLAGS" ; CFLAGS="" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +int_least32_t v = 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_stdint_result="(assuming C99 compatible system)" + ac_cv_header_stdint_t="stdint.h"; +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + { echo "$as_me:$LINENO: result: (are you sure you want them in ./stdint.h?)" >&5 +echo "${ECHO_T}(are you sure you want them in ./stdint.h?)" >&6; } +elif test "$ac_stdint_h" = "inttypes.h" ; then + { echo "$as_me:$LINENO: result: (are you sure you want them in ./inttypes.h?)" >&5 +echo "${ECHO_T}(are you sure you want them in ./inttypes.h?)" >&6; } +elif test "_$ac_cv_header_stdint_t" = "_" ; then + { echo "$as_me:$LINENO: result: (putting them into $ac_stdint_h)$v" >&5 +echo "${ECHO_T}(putting them into $ac_stdint_h)$v" >&6; } +else + ac_cv_header_stdint="$ac_cv_header_stdint_t" + { echo "$as_me:$LINENO: result: $ac_cv_header_stdint (shortcircuit)" >&5 +echo "${ECHO_T}$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)" +{ echo "$as_me:$LINENO: checking for stdint uintptr_t" >&5 +echo $ECHO_N "checking for stdint uintptr_t... $ECHO_C" >&6; } +if test "${ac_cv_header_stdint_x+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + ac_cv_header_stdint_x="" # the 1997 typedefs (inttypes.h) + { echo "$as_me:$LINENO: result: (..)" >&5 +echo "${ECHO_T}(..)" >&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 + { echo "$as_me:$LINENO: checking for uintptr_t" >&5 +echo $ECHO_N "checking for uintptr_t... $ECHO_C" >&6; } +if test "${ac_cv_type_uintptr_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$i> + +typedef uintptr_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_uintptr_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_uintptr_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_uintptr_t" >&5 +echo "${ECHO_T}$ac_cv_type_uintptr_t" >&6; } +if test $ac_cv_type_uintptr_t = yes; then + ac_cv_header_stdint_x=$i +else + continue +fi + + { echo "$as_me:$LINENO: checking for uint64_t" >&5 +echo $ECHO_N "checking for uint64_t... $ECHO_C" >&6; } +if test "${ac_cv_type_uint64_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include<$i> + +typedef uint64_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_uint64_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_uint64_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_uint64_t" >&5 +echo "${ECHO_T}$ac_cv_type_uint64_t" >&6; } +if test $ac_cv_type_uint64_t = yes; then + and64="/uint64_t" +else + and64="" +fi + + ac_cv_stdint_result="(seen uintptr_t$and64 in $i)" + break; + done + { echo "$as_me:$LINENO: checking for stdint uintptr_t" >&5 +echo $ECHO_N "checking for stdint uintptr_t... $ECHO_C" >&6; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdint_x" >&5 +echo "${ECHO_T}$ac_cv_header_stdint_x" >&6; } + +if test "_$ac_cv_header_stdint_x" = "_" ; then +{ echo "$as_me:$LINENO: checking for stdint uint32_t" >&5 +echo $ECHO_N "checking for stdint uint32_t... $ECHO_C" >&6; } +if test "${ac_cv_header_stdint_o+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + ac_cv_header_stdint_o="" # the 1995 typedefs (sys/inttypes.h) + { echo "$as_me:$LINENO: result: (..)" >&5 +echo "${ECHO_T}(..)" >&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 + { echo "$as_me:$LINENO: checking for uint32_t" >&5 +echo $ECHO_N "checking for uint32_t... $ECHO_C" >&6; } +if test "${ac_cv_type_uint32_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$i> + +typedef uint32_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_uint32_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_uint32_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_uint32_t" >&5 +echo "${ECHO_T}$ac_cv_type_uint32_t" >&6; } +if test $ac_cv_type_uint32_t = yes; then + ac_cv_header_stdint_o=$i +else + continue +fi + + { echo "$as_me:$LINENO: checking for uint64_t" >&5 +echo $ECHO_N "checking for uint64_t... $ECHO_C" >&6; } +if test "${ac_cv_type_uint64_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include<$i> + +typedef uint64_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_uint64_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_uint64_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_uint64_t" >&5 +echo "${ECHO_T}$ac_cv_type_uint64_t" >&6; } +if test $ac_cv_type_uint64_t = yes; then + and64="/uint64_t" +else + and64="" +fi + + ac_cv_stdint_result="(seen uint32_t$and64 in $i)" + break; + done + { echo "$as_me:$LINENO: checking for stdint uint32_t" >&5 +echo $ECHO_N "checking for stdint uint32_t... $ECHO_C" >&6; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdint_o" >&5 +echo "${ECHO_T}$ac_cv_header_stdint_o" >&6; } +fi + +if test "_$ac_cv_header_stdint_x" = "_" ; then +if test "_$ac_cv_header_stdint_o" = "_" ; then +{ echo "$as_me:$LINENO: checking for stdint u_int32_t" >&5 +echo $ECHO_N "checking for stdint u_int32_t... $ECHO_C" >&6; } +if test "${ac_cv_header_stdint_u+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + ac_cv_header_stdint_u="" # the BSD typedefs (sys/types.h) + { echo "$as_me:$LINENO: result: (..)" >&5 +echo "${ECHO_T}(..)" >&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 + { echo "$as_me:$LINENO: checking for u_int32_t" >&5 +echo $ECHO_N "checking for u_int32_t... $ECHO_C" >&6; } +if test "${ac_cv_type_u_int32_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$i> + +typedef u_int32_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_u_int32_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_u_int32_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_u_int32_t" >&5 +echo "${ECHO_T}$ac_cv_type_u_int32_t" >&6; } +if test $ac_cv_type_u_int32_t = yes; then + ac_cv_header_stdint_u=$i +else + continue +fi + + { echo "$as_me:$LINENO: checking for u_int64_t" >&5 +echo $ECHO_N "checking for u_int64_t... $ECHO_C" >&6; } +if test "${ac_cv_type_u_int64_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include<$i> + +typedef u_int64_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_u_int64_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_u_int64_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_u_int64_t" >&5 +echo "${ECHO_T}$ac_cv_type_u_int64_t" >&6; } +if test $ac_cv_type_u_int64_t = yes; then + and64="/u_int64_t" +else + and64="" +fi + + ac_cv_stdint_result="(seen u_int32_t$and64 in $i)" + break; + done + { echo "$as_me:$LINENO: checking for stdint u_int32_t" >&5 +echo $ECHO_N "checking for stdint u_int32_t... $ECHO_C" >&6; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdint_u" >&5 +echo "${ECHO_T}$ac_cv_header_stdint_u" >&6; } +fi fi + +if test "_$ac_cv_header_stdint_x" = "_" ; then + { echo "$as_me:$LINENO: checking for stdint datatype model" >&5 +echo $ECHO_N "checking for stdint datatype model... $ECHO_C" >&6; } + { echo "$as_me:$LINENO: result: (..)" >&5 +echo "${ECHO_T}(..)" >&6; } + { echo "$as_me:$LINENO: checking for char" >&5 +echo $ECHO_N "checking for char... $ECHO_C" >&6; } +if test "${ac_cv_type_char+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef char ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_char=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_char=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_char" >&5 +echo "${ECHO_T}$ac_cv_type_char" >&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. +{ echo "$as_me:$LINENO: checking size of char" >&5 +echo $ECHO_N "checking size of char... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_char+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef char ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef char ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef char ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef char ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef char ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_char=$ac_lo;; +'') if test "$ac_cv_type_char" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (char) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (char) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_char=0 + fi ;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef char ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_char=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_char" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (char) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (char) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_char=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_char" >&5 +echo "${ECHO_T}$ac_cv_sizeof_char" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_CHAR $ac_cv_sizeof_char +_ACEOF + + + { echo "$as_me:$LINENO: checking for short" >&5 +echo $ECHO_N "checking for short... $ECHO_C" >&6; } +if test "${ac_cv_type_short+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef short ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_short=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_short=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_short" >&5 +echo "${ECHO_T}$ac_cv_type_short" >&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. +{ echo "$as_me:$LINENO: checking size of short" >&5 +echo $ECHO_N "checking size of short... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_short+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_short=$ac_lo;; +'') if test "$ac_cv_type_short" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (short) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (short) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_short=0 + fi ;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef short ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_short=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_short" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (short) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (short) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_short=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_short" >&5 +echo "${ECHO_T}$ac_cv_sizeof_short" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_SHORT $ac_cv_sizeof_short +_ACEOF + + + { echo "$as_me:$LINENO: checking for int" >&5 +echo $ECHO_N "checking for int... $ECHO_C" >&6; } +if test "${ac_cv_type_int+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef int ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_int=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_int=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5 +echo "${ECHO_T}$ac_cv_type_int" >&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. +{ echo "$as_me:$LINENO: checking size of int" >&5 +echo $ECHO_N "checking size of int... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_int+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_int=$ac_lo;; +'') if test "$ac_cv_type_int" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (int) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_int=0 + fi ;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef int ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_int=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_int" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (int) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_int=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5 +echo "${ECHO_T}$ac_cv_sizeof_int" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INT $ac_cv_sizeof_int +_ACEOF + + + { echo "$as_me:$LINENO: checking for long" >&5 +echo $ECHO_N "checking for long... $ECHO_C" >&6; } +if test "${ac_cv_type_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef long ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_long=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_long=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5 +echo "${ECHO_T}$ac_cv_type_long" >&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. +{ echo "$as_me:$LINENO: checking size of long" >&5 +echo $ECHO_N "checking size of long... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_long=$ac_lo;; +'') if test "$ac_cv_type_long" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (long) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (long) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_long=0 + fi ;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_long=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_long" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (long) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (long) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_long=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 +echo "${ECHO_T}$ac_cv_sizeof_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + + { echo "$as_me:$LINENO: checking for void*" >&5 +echo $ECHO_N "checking for void*... $ECHO_C" >&6; } +if test "${ac_cv_type_voidp+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef void* ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_voidp=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_voidp=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_voidp" >&5 +echo "${ECHO_T}$ac_cv_type_voidp" >&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. +{ echo "$as_me:$LINENO: checking size of void*" >&5 +echo $ECHO_N "checking size of void*... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_voidp+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef void* ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef void* ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef void* ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef void* ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef void* ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_voidp=$ac_lo;; +'') if test "$ac_cv_type_voidp" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (void*) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (void*) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_voidp=0 + fi ;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef void* ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_voidp=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_voidp" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (void*) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (void*) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_voidp=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_voidp" >&5 +echo "${ECHO_T}$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 + { echo "$as_me:$LINENO: result: combined for stdint datatype model... $name" >&5 +echo "${ECHO_T}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 + +{ echo "$as_me:$LINENO: checking for extra inttypes in chosen header" >&5 +echo $ECHO_N "checking for extra inttypes in chosen header... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: ($ac_cv_header_stdint)" >&5 +echo "${ECHO_T}($ac_cv_header_stdint)" >&6; } +unset ac_cv_type_int_least32_t +unset ac_cv_type_int_fast32_t +{ echo "$as_me:$LINENO: checking for int_least32_t" >&5 +echo $ECHO_N "checking for int_least32_t... $ECHO_C" >&6; } +if test "${ac_cv_type_int_least32_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_cv_header_stdint> + +typedef int_least32_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_int_least32_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_int_least32_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_int_least32_t" >&5 +echo "${ECHO_T}$ac_cv_type_int_least32_t" >&6; } + +{ echo "$as_me:$LINENO: checking for int_fast32_t" >&5 +echo $ECHO_N "checking for int_fast32_t... $ECHO_C" >&6; } +if test "${ac_cv_type_int_fast32_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include<$ac_cv_header_stdint> + +typedef int_fast32_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_int_fast32_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_int_fast32_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_int_fast32_t" >&5 +echo "${ECHO_T}$ac_cv_type_int_fast32_t" >&6; } + +{ echo "$as_me:$LINENO: checking for intmax_t" >&5 +echo $ECHO_N "checking for intmax_t... $ECHO_C" >&6; } +if test "${ac_cv_type_intmax_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_cv_header_stdint> + +typedef intmax_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_intmax_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_intmax_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_intmax_t" >&5 +echo "${ECHO_T}$ac_cv_type_intmax_t" >&6; } + + +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 + +{ echo "$as_me:$LINENO: result: make use of $ac_cv_header_stdint in $ac_stdint_h $ac_cv_stdint_result" >&5 +echo "${ECHO_T}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. +{ echo "$as_me:$LINENO: checking for fcntl file locking" >&5 +echo $ECHO_N "checking for fcntl file locking... $ECHO_C" >&6; } +if test "${nettle_cv_fcntl_locking+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_UNISTD_H +# include +#endif +#include + +int +main () +{ + +int op = F_SETLKW; +struct flock fl; + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + nettle_cv_fcntl_locking=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + nettle_cv_fcntl_locking=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $nettle_cv_fcntl_locking" >&5 +echo "${ECHO_T}$nettle_cv_fcntl_locking" >&6; } + + + +if test "x$nettle_cv_fcntl_locking" = "xyes" ; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_FCNTL_LOCKING 1 +_ACEOF + +fi + +# Checks for libraries + +{ echo "$as_me:$LINENO: checking for __gmpz_getlimbn in -lgmp" >&5 +echo $ECHO_N "checking for __gmpz_getlimbn in -lgmp... $ECHO_C" >&6; } +if test "${ac_cv_lib_gmp___gmpz_getlimbn+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgmp $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_gmp___gmpz_getlimbn=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_gmp___gmpz_getlimbn=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_gmp___gmpz_getlimbn" >&5 +echo "${ECHO_T}$ac_cv_lib_gmp___gmpz_getlimbn" >&6; } +if test $ac_cv_lib_gmp___gmpz_getlimbn = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBGMP 1 +_ACEOF + + LIBS="-lgmp $LIBS" + +else + { echo "$as_me:$LINENO: WARNING: GNU MP not found, or not 3.1 or up, see http://www.swox.com/gmp. +Support for public key algorithms will be unavailable." >&5 +echo "$as_me: WARNING: GNU MP not found, or not 3.1 or up, see http://www.swox.com/gmp. +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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +int main(int argc, char **argv) { return 0; } +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_success=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_success=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + + if test $ac_success = no ; then + { echo "$as_me:$LINENO: checking Running simple test program failed. Trying -R flags" >&5 +echo $ECHO_N "checking Running simple test program failed. Trying -R flags... $ECHO_C" >&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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +int main(int argc, char **argv) { return 0; } +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_success=yes + ac_rpath_save_LDFLAGS="$LDFLAGS" + { echo "$as_me:$LINENO: result: adding $RPATHFLAG$d" >&5 +echo "${ECHO_T}adding $RPATHFLAG$d" >&6; } + +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +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.$ac_ext +fi + + + LDFLAGS="$ac_rpath_save_LDFLAGS" + fi + done + RPATH_CANDIDATE_DIRS=$ac_remaining_dirs + fi + if test $ac_success = no ; then + { echo "$as_me:$LINENO: result: failed" >&5 +echo "${ECHO_T}failed" >&6; } + fi +fi + + + + +{ echo "$as_me:$LINENO: checking for __gmpz_powm_sec" >&5 +echo $ECHO_N "checking for __gmpz_powm_sec... $ECHO_C" >&6; } +if test "${ac_cv_func___gmpz_powm_sec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define __gmpz_powm_sec to an innocuous variant, in case declares __gmpz_powm_sec. + For example, HP-UX 11i declares gettimeofday. */ +#define __gmpz_powm_sec innocuous___gmpz_powm_sec + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char __gmpz_powm_sec (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef __gmpz_powm_sec + +/* 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_powm_sec (); +/* 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___gmpz_powm_sec || defined __stub_____gmpz_powm_sec +choke me +#endif + +int +main () +{ +return __gmpz_powm_sec (); + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func___gmpz_powm_sec=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func___gmpz_powm_sec=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func___gmpz_powm_sec" >&5 +echo "${ECHO_T}$ac_cv_func___gmpz_powm_sec" >&6; } +if test $ac_cv_func___gmpz_powm_sec = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_MPZ_POWM_SEC 1 +_ACEOF + +fi + + + + + +if test "x$enable_public_key" = xyes ; then + cat >>confdefs.h <<\_ACEOF +#define WITH_HOGWEED 1 +_ACEOF + + 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 + { echo "$as_me:$LINENO: checking for BF_ecb_encrypt in -lcrypto" >&5 +echo $ECHO_N "checking for BF_ecb_encrypt in -lcrypto... $ECHO_C" >&6; } +if test "${ac_cv_lib_crypto_BF_ecb_encrypt+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_crypto_BF_ecb_encrypt=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_crypto_BF_ecb_encrypt=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_BF_ecb_encrypt" >&5 +echo "${ECHO_T}$ac_cv_lib_crypto_BF_ecb_encrypt" >&6; } +if test $ac_cv_lib_crypto_BF_ecb_encrypt = yes; then + OPENSSL_LIBFLAGS='-lcrypto' +else + enable_openssl=no +fi + +fi + + + + +if test x$enable_openssl = xyes ; then + cat >>confdefs.h <<\_ACEOF +#define WITH_OPENSSL 1 +_ACEOF + +fi + + + +# 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" + + +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_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_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" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +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= +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=`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. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $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} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## 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=: + # Zsh 3.x and 4.x performs 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 + + + + +# PATH needs CR +# 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 + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +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.) +as_nl=' +' +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 + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +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 + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. 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" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); 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 +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +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 +fi +echo >conf$$.file +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 +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=: +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 + +# 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.1, which was +generated by GNU Autoconf 2.61. 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 + +cat >>$CONFIG_STATUS <<_ACEOF +# 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_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet 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 ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +nettle config.status 2.1 +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 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' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +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=$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 ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + 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. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$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 +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS +# +# variables for create stdint.h replacement +PACKAGE="$PACKAGE" +VERSION="$VERSION" +ac_stdint_h="$ac_stdint_h" +_ac_stdint_h=`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 + +# 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" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + 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 '{ (exit 1); 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") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +build!$build$ac_delim +build_cpu!$build_cpu$ac_delim +build_vendor!$build_vendor$ac_delim +build_os!$build_os$ac_delim +host!$host$ac_delim +host_cpu!$host_cpu$ac_delim +host_vendor!$host_vendor$ac_delim +host_os!$host_os$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +CXX!$CXX$ac_delim +CXXFLAGS!$CXXFLAGS$ac_delim +ac_ct_CXX!$ac_ct_CXX$ac_delim +CXX_TESTS!$CXX_TESTS$ac_delim +SET_MAKE!$SET_MAKE$ac_delim +RANLIB!$RANLIB$ac_delim +NM!$NM$ac_delim +OBJDUMP!$OBJDUMP$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +DEP_INCLUDE!$DEP_INCLUDE$ac_delim +DEP_FLAGS!$DEP_FLAGS$ac_delim +DEP_PROCESS!$DEP_PROCESS$ac_delim +CCPIC!$CCPIC$ac_delim +CCPIC_MAYBE!$CCPIC_MAYBE$ac_delim +ASM_SYMBOL_PREFIX!$ASM_SYMBOL_PREFIX$ac_delim +ASM_ELF_STYLE!$ASM_ELF_STYLE$ac_delim +ASM_TYPE_FUNCTION!$ASM_TYPE_FUNCTION$ac_delim +ASM_MARK_NOEXEC_STACK!$ASM_MARK_NOEXEC_STACK$ac_delim +ASM_ALIGN_LOG!$ASM_ALIGN_LOG$ac_delim +SHLIBCFLAGS!$SHLIBCFLAGS$ac_delim +LIBNETTLE_MAJOR!$LIBNETTLE_MAJOR$ac_delim +LIBNETTLE_MINOR!$LIBNETTLE_MINOR$ac_delim +LIBNETTLE_FORLINK!$LIBNETTLE_FORLINK$ac_delim +LIBNETTLE_SONAME!$LIBNETTLE_SONAME$ac_delim +LIBNETTLE_FILE!$LIBNETTLE_FILE$ac_delim +LIBNETTLE_LINK!$LIBNETTLE_LINK$ac_delim +LIBNETTLE_LIBS!$LIBNETTLE_LIBS$ac_delim +LIBHOGWEED_MAJOR!$LIBHOGWEED_MAJOR$ac_delim +LIBHOGWEED_MINOR!$LIBHOGWEED_MINOR$ac_delim +LIBHOGWEED_FORLINK!$LIBHOGWEED_FORLINK$ac_delim +LIBHOGWEED_SONAME!$LIBHOGWEED_SONAME$ac_delim +LIBHOGWEED_FILE!$LIBHOGWEED_FILE$ac_delim +LIBHOGWEED_LINK!$LIBHOGWEED_LINK$ac_delim +LIBHOGWEED_LIBS!$LIBHOGWEED_LIBS$ac_delim +M4!$M4$ac_delim +CPP!$CPP$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +ALLOCA!$ALLOCA$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +IF_HOGWEED!$IF_HOGWEED$ac_delim +IF_SHARED!$IF_SHARED$ac_delim +OPENSSL_LIBFLAGS!$OPENSSL_LIBFLAGS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +CEOF$ac_eof +_ACEOF + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 1; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :L $CONFIG_LINKS :C $CONFIG_COMMANDS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[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 || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$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 "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + 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 || +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" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`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 || +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" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`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 +# 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= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + 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 + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;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 +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out + +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"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +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 + ;; + :H) + # + # CONFIG_HEADER + # +_ACEOF + +# Transform confdefs.h into a sed script `conftest.defines', that +# substitutes the proper values into config.h.in to produce config.h. +rm -f conftest.defines conftest.tail +# First, append a space to every undef/define line, to ease matching. +echo 's/$/ /' >conftest.defines +# Then, protect against being on the right side of a sed subst, or in +# an unquoted here document, in config.status. If some macros were +# called several times there might be several #defines for the same +# symbol, which is useless. But do not sort them, since the last +# AC_DEFINE must be honored. +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +# NAME is the cpp macro being defined, VALUE is the value it is being given. +# PARAMS is the parameter list in the macro definition--in most cases, it's +# just an empty string. +ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +ac_dB='\\)[ (].*,\\1define\\2' +ac_dC=' ' +ac_dD=' ,' + +uniq confdefs.h | + sed -n ' + t rset + :rset + s/^[ ]*#[ ]*define[ ][ ]*// + t ok + d + :ok + s/[\\&,]/\\&/g + s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p + s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p + ' >>conftest.defines + +# Remove the space that was appended to ease matching. +# Then 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. +# (The regexp can be short, since the line contains either #define or #undef.) +echo 's/ $// +s,^[ #]*u.*,/* & */,' >>conftest.defines + +# Break up conftest.defines: +ac_max_sed_lines=50 + +# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +# et cetera. +ac_in='$ac_file_inputs' +ac_out='"$tmp/out1"' +ac_nxt='"$tmp/out2"' + +while : +do + # Write a here document: + cat >>$CONFIG_STATUS <<_ACEOF + # First, check the format of the line: + cat >"\$tmp/defines.sed" <<\\CEOF +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +b +:def +_ACEOF + sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS + ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in + sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail + grep . conftest.tail >/dev/null || break + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines conftest.tail + +echo "ac_result=$ac_in" >>$CONFIG_STATUS +cat >>$CONFIG_STATUS <<\_ACEOF + if test x"$ac_file" != x-; then + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f $ac_file + mv "$tmp/config.h" $ac_file + fi + else + echo "/* $configure_input */" + cat "$ac_result" + fi + rm -f "$tmp/out12" + ;; + :L) + # + # CONFIG_LINK + # + + { echo "$as_me:$LINENO: linking $srcdir/$ac_source to $ac_file" >&5 +echo "$as_me: linking $srcdir/$ac_source to $ac_file" >&6;} + + if test ! -r "$srcdir/$ac_source"; then + { { echo "$as_me:$LINENO: error: $srcdir/$ac_source: file not found" >&5 +echo "$as_me: error: $srcdir/$ac_source: file not found" >&2;} + { (exit 1); exit 1; }; } + fi + rm -f "$ac_file" + + # Try a relative symlink, then a hard link, then a copy. + case $srcdir in + [\\/$]* | ?:[\\/]* ) ac_rel_source=$srcdir/$ac_source ;; + *) ac_rel_source=$ac_top_build_prefix$srcdir/$ac_source ;; + esac + ln -s "$ac_rel_source" "$ac_file" 2>/dev/null || + ln "$srcdir/$ac_source" "$ac_file" 2>/dev/null || + cp -p "$srcdir/$ac_source" "$ac_file" || + { { echo "$as_me:$LINENO: error: cannot link or copy $srcdir/$ac_source to $ac_file" >&5 +echo "$as_me: error: cannot link or copy $srcdir/$ac_source to $ac_file" >&2;} + { (exit 1); exit 1; }; } + ;; + :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 +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) +{ echo "$as_me:$LINENO: creating $ac_stdint_h : $_ac_stdint_h" >&5 +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 < +#else +#include + +/* .................... 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 <= 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 + { echo "$as_me:$LINENO: $ac_stdint_h is unchanged" >&5 +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 || +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" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`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 || +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" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + rm -f $ac_stdint_h + mv $ac_stdint $ac_stdint_h + fi + ;; + + esac +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# 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 || { (exit 1); exit 1; } +fi + + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..0251ffa --- /dev/null +++ b/configure.ac @@ -0,0 +1,539 @@ +dnl -*- mode: shell-script; sh-indentation: 2; -*- + +dnl Process this file with autoconf to produce a configure script. + +AC_INIT([nettle], [2.1], [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=0 + +LIBHOGWEED_MAJOR=2 +LIBHOGWEED_MINOR=0 + +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]) + +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 be 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' + ;; + # According to the fhs, all architectures except IA64 + # puts 32-bit libraries in lib, and 64-bit in lib64. + *:linux*:32) + libdir='${exec_prefix}/lib' + ;; + *:linux*:64) + libdir='${exec_prefix}/lib64' + ;; + # 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.]); #' + + esac + AC_MSG_NOTICE([Libraries to be installed in $libdir.]) + fi +fi + +# Select assembler code +asm_path= +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 + +# 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 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 + 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_LIBFILE) -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_LIBFILE) -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='' + ;; + *) + 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 <&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) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_TYPE_UID_T +AC_TYPE_SIZE_T +AC_HEADER_TIME +# Used by eratosthenes.c +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 + +# 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 +#endif +#if HAVE_UNISTD_H +# include +#endif +#include +],[ +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://www.swox.com/gmp. +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) + +# 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_OUTPUT + diff --git a/ctr.c b/ctr.c new file mode 100644 index 0000000..25ce7f8 --- /dev/null +++ b/ctr.c @@ -0,0 +1,84 @@ +/* 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 +#include +#include + +#include "ctr.h" + +#include "memxor.h" +#include "nettle-internal.h" + +#define INCREMENT(size, counter, i) \ +do { \ + if (++(ctr)[(size) - 1] == 0) \ + { \ + unsigned i = size - 1; \ + while (i > 0 && ++(ctr)[--i] == 0) \ + ; \ + } \ +} while (0) + +void +ctr_crypt(void *ctx, nettle_crypt_func f, + unsigned block_size, uint8_t *ctr, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE); + TMP_ALLOC(buffer, block_size); + + if (src != dst) + { + for (; length >= block_size; length -= block_size, src += block_size, dst += block_size) + { + f(ctx, block_size, dst, ctr); + memxor(dst, src, block_size); + INCREMENT(block_size, ctr, i); + } + } + else + { + for (; length >= block_size; length -= block_size, src += block_size, dst += block_size) + { + f(ctx, block_size, buffer, ctr); + memxor3(dst, src, buffer, block_size); + INCREMENT(block_size, ctr, i); + } + } + if (length > 0) + { + /* A final partial block */ + + f(ctx, block_size, buffer, ctr); + memxor3(dst, src, buffer, length); + INCREMENT(block_size, ctr, i); + } +} diff --git a/ctr.h b/ctr.h new file mode 100644 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 index 0000000..a724471 --- /dev/null +++ b/der-iterator.c @@ -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 +#include + +#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 index 0000000..206c714 --- /dev/null +++ b/der2dsa.c @@ -0,0 +1,119 @@ +/* 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); +} + +/* FIXME: Rename this and the next function to something + openssl-specific? */ +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 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 index 0000000..cd8cd1d --- /dev/null +++ b/des-compat.c @@ -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 +#include + +#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 index 0000000..8aab3bc --- /dev/null +++ b/des-compat.h @@ -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 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 + +#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> 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 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 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 index 0000000..2559548 --- /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 index 0000000..65a54fb --- /dev/null +++ b/descore.README @@ -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 index 0000000..0f7aecb --- /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 index 0000000..0bff551 --- /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 index 0000000..be17771 --- /dev/null +++ b/dsa-keygen.c @@ -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 +#include + +#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_init_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 index 0000000..5654c49 --- /dev/null +++ b/dsa-sha1-sign.c @@ -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 index 0000000..73e948c --- /dev/null +++ b/dsa-sha1-verify.c @@ -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 + +#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 index 0000000..ea82022 --- /dev/null +++ b/dsa-sha256-sign.c @@ -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 index 0000000..ed79a86 --- /dev/null +++ b/dsa-sha256-verify.c @@ -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 + +#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 index 0000000..9c5a29c --- /dev/null +++ b/dsa-sign.c @@ -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 +#include + +#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, 0q); + 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 index 0000000..faea0a0 --- /dev/null +++ b/dsa-verify.c @@ -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 + +#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 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 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 + +#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 index 0000000..213903d --- /dev/null +++ b/dsa2sexp.c @@ -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 index 0000000..2a6632d --- /dev/null +++ b/examples/Makefile.in @@ -0,0 +1,98 @@ +@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@ +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 $(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 index 0000000..287aaa3 --- /dev/null +++ b/examples/eratosthenes.c @@ -0,0 +1,388 @@ +/* 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 +#include +#include +#include + +#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) +{ + unsigned 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, + }; + + /* Isolate least significant bit */ + x &= -x; + + unsigned i = 0; +#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; + + while ( (c = getopt(argc, argv, "?svb:")) != -1) + switch (c) + { + case '?': + usage(); + return EXIT_FAILURE; + case 'b': + block_nbits = CHAR_BIT * atosize(optarg); + if (!block_nbits) + { + usage(); + return EXIT_FAILURE; + } + break; + + case 's': + silent = 1; + break; + + case 'v': + verbose++; + break; + + 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 index 0000000..ed32692 --- /dev/null +++ b/examples/getopt.c @@ -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. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +# ifndef const +# define const +# endif +#endif + +#include + +/* 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 +# 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 +# include +#endif /* GNU C library. */ + +#ifdef VMS +# include +# if HAVE_STRING_H - 0 +# include +# endif +#endif + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. */ +# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC +# include +# 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; + +#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 +# define my_index strchr +#else + +# if HAVE_STRING_H +# include +# else +# include +# 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__ */ + +/* 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; +} + +/* 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. */ + +#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 index 0000000..76cf5ee --- /dev/null +++ b/examples/getopt.h @@ -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 , but + that does not exist if we are standalone. So: if __GNU_LIBRARY__ is + not defined, include , which will pull in 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 +#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 index 0000000..62c55cf --- /dev/null +++ b/examples/getopt1.c @@ -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. */ + +#ifdef HAVE_CONFIG_H +#include +#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 + +/* 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 +#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 +#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. */ + +#ifdef TEST + +#include + +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 index 0000000..689e0f6 --- /dev/null +++ b/examples/io.c @@ -0,0 +1,189 @@ +/* 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 +#include + +/* For errno and strerror */ +#include +#include + +#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; + + for (size = 100, 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 index 0000000..e85dc5f --- /dev/null +++ b/examples/io.h @@ -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 + +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 index 0000000..95296ba --- /dev/null +++ b/examples/nettle-benchmark.c @@ -0,0 +1,440 @@ +/* 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 +#include +#include +#include +#include +#include + +#include + +#include "aes.h" +#include "arcfour.h" +#include "blowfish.h" +#include "cast128.h" +#include "cbc.h" +#include "des.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 clocks. */ +#define BENCH_BLOCK 10240 +#define BENCH_INTERVAL (CLOCKS_PER_SEC / 4) + +/* Total MB:s, for MB/s figures. */ +#define BENCH_TOTAL 10.0 + +/* FIXME: Proper configure test for rdtsc? */ +#ifndef WITH_CYCLE_COUNTER +# if defined(__GNUC__) && defined(__i386__) +# define WITH_CYCLE_COUNTER 1 +# else +# define WITH_CYCLE_COUNTER 0 +# endif +#endif + +#if WITH_CYCLE_COUNTER +#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") +#define BENCH_ITERATIONS 10 +#endif + +/* Returns second per function call */ +static double +time_function(void (*f)(void *arg), void *arg) +{ + clock_t before; + clock_t after; + clock_t done; + unsigned ncalls; + + before = clock(); + done = before + BENCH_INTERVAL; + ncalls = 0; + + do + { + f(arg); + after = clock(); + ncalls++; + } + while (after < done); + + return ((double)(after - before)) / CLOCKS_PER_SEC / ncalls; +} + +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); +} + +/* Set data[i] = floor(sqrt(i)) */ +static void +init_data(uint8_t *data) +{ + unsigned i,j; + for (i = j = 0; i 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) + { + fprintf(stderr, "Virtual memory exhausted.\n"); + abort(); + } + + return p; +} + +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_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)); + } + 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 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, + 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 + }; + + while ( (c = getopt(argc, argv, "f:")) != -1) + switch (c) + { + case 'f': + frequency = atof(optarg); + if (frequency > 0.0) + break; + + case ':': case '?': + fprintf(stderr, "Usage: nettle-benchmark [-f clock frequency]\n"); + return EXIT_FAILURE; + + default: + abort(); + } + + bench_sha1_compress(); + + header(); + + for (i = 0; hashes[i]; i++) + time_hash(hashes[i]); + + for (i = 0; ciphers[i]; i++) + time_cipher(ciphers[i]); + + return 0; +} diff --git a/examples/nettle-openssl.c b/examples/nettle-openssl.c new file mode 100644 index 0000000..5f5f2b1 --- /dev/null +++ b/examples/nettle-openssl.c @@ -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 + +#include +#include +#include +#include +#include + +#include +#include + +#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 index 0000000..5283ecc --- /dev/null +++ b/examples/next-prime.c @@ -0,0 +1,158 @@ +/* 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 +#include +#include + +#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_FACTORIAL = -100 }; + static const struct option options[] = + { + /* Name, args, flag, val */ + { "help", no_argument, NULL, '?' }, + { "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, "v?s:", options, NULL)) != -1) + switch (c) + { + case 'v': + verbose = 1; + break; + case '?': + usage(); + return EXIT_FAILURE; + case 'f': + factorial = 1; + break; + case 's': + prime_limit = atoi(optarg); + if (prime_limit < 0) + { + usage(); + return EXIT_FAILURE; + } + break; + 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 index 0000000..1ed4fcd --- /dev/null +++ b/examples/random-prime.c @@ -0,0 +1,143 @@ +/* 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 +#include +#include + +#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; + + static const struct option options[] = + { + /* Name, args, flag, val */ + { "help", no_argument, NULL, '?' }, + { "verbose", no_argument, NULL, 'v' }, + { "random", required_argument, NULL, 'r' }, + { NULL, 0, NULL, 0} + }; + + while ( (c = getopt_long(argc, argv, "v?r:", options, NULL)) != -1) + switch (c) + { + case 'v': + verbose = 1; + break; + case 'r': + random_file = optarg; + break; + case '?': + usage(); + 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 index 0000000..1d092e7 --- /dev/null +++ b/examples/read_rsa_key.c @@ -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 + +#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 index 0000000..5e0ee79 --- /dev/null +++ b/examples/rsa-decrypt.c @@ -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 +#include +#include +#include +#include + +/* 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 index 0000000..08b7a44 --- /dev/null +++ b/examples/rsa-encrypt-test @@ -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 index 0000000..e87dcb6 --- /dev/null +++ b/examples/rsa-encrypt.c @@ -0,0 +1,240 @@ +/* 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 +#include +#include +#include +#include + +/* 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; + + while ( (c = getopt(argc, argv, "o:r:")) != -1) + switch (c) + { + case 'r': + random_name = optarg; + break; + + case '?': + if (isprint (optopt)) + werror("Unknown option `-%c'.\n", optopt); + else + werror("Unknown option character `\\x%x'.\n", + optopt); + 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 index 0000000..2f70e55 --- /dev/null +++ b/examples/rsa-keygen.c @@ -0,0 +1,156 @@ +/* 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 +#include +#include +#include +#include + +#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; + + while ( (c = getopt(argc, argv, "o:r:")) != -1) + switch (c) + { + case 'o': + priv_name = optarg; + break; + + case 'r': + random_name = optarg; + break; + + case '?': + if (isprint (optopt)) + werror("Unknown option `-%c'.\n", optopt); + else + werror("Unknown option character `\\x%x'.\n", + optopt); + 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 index 0000000..44b85ec --- /dev/null +++ b/examples/rsa-session.h @@ -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 index 0000000..1621226 --- /dev/null +++ b/examples/rsa-sign-test @@ -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 index 0000000..c480761 --- /dev/null +++ b/examples/rsa-sign.c @@ -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 +#include +#include +#include + +/* 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 index 0000000..765b61f --- /dev/null +++ b/examples/rsa-verify-test @@ -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/ 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 index 0000000..8781812 --- /dev/null +++ b/examples/rsa-verify.c @@ -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 +#include +#include +#include + +#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 index 0000000..f240599 --- /dev/null +++ b/examples/run-tests @@ -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 index 0000000..7588d6f --- /dev/null +++ b/examples/setup-env @@ -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 index 0000000..ce1a157 --- /dev/null +++ b/examples/teardown-env @@ -0,0 +1,6 @@ +#! /bin/sh + +rm -rf testkey testkey.pub testsignature testsignature2 testdata \ + testciphertext testcleartext + + diff --git a/hmac-md5.c b/hmac-md5.c new file mode 100644 index 0000000..99ce1f9 --- /dev/null +++ b/hmac-md5.c @@ -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-sha1.c b/hmac-sha1.c new file mode 100644 index 0000000..64c079e --- /dev/null +++ b/hmac-sha1.c @@ -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 index 0000000..580509e --- /dev/null +++ b/hmac-sha224.c @@ -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 index 0000000..9ead853 --- /dev/null +++ b/hmac-sha256.c @@ -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 index 0000000..f39705f --- /dev/null +++ b/hmac-sha384.c @@ -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 index 0000000..c09e9f5 --- /dev/null +++ b/hmac-sha512.c @@ -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 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 +/* Needed for alloca on freebsd */ +#include +#include + +#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 index 0000000..0142e6e --- /dev/null +++ b/hmac.h @@ -0,0 +1,181 @@ +/* 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 "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_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-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/install-sh b/install-sh new file mode 100755 index 0000000..4fbbae7 --- /dev/null +++ b/install-sh @@ -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 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 index 0000000..e12688c --- /dev/null +++ b/knuth-lfib.c @@ -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 +#include + +#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= 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; jx[j+KK-LL] = x[j]; + for (; jx[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= 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 index 0000000..b52393e --- /dev/null +++ b/knuth-lfib.h @@ -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 index 0000000..2cc69cb --- /dev/null +++ b/macros.h @@ -0,0 +1,122 @@ +/* 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)) ) + +#endif /* NETTLE_MACROS_H_INCLUDED */ diff --git a/md2-meta.c b/md2-meta.c new file mode 100644 index 0000000..0ed0b47 --- /dev/null +++ b/md2-meta.c @@ -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 index 0000000..ae2abb5 --- /dev/null +++ b/md2.c @@ -0,0 +1,167 @@ +/* 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 +#include + +#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]; + iX[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]); + } +} + +#if 0 +static void +md2_final(struct md2_ctx *ctx) +{ + unsigned left = MD2_DATA_SIZE - ctx->index; + memset(ctx->block + ctx->index, left, left); + md2_transform(ctx, ctx->block); +} +#endif + +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) +{ + if (ctx->index) + { + /* Try to fill partial block */ + unsigned left = MD2_DATA_SIZE - ctx->index; + if (length < left) + { + memcpy(ctx->block + ctx->index, data, length); + ctx->index += length; + return; /* Finished */ + } + else + { + memcpy(ctx->block + ctx->index, data, left); + md2_transform(ctx, ctx->block); + data += left; + length -= left; + } + } + while (length >= MD2_DATA_SIZE) + { + md2_transform(ctx, data); + data += MD2_DATA_SIZE; + length -= MD2_DATA_SIZE; + } + if ((ctx->index = length)) /* This assignment is intended */ + /* Buffer leftovers */ + memcpy(ctx->block, data, length); +} + +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 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 index 0000000..2d74f79 --- /dev/null +++ b/md4-meta.c @@ -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 index 0000000..544ce0d --- /dev/null +++ b/md4.c @@ -0,0 +1,272 @@ +/* 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 +#include + +#include "md4.h" + +#include "macros.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_block(struct md4_ctx *ctx, const uint8_t *block); + +static void +md4_final(struct md4_ctx *ctx); + +void +md4_init(struct md4_ctx *ctx) +{ + /* Same constants as for md5. */ + ctx->digest[0] = 0x67452301; + ctx->digest[1] = 0xefcdab89; + ctx->digest[2] = 0x98badcfe; + ctx->digest[3] = 0x10325476; + + ctx->count_l = ctx->count_h = 0; + ctx->index = 0; +} + +void +md4_update(struct md4_ctx *ctx, + unsigned length, + const uint8_t *data) +{ + if (ctx->index) + { + /* Try to fill partial block */ + unsigned left = MD4_DATA_SIZE - ctx->index; + if (length < left) + { + memcpy(ctx->block + ctx->index, data, length); + ctx->index += length; + return; /* Finished */ + } + else + { + memcpy(ctx->block + ctx->index, data, left); + md4_block(ctx, ctx->block); + data += left; + length -= left; + } + } + while (length >= MD4_DATA_SIZE) + { + md4_block(ctx, data); + data += MD4_DATA_SIZE; + length -= MD4_DATA_SIZE; + } + if ((ctx->index = length)) /* This assignment is intended */ + /* Buffer leftovers */ + memcpy(ctx->block, data, length); +} + +void +md4_digest(struct md4_ctx *ctx, + unsigned length, + uint8_t *digest) +{ + unsigned i; + unsigned words; + unsigned leftover; + + assert(length <= MD4_DIGEST_SIZE); + + md4_final(ctx); + + words = length / 4; + leftover = length % 4; + + /* Little endian order */ + for (i = 0; i < words; i++, digest += 4) + LE_WRITE_UINT32(digest, ctx->digest[i]); + + if (leftover) + { + uint32_t word; + unsigned j; + + assert(i < _MD4_DIGEST_LENGTH); + + /* Still least significant byte first. */ + for (word = ctx->digest[i], j = 0; j < leftover; + j++, word >>= 8) + digest[j] = word & 0xff; + } + 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<>(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_block(struct md4_ctx *ctx, const uint8_t *block) +{ + uint32_t data[MD4_DATA_LENGTH]; + unsigned i; + + /* Update block count */ + if (!++ctx->count_l) + ++ctx->count_h; + + /* Endian independent conversion */ + for (i = 0; i<16; i++, block += 4) + data[i] = LE_READ_UINT32(block); + + md4_transform(ctx->digest, data); +} + +/* Final wrapup - pad to MD4_DATA_SIZE-byte boundary with the bit + * pattern 1 0* (64-bit count of bits processed, LSB-first) */ + +static void +md4_final(struct md4_ctx *ctx) +{ + uint32_t data[MD4_DATA_LENGTH]; + unsigned i; + unsigned words; + + i = ctx->index; + + /* Set the first char of padding to 0x80. This is safe since there + * is always at least one byte free */ + assert(i < MD4_DATA_SIZE); + ctx->block[i++] = 0x80; + + /* Fill rest of word */ + for( ; i & 3; i++) + ctx->block[i] = 0; + + /* i is now a multiple of the word size 4 */ + words = i >> 2; + for (i = 0; i < words; i++) + data[i] = LE_READ_UINT32(ctx->block + 4*i); + + if (words > (MD4_DATA_LENGTH-2)) + { /* No room for length in this block. Process it and + * pad with another one */ + for (i = words ; i < MD4_DATA_LENGTH; i++) + data[i] = 0; + md4_transform(ctx->digest, data); + for (i = 0; i < (MD4_DATA_LENGTH-2); i++) + data[i] = 0; + } + else + for (i = words ; i < MD4_DATA_LENGTH - 2; i++) + data[i] = 0; + + /* There are 512 = 2^9 bits in one block + * Little-endian order => Least significant word first */ + + data[MD4_DATA_LENGTH-1] = (ctx->count_h << 9) | (ctx->count_l >> 23); + data[MD4_DATA_LENGTH-2] = (ctx->count_l << 9) | (ctx->index << 3); + md4_transform(ctx->digest, data); +} diff --git a/md4.h b/md4.h new file mode 100644 index 0000000..e9a32b9 --- /dev/null +++ b/md4.h @@ -0,0 +1,72 @@ +/* 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 + +struct md4_ctx +{ + uint32_t digest[_MD4_DIGEST_LENGTH]; + uint32_t count_l, count_h; /* 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 index 0000000..31a2fd5 --- /dev/null +++ b/md5-compat.c @@ -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 index 0000000..8f5f331 --- /dev/null +++ b/md5-compat.h @@ -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 index 0000000..ec949e7 --- /dev/null +++ b/md5-compress.c @@ -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 +# define DEBUG(i) \ + fprintf(stderr, "%2d: %8x %8x %8x %8x\n", i, a, b, c, d) +#else +# define DEBUG(i) +#endif + +#include +#include +#include + +#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<>(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 index 0000000..3ea5900 --- /dev/null +++ b/md5-meta.c @@ -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 index 0000000..d398b31 --- /dev/null +++ b/md5.c @@ -0,0 +1,169 @@ +/* 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 +#include + +#include "md5.h" + +#include "macros.h" + +static void +md5_final(struct md5_ctx *ctx); + +void +md5_init(struct md5_ctx *ctx) +{ + ctx->digest[0] = 0x67452301; + ctx->digest[1] = 0xefcdab89; + ctx->digest[2] = 0x98badcfe; + ctx->digest[3] = 0x10325476; + + ctx->count_l = ctx->count_h = 0; + ctx->index = 0; +} + +#define MD5_INCR(ctx) ((ctx)->count_h += !++(ctx)->count_l) + +void +md5_update(struct md5_ctx *ctx, + unsigned length, + const uint8_t *data) +{ + if (ctx->index) + { + /* Try to fill partial block */ + unsigned left = MD5_DATA_SIZE - ctx->index; + if (length < left) + { + memcpy(ctx->block + ctx->index, data, length); + ctx->index += length; + return; /* Finished */ + } + else + { + memcpy(ctx->block + ctx->index, data, left); + + _nettle_md5_compress(ctx->digest, ctx->block); + MD5_INCR(ctx); + + data += left; + length -= left; + } + } + while (length >= MD5_DATA_SIZE) + { + _nettle_md5_compress(ctx->digest, data); + MD5_INCR(ctx); + + data += MD5_DATA_SIZE; + length -= MD5_DATA_SIZE; + } + if ((ctx->index = length)) /* This assignment is intended */ + /* Buffer leftovers */ + memcpy(ctx->block, data, length); +} + +void +md5_digest(struct md5_ctx *ctx, + unsigned length, + uint8_t *digest) +{ + unsigned i; + unsigned words; + unsigned leftover; + + assert(length <= MD5_DIGEST_SIZE); + + md5_final(ctx); + + words = length / 4; + leftover = length % 4; + + /* Little endian order */ + for (i = 0; i < words; i++, digest += 4) + LE_WRITE_UINT32(digest, ctx->digest[i]); + + if (leftover) + { + uint32_t word; + unsigned j; + + assert(i < _MD5_DIGEST_LENGTH); + + /* Still least significant byte first. */ + for (word = ctx->digest[i], j = 0; j < leftover; + j++, word >>= 8) + digest[j] = word & 0xff; + } + md5_init(ctx); +} + +/* Final wrapup - pad to MD5_DATA_SIZE-byte boundary with the bit + * pattern 1 0* (64-bit count of bits processed, LSB-first) */ + +static void +md5_final(struct md5_ctx *ctx) +{ + uint32_t bitcount_high; + uint32_t bitcount_low; + unsigned i; + + i = ctx->index; + + /* Set the first char of padding to 0x80. This is safe since there + * is always at least one byte free */ + assert(i < MD5_DATA_SIZE); + ctx->block[i++] = 0x80; + + if (i > (MD5_DATA_SIZE - 8)) + { + /* No room for length in this block. Process it and + pad with another one */ + memset(ctx->block + i, 0, MD5_DATA_SIZE - i); + + _nettle_md5_compress(ctx->digest, ctx->block); + i = 0; + } + if (i < (MD5_DATA_SIZE - 8)) + memset(ctx->block + i, 0, (MD5_DATA_SIZE - 8) - i); + + /* There are 512 = 2^9 bits in one block + * Little-endian order => Least significant word first */ + + bitcount_low = (ctx->count_l << 9) | (ctx->index << 3); + bitcount_high = (ctx->count_h << 9) | (ctx->count_l >> 23); + LE_WRITE_UINT32(ctx->block + (MD5_DATA_SIZE - 8), bitcount_low); + LE_WRITE_UINT32(ctx->block + (MD5_DATA_SIZE - 4), bitcount_high); + + _nettle_md5_compress(ctx->digest, ctx->block); +} diff --git a/md5.h b/md5.h new file mode 100644 index 0000000..c936cb2 --- /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 digest[_MD5_DIGEST_LENGTH]; + uint32_t count_l, count_h; /* 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 index 0000000..92f14a5 --- /dev/null +++ b/memxor.c @@ -0,0 +1,35 @@ +/* memxor.c + * + * $Id: memxor.c,v 1.1 2007/04/05 14:20:35 nisse Exp $ + */ + +/* XOR LEN bytes starting at SRCADDR onto DESTADDR. Result undefined + if the source overlaps with the destination. + Return DESTADDR. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "memxor.h" + +uint8_t * +memxor(uint8_t *dst, const uint8_t *src, size_t n) +{ + size_t i; + for (i = 0; i +#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 index 0000000..a4817fa --- /dev/null +++ b/nettle-internal.c @@ -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 +#include + +#include "nettle-internal.h" +#include "des.h" +#include "blowfish.h" + +/* DES uses a different signature for the key set function. + * And we have to adjust parity. */ +static void +des_set_key_hack(void *c, unsigned length, const uint8_t *key) +{ + struct des_ctx *ctx = c; + uint8_t pkey[DES_KEY_SIZE]; + + assert(length == DES_KEY_SIZE); + des_fix_parity(DES_KEY_SIZE, pkey, key); + if (!des_set_key(ctx, pkey)) + abort(); +} + +static void +des3_set_key_hack(void *c, unsigned length, const uint8_t *key) +{ + struct des3_ctx *ctx = c; + uint8_t pkey[DES3_KEY_SIZE]; + + assert(length == DES3_KEY_SIZE); + des_fix_parity(DES3_KEY_SIZE, pkey, key); + if (!des3_set_key(ctx, pkey)) + abort(); +} + +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 it will crash if + * we try to encrypt something with a weak key. */ +const struct nettle_cipher +nettle_blowfish128 = _NETTLE_CIPHER(blowfish, BLOWFISH, 128); diff --git a/nettle-internal.h b/nettle-internal.h new file mode 100644 index 0000000..c5b1b53 --- /dev/null +++ b/nettle-internal.h @@ -0,0 +1,77 @@ +/* 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; + +#endif /* NETTLE_INTERNAL_H_INCLUDED */ diff --git a/nettle-meta.h b/nettle-meta.h new file mode 100644 index 0000000..e3fb4e2 --- /dev/null +++ b/nettle-meta.h @@ -0,0 +1,217 @@ +/* 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, keysize) { \ + #name #keysize, \ + sizeof(struct name##_ctx), \ + NAME##_BLOCK_SIZE, \ + keysize / 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, keysize) { \ + #name #keysize, \ + sizeof(struct name##_ctx), \ + NAME##_BLOCK_SIZE, \ + keysize / 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, keysize) {\ + #name #keysize, \ + sizeof(struct name##_ctx), \ + NAME##_BLOCK_SIZE, \ + keysize / 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, keysize) { \ + #name, \ + sizeof(struct name##_ctx), \ + NAME##_BLOCK_SIZE, \ + keysize / 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, \ +} + +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 \ +} + +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_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, \ +} + +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 index 0000000..2a97715 --- /dev/null +++ b/nettle-types.h @@ -0,0 +1,87 @@ +/* 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); + +/* 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 index 0000000..7287270 --- /dev/null +++ b/nettle-write.h @@ -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 index 0000000..52ef62b --- /dev/null +++ b/nettle.html @@ -0,0 +1,5286 @@ + + +Nettle: a low-level cryptographic library + + + + + + + + +

Nettle: a low-level cryptographic library

+ + + + +
+


+Node: Top, +Next: , +Previous: (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.1), a +low-level cryptographic library. + +

Originally written 2001 by Niels Möller, updated 2010. + +

+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. +
+ + + +
+


+Node: Introduction, +Next: , +Previous: Top, +Up: Top +
+
+ +

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. + +

+


+Node: Copyright, +Next: , +Previous: Introduction, +Up: Top +
+
+ +

Copyright

+ +

Nettle is distributed under the GNU General Public License (GPL) (see +the file COPYING for details). However, most of the individual files +are dual licensed under less restrictive licenses like the GNU Lesser +General Public License (LGPL), or are in the public domain. This means +that if you don't use the parts of nettle that are GPL-only, you have +the option to use the Nettle library just as if it were licensed under +the LGPL. 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 Ray +Dassen and Niels Möller. Released under the GPL. + +
CAMELLIA +
The C implementation is by Nippon Telegraph and Telephone Corporation +(NTT), heavily modified by Niels Möller. Assembler for x86 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. + +
SERPENT +
The implementation of the SERPENT cipher is written by Ross Anderson, +Eli Biham, and Lars Knudsen, adapted to LSH by Rafael Sevilla, and to +Nettle by Niels Möller. Released under the GPL. + +
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. +
+ +
+


+Node: Conventions, +Next: , +Previous: Copyright, +Up: Top +
+
+ +

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. + +

+


+Node: Example, +Next: , +Previous: Conventions, +Up: Top +
+
+ +

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
+     
+ +
+


+Node: Linking, +Next: , +Previous: Example, +Up: Top +
+
+ +

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. + +

+


+Node: Reference, +Next: , +Previous: Linking, +Up: Top +
+
+ +

Reference

+ +

This chapter describes all the Nettle functions, grouped by family. + +

+ +
+


+Node: Hash functions, +Next: , +Previous: Reference, +Up: Reference +
+
+ +

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. + +

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>. + +

+ + + + + +
struct md5_ctx + Context struct
+ + +
+
+ +

+ + + + + +
MD5_DIGEST_SIZE + Constant
+ + +
+The size of an MD5 digest, i.e. 16. +
+ +

+ + + + + +
MD5_DATA_SIZE + Constant
+ + +
+The internal block size of MD5. Useful for some special constructions, +in particular HMAC-MD5. +
+ +

+ + + + + +
void md5_init (struct md5_ctx *ctx) + Function
+ + +
+Initialize the MD5 state. +
+ +

+ + + + + +
void md5_update (struct md5_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Hash some more data. +
+ +

+ + + + + +
void md5_digest (struct md5_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+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. + +

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>. + +

+ + + + + +
struct md2_ctx + Context struct
+ + +
+
+ +

+ + + + + +
MD2_DIGEST_SIZE + Constant
+ + +
+The size of an MD2 digest, i.e. 16. +
+ +

+ + + + + +
MD2_DATA_SIZE + Constant
+ + +
+The internal block size of MD2. +
+ +

+ + + + + +
void md2_init (struct md2_ctx *ctx) + Function
+ + +
+Initialize the MD2 state. +
+ +

+ + + + + +
void md2_update (struct md2_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Hash some more data. +
+ +

+ + + + + +
void md2_digest (struct md2_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+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. +

+ +

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. + +

+ + + + + +
struct md4_ctx + Context struct
+ + +
+
+ +

+ + + + + +
MD4_DIGEST_SIZE + Constant
+ + +
+The size of an MD4 digest, i.e. 16. +
+ +

+ + + + + +
MD4_DATA_SIZE + Constant
+ + +
+The internal block size of MD4. +
+ +

+ + + + + +
void md4_init (struct md4_ctx *ctx) + Function
+ + +
+Initialize the MD4 state. +
+ +

+ + + + + +
void md4_update (struct md4_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Hash some more data. +
+ +

+ + + + + +
void md4_digest (struct md4_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+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. +

+ +

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. + +

+ + + + + +
struct sha1_ctx + Context struct
+ + +
+
+ +

+ + + + + +
SHA1_DIGEST_SIZE + Constant
+ + +
+The size of an SHA1 digest, i.e. 20. +
+ +

+ + + + + +
SHA1_DATA_SIZE + Constant
+ + +
+The internal block size of SHA1. Useful for some special constructions, +in particular HMAC-SHA1. +
+ +

+ + + + + +
void sha1_init (struct sha1_ctx *ctx) + Function
+ + +
+Initialize the SHA1 state. +
+ +

+ + + + + +
void sha1_update (struct sha1_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Hash some more data. +
+ +

+ + + + + +
void sha1_digest (struct sha1_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+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. +

+ +

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. + +

+ + + + + +
struct sha256_ctx + Context struct
+ + +
+
+ +

+ + + + + +
SHA256_DIGEST_SIZE + Constant
+ + +
+The size of an SHA256 digest, i.e. 32. +
+ +

+ + + + + +
SHA256_DATA_SIZE + Constant
+ + +
+The internal block size of SHA256. Useful for some special constructions, +in particular HMAC-SHA256. +
+ +

+ + + + + +
void sha256_init (struct sha256_ctx *ctx) + Function
+ + +
+Initialize the SHA256 state. +
+ +

+ + + + + +
void sha256_update (struct sha256_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Hash some more data. +
+ +

+ + + + + +
void sha256_digest (struct sha256_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+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. +

+ +

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. + +

+ + + + + +
struct sha224_ctx + Context struct
+ + +
+
+ +

+ + + + + +
SHA224_DIGEST_SIZE + Constant
+ + +
+The size of an SHA224 digest, i.e. 28. +
+ +

+ + + + + +
SHA224_DATA_SIZE + Constant
+ + +
+The internal block size of SHA224. Useful for some special constructions, +in particular HMAC-SHA224. +
+ +

+ + + + + +
void sha224_init (struct sha224_ctx *ctx) + Function
+ + +
+Initialize the SHA224 state. +
+ +

+ + + + + +
void sha224_update (struct sha224_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Hash some more data. +
+ +

+ + + + + +
void sha224_digest (struct sha224_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+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. +

+ +

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. + +

+ + + + + +
struct sha512_ctx + Context struct
+ + +
+
+ +

+ + + + + +
SHA512_DIGEST_SIZE + Constant
+ + +
+The size of an SHA512 digest, i.e. 64. +
+ +

+ + + + + +
SHA512_DATA_SIZE + Constant
+ + +
+The internal block size of SHA512. Useful for some special constructions, +in particular HMAC-SHA512. +
+ +

+ + + + + +
void sha512_init (struct sha512_ctx *ctx) + Function
+ + +
+Initialize the SHA512 state. +
+ +

+ + + + + +
void sha512_update (struct sha512_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Hash some more data. +
+ +

+ + + + + +
void sha512_digest (struct sha512_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+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. +

+ +

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. + +

+ + + + + +
struct sha384_ctx + Context struct
+ + +
+
+ +

+ + + + + +
SHA384_DIGEST_SIZE + Constant
+ + +
+The size of an SHA384 digest, i.e. 48. +
+ +

+ + + + + +
SHA384_DATA_SIZE + Constant
+ + +
+The internal block size of SHA384. Useful for some special constructions, +in particular HMAC-SHA384. +
+ +

+ + + + + +
void sha384_init (struct sha384_ctx *ctx) + Function
+ + +
+Initialize the SHA384 state. +
+ +

+ + + + + +
void sha384_update (struct sha384_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Hash some more data. +
+ +

+ + + + + +
void sha384_digest (struct sha384_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+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. +

+ +

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 see Keyed hash functions. + +

+ + + + + +
struct nettle_hash name context_size digest_size block_size init update digest + Meta struct
+ + +
+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. +
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
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_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 + Constant Struct
+ + +
+ +

These are all the hash functions that Nettle implements. +

+ +

+


+Node: Cipher functions, +Next: , +Previous: Hash functions, +Up: Reference +
+
+ +

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 See 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 see 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. + +

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>. + +

+ + + + + +
struct aes_ctx + Context struct
+ + +
+
+ +

+ + + + + +
AES_BLOCK_SIZE + Constant
+ + +
+The AES block-size, 16 +
+ +

+ + + + + +
AES_MIN_KEY_SIZE + Constant
+ + +
+
+ +

+ + + + + +
AES_MAX_KEY_SIZE + Constant
+ + +
+
+ +

+ + + + + +
AES_KEY_SIZE + Constant
+ + +
+Default AES key size, 32 +
+ +

+ + + + + + + + + + +
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) + Function
+ + +
+Initialize the cipher, for encryption or decryption, respectively. +
+ +

+ + + + + +
void aes_invert_key (struct aes_ctx *dst, const struct aes_ctx *src) + Function
+ + +
+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. +
+ +

+ + + + + +
void aes_encrypt (struct aes_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+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. +
+ +

+ + + + + +
void aes_decrypt (struct aes_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Analogous to aes_encrypt +
+ +

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>. + +

+ + + + + +
struct arcfour_ctx + Context struct
+ + +
+
+ +

+ + + + + +
ARCFOUR_MIN_KEY_SIZE + Constant
+ + +
+Minimum key size, 1 +
+ +

+ + + + + +
ARCFOUR_MAX_KEY_SIZE + Constant
+ + +
+Maximum key size, 256 +
+ +

+ + + + + +
ARCFOUR_KEY_SIZE + Constant
+ + +
+Default ARCFOUR key size, 16 +
+ +

+ + + + + +
void arcfour_set_key (struct arcfour_ctx *ctx, unsigned length, const uint8_t *key) + Function
+ + +
+Initialize the cipher. The same function is used for both encryption and +decryption. +
+ +

+ + + + + +
void arcfour_crypt (struct arcfour_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+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. +
+ +

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. + +

+ + + + + +
struct arctwo_ctx + Context struct
+ + +
+
+ +

+ + + + + +
ARCTWO_BLOCK_SIZE + Constant
+ + +
+The AES block-size, 8 +
+ +

+ + + + + +
ARCTWO_MIN_KEY_SIZE + Constant
+ + +
+
+ +

+ + + + + +
ARCTWO_MAX_KEY_SIZE + Constant
+ + +
+
+ +

+ + + + + +
ARCTWO_KEY_SIZE + Constant
+ + +
+Default ARCTWO key size, 8 +
+ +

+ + + + + + + + + + + + + + + +
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) + Function
+ + +
+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) +

+ +

+ + + + + +
void arctwo_encrypt (struct arctwo_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+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. +
+ +

+ + + + + +
void arctwo_decrypt (struct arctwo_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Analogous to arctwo_encrypt +
+ +

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>. + +

+ + + + + +
struct blowfish_ctx + Context struct
+ + +
+
+ +

+ + + + + +
BLOWFISH_BLOCK_SIZE + Constant
+ + +
+The BLOWFISH block-size, 8 +
+ +

+ + + + + +
BLOWFISH_MIN_KEY_SIZE + Constant
+ + +
+Minimum BLOWFISH key size, 8 +
+ +

+ + + + + +
BLOWFISH_MAX_KEY_SIZE + Constant
+ + +
+Maximum BLOWFISH key size, 56 +
+ +

+ + + + + +
BLOWFISH_KEY_SIZE + Constant
+ + +
+Default BLOWFISH key size, 16 +
+ +

+ + + + + +
int blowfish_set_key (struct blowfish_ctx *ctx, unsigned length, const uint8_t *key) + Function
+ + +
+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. +

+ +

+ + + + + +
void blowfish_encrypt (struct blowfish_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+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. +
+ +

+ + + + + +
void blowfish_decrypt (struct blowfish_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Analogous to blowfish_encrypt +
+ +

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>. + +

+ + + + + +
struct camellia_ctx + Context struct
+ + +
+
+ +

+ + + + + +
CAMELLIA_BLOCK_SIZE + Constant
+ + +
+The CAMELLIA block-size, 16 +
+ +

+ + + + + +
CAMELLIA_MIN_KEY_SIZE + Constant
+ + +
+
+ +

+ + + + + +
CAMELLIA_MAX_KEY_SIZE + Constant
+ + +
+
+ +

+ + + + + +
CAMELLIA_KEY_SIZE + Constant
+ + +
+Default CAMELLIA key size, 32 +
+ +

+ + + + + + + + + + +
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) + Function
+ + +
+Initialize the cipher, for encryption or decryption, respectively. +
+ +

+ + + + + +
void camellia_invert_key (struct camellia_ctx *dst, const struct camellia_ctx *src) + Function
+ + +
+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. +
+ +

+ + + + + +
void camellia_crypt (struct camellia_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+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. +
+ +

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>. + +

+ + + + + +
struct cast128_ctx + Context struct
+ + +
+
+ +

+ + + + + +
CAST128_BLOCK_SIZE + Constant
+ + +
+The CAST128 block-size, 8 +
+ +

+ + + + + +
CAST128_MIN_KEY_SIZE + Constant
+ + +
+Minimum CAST128 key size, 5 +
+ +

+ + + + + +
CAST128_MAX_KEY_SIZE + Constant
+ + +
+Maximum CAST128 key size, 16 +
+ +

+ + + + + +
CAST128_KEY_SIZE + Constant
+ + +
+Default CAST128 key size, 16 +
+ +

+ + + + + +
void cast128_set_key (struct cast128_ctx *ctx, unsigned length, const uint8_t *key) + Function
+ + +
+Initialize the cipher. The same function is used for both encryption and +decryption. +
+ +

+ + + + + +
void cast128_encrypt (struct cast128_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+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. +
+ +

+ + + + + +
void cast128_decrypt (struct cast128_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Analogous to cast128_encrypt +
+ +

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>. + +

+ + + + + +
struct des_ctx + Context struct
+ + +
+
+ +

+ + + + + +
DES_BLOCK_SIZE + Constant
+ + +
+The DES block-size, 8 +
+ +

+ + + + + +
DES_KEY_SIZE + Constant
+ + +
+DES key size, 8 +
+ +

+ + + + + +
int des_set_key (struct des_ctx *ctx, const uint8_t *key) + Function
+ + +
+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. +
+ +

+ + + + + +
void des_encrypt (struct des_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+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. +
+ +

+ + + + + +
void des_decrypt (struct des_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Analogous to des_encrypt +
+ +

+ + + + + +
int des_check_parity (unsigned length, const uint8_t *key); + Function
+ + +
+Checks that the given key has correct, odd, parity. Returns 1 for +correct parity, and 0 for bad parity. +
+ +

+ + + + + +
void des_fix_parity (unsigned length, uint8_t *dst, const uint8_t *src) + Function
+ + +
+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. +
+ +

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>. + +

+ + + + + +
struct des3_ctx + Context struct
+ + +
+
+ +

+ + + + + +
DES3_BLOCK_SIZE + Constant
+ + +
+The DES3 block-size is the same as DES_BLOCK_SIZE, 8 +
+ +

+ + + + + +
DES3_KEY_SIZE + Constant
+ + +
+DES key size, 24 +
+ +

+ + + + + +
int des3_set_key (struct des3_ctx *ctx, const uint8_t *key) + Function
+ + +
+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. + +

+ + + + + +
void des3_encrypt (struct des3_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+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. +
+ +

+ + + + + +
void des3_decrypt (struct des3_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Analogous to des_encrypt +
+ +

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>. + +

+ + + + + +
struct serpent_ctx + Context struct
+ + +
+
+ +

+ + + + + +
SERPENT_BLOCK_SIZE + Constant
+ + +
+The SERPENT block-size, 16 +
+ +

+ + + + + +
SERPENT_MIN_KEY_SIZE + Constant
+ + +
+Minimum SERPENT key size, 16 +
+ +

+ + + + + +
SERPENT_MAX_KEY_SIZE + Constant
+ + +
+Maximum SERPENT key size, 32 +
+ +

+ + + + + +
SERPENT_KEY_SIZE + Constant
+ + +
+Default SERPENT key size, 32 +
+ +

+ + + + + +
void serpent_set_key (struct serpent_ctx *ctx, unsigned length, const uint8_t *key) + Function
+ + +
+Initialize the cipher. The same function is used for both encryption and +decryption. +
+ +

+ + + + + +
void serpent_encrypt (struct serpent_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+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. +
+ +

+ + + + + +
void serpent_decrypt (struct serpent_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Analogous to serpent_encrypt +
+ +

TWOFISH

+ +

Another AES finalist, this one designed by Bruce Schneier and others. +Nettle defines it in <nettle/twofish.h>. + +

+ + + + + +
struct twofish_ctx + Context struct
+ + +
+
+ +

+ + + + + +
TWOFISH_BLOCK_SIZE + Constant
+ + +
+The TWOFISH block-size, 16 +
+ +

+ + + + + +
TWOFISH_MIN_KEY_SIZE + Constant
+ + +
+Minimum TWOFISH key size, 16 +
+ +

+ + + + + +
TWOFISH_MAX_KEY_SIZE + Constant
+ + +
+Maximum TWOFISH key size, 32 +
+ +

+ + + + + +
TWOFISH_KEY_SIZE + Constant
+ + +
+Default TWOFISH key size, 32 +
+ +

+ + + + + +
void twofish_set_key (struct twofish_ctx *ctx, unsigned length, const uint8_t *key) + Function
+ + +
+Initialize the cipher. The same function is used for both encryption and +decryption. +
+ +

+ + + + + +
void twofish_encrypt (struct twofish_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+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. +
+ +

+ + + + + +
void twofish_decrypt (struct twofish_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Analogous to twofish_encrypt +
+ +

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>. + +

+ + + + + +
struct nettle_cipher name context_size block_size key_size set_encrypt_key set_decrypt_key encrypt decrypt + Meta struct
+ + +
+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. +
+ +

+ + + + + + + + + + + + + + + +
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 + 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
+ + +
+ +

Nettle includes such structs for all the regular ciphers, i.e. +ones without weak keys or other oddities. +

+ +

+


+Node: Cipher modes, +Next: , +Previous: Cipher functions, +Up: Reference +
+
+ +

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 See 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 two other modes of operation: Cipher Block Chaining +(CBC) and Counter mode (CTR). CBC is +widely used, but there are a few subtle issues of information leakage. +CTR was standardized more recently, and is believed to be more +secure. + +

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. + +

+ + + + + + + + + + +
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) + Function
+ + +
+ +

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. + +

+ + + + + +
CBC_CTX (context_type, block_size) + Macro
+ + +
+Expands into +
          {
+             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);
+     
+ +

+ + + + + +
CBC_SET_IV (ctx, iv) + Macro
+ + +
+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. +
+ +

+ + + + + + + + + + +
CBC_ENCRYPT (ctx, f, length, dst, src) + Macro
CBC_DECRYPT (ctx, f, length, dst, src) + Macro
+ + +
+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. + +

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. + +

+ + + + + +
void ctr_crypt (void *ctx, nettle_crypt_func f, unsigned block_size, uint8_t *ctr, unsigned length, uint8_t *dst, const uint8_t *src) + Function
+ + +
+ +

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. + +

+ + + + + +
CTR_CTX (context_type, block_size) + Macro
+ + +
+Expands into +
          {
+             context_type ctx;
+             uint8_t ctr[block_size];
+          }
+          
+
+ +

+ + + + + +
CTR_SET_COUNTER (ctx, iv) + Macro
+ + +
+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. +
+ +

+ + + + + +
CTR_CRYPT (ctx, f, length, dst, src) + Macro
+ + +
+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. +
+ +

+


+Node: Keyed hash functions, +Next: , +Previous: Cipher modes, +Up: Reference +
+
+ +

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. + +

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-SHA1, HMAC-SHA256, and HMAC-SHA512. +First, the abstract functions: + +

+ + + + + +
void hmac_set_key (void *outer, void *inner, void *state, const struct nettle_hash *H, unsigned length, const uint8_t *key) + Function
+ + +
+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. +
+ +

+ + + + + +
void hmac_update (void *state, const struct nettle_hash *H, unsigned length, const uint8_t *data) + Function
+ + +
+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. +
+ +

+ + + + + +
void hmac_digest (const void *outer, const void *inner, void *state, const struct nettle_hash *H, unsigned length, uint8_t *digest) + Function
+ + +
+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. + +

+ + + + + +
HMAC_CTX (type) + Macro
+ + +
+Expands into +
          {
+             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);
+     
+ +

+ + + + + +
HMAC_SET_KEY (ctx, H, length, key) + Macro
+ + +
+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. +
+ +

+ + + + + +
HMAC_DIGEST (ctx, H, length, digest) + Macro
+ + +
+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. + +

Concrete HMAC functions

+ +

Now we come to the specialized HMAC functions, which are +easier to use than the general HMAC functions. + +

HMAC-MD5

+ +

+ + + + + +
struct hmac_md5_ctx + Context struct
+ + +
+
+ +

+ + + + + +
void hmac_md5_set_key (struct hmac_md5_ctx *ctx, unsigned key_length, const uint8_t *key) + Function
+ + +
+Initializes the context with the key. +
+ +

+ + + + + +
void hmac_md5_update (struct hmac_md5_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Process some more data. +
+ +

+ + + + + +
void hmac_md5_digest (struct hmac_md5_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+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. +

+ +

HMAC-SHA1

+ +

+ + + + + +
struct hmac_sha1_ctx + Context struct
+ + +
+
+ +

+ + + + + +
void hmac_sha1_set_key (struct hmac_sha1_ctx *ctx, unsigned key_length, const uint8_t *key) + Function
+ + +
+Initializes the context with the key. +
+ +

+ + + + + +
void hmac_sha1_update (struct hmac_sha1_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Process some more data. +
+ +

+ + + + + +
void hmac_sha1_digest (struct hmac_sha1_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+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. +

+ +

HMAC-SHA256

+ +

+ + + + + +
struct hmac_sha256_ctx + Context struct
+ + +
+
+ +

+ + + + + +
void hmac_sha256_set_key (struct hmac_sha256_ctx *ctx, unsigned key_length, const uint8_t *key) + Function
+ + +
+Initializes the context with the key. +
+ +

+ + + + + +
void hmac_sha256_update (struct hmac_sha256_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Process some more data. +
+ +

+ + + + + +
void hmac_sha256_digest (struct hmac_sha256_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+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. +

+ +

HMAC-SHA512

+ +

+ + + + + +
struct hmac_sha512_ctx + Context struct
+ + +
+
+ +

+ + + + + +
void hmac_sha512_set_key (struct hmac_sha512_ctx *ctx, unsigned key_length, const uint8_t *key) + Function
+ + +
+Initializes the context with the key. +
+ +

+ + + + + +
void hmac_sha512_update (struct hmac_sha512_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Process some more data. +
+ +

+ + + + + +
void hmac_sha512_digest (struct hmac_sha512_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+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. +

+ +

+


+Node: Public-key algorithms, +Next: , +Previous: Keyed hash functions, +Up: Reference +
+
+ +

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". + +

+ +
+


+Node: RSA, +Next: , +Previous: Public-key algorithms, +Up: Public-key algorithms +
+
+ +

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 n1. 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. + +

Nettle's RSA support

+ +

Nettle represents RSA keys using two structures that contain +large numbers (of type mpz_t). + +

+ + + + + +
rsa_public_key size n e + Context struct
+ + +
+size is the size, in octets, of the modulo, and is used internally. +n and e is the public key. +
+ +

+ + + + + +
rsa_private_key size d p q a b c + Context struct
+ + +
+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 + +

+ + + + + + + + + + +
void rsa_public_key_init (struct rsa_public_key *pub) + Function
void rsa_private_key_init (struct rsa_private_key *key) + Function
+ + +
+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 + +

+ + + + + + + + + + +
void rsa_public_key_clear (struct rsa_public_key *pub) + Function
void rsa_private_key_clear (struct rsa_private_key *key) + Function
+ + +
+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 +See GMP Allocation. + +

When you have assigned values to the attributes of a key, you must call + +

+ + + + + + + + + + +
int rsa_public_key_prepare (struct rsa_public_key *pub) + Function
int rsa_private_key_prepare (struct rsa_private_key *key) + Function
+ + +
+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: + +

+ + + + + + + + + + + + + + + + + + + + +
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) + Function
+ + +
+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. +
+ +

+ + + + + + + + + + + + + + + + + + + + +
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); + Function
+ + +
+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. +
+ +

+ + + + + + + + + + + + + + + + + + + + +
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) + Function
+ + +
+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. +
+ +

+ + + + + + + + + + + + + + + + + + + + +
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) + Function
+ + +
+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. + +

+ + + + + +
void rsa_compute_root (struct rsa_private_key *key, mpz_t x, const mpz_t m) + Function
+ + +
+Computes x = m^d, efficiently. +
+ +

At last, how do you create new keys? + +

+ + + + + +
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); + Function
+ + +
+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 +See 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. +

+ +

+


+Node: DSA, +Previous: RSA, +Up: Public-key algorithms +
+
+ +

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 +(see 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. + +

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 See GMP 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. + +

+ + + + + +
dsa_public_key p q g y + Context struct
+ + +
+The public parameters described above. +
+ +

+ + + + + +
dsa_private_key x + Context struct
+ + +
+The private key x. +
+ +

Before use, these structs must be initialized by calling one of + +

+ + + + + + + + + + +
void dsa_public_key_init (struct dsa_public_key *pub) + Function
void dsa_private_key_init (struct dsa_private_key *key) + Function
+ + +
+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 + +

+ + + + + + + + + + +
void dsa_public_key_clear (struct dsa_public_key *pub) + Function
void dsa_private_key_clear (struct dsa_private_key *key) + Function
+ + +
+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. + +

+ + + + + +
dsa_signature r s + Context struct
+ + +
+
+ +

+ + + + + + + + + + +
void dsa_signature_init (struct dsa_signature *signature) + Function
void dsa_signature_clear (struct dsa_signature *signature) + Function
+ + +
+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. + +

+ + + + + + + + + + + + + + + + + + + + +
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) + Function
+ + +
+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 +See 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 + +

+ + + + + + + + + + + + + + + + + + + + +
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) + Function
+ + +
+Verifies a signature. Returns 1 if the signature is valid, otherwise 0. +
+ +

Key generation uses mostly the same parameters as the corresponding +RSA 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) + Function
+ + +
+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 +See 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. +

+ +

+


+Node: Randomness, +Next: , +Previous: Public-key algorithms, +Up: Reference +
+
+ +

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. + +

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>. + +

+ + + + + +
struct yarrow256_ctx + Context struct
+ + +
+
+ +

+ + + + + +
struct yarrow_source + Context struct
+ + +
+Information about a single source. +
+ +

+ + + + + +
YARROW256_SEED_FILE_SIZE + Constant
+ + +
+Recommanded size of the Yarrow-256 seed file. +
+ +

+ + + + + +
void yarrow256_init (struct yarrow256_ctx *ctx, unsigned nsources, struct yarrow_source *sources) + Function
+ + +
+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. +
+ +

+ + + + + +
void yarrow256_seed (struct yarrow256_ctx *ctx, unsigned length, uint8_t *seed_file) + Function
+ + +
+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. +

+ +

+ + + + + +
int yarrow256_update (struct yarrow256_ctx *ctx, unsigned source, unsigned entropy, unsigned length, const uint8_t *data) + Function
+ + +
+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. +

+ +

+ + + + + +
void yarrow256_random (struct yarrow256_ctx *ctx, unsigned length, uint8_t *dst) + Function
+ + +
+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. +

+ +

+ + + + + +
int yarrow256_is_seeded (struct yarrow256_ctx *ctx) + Function
+ + +
+Returns 1 if the generator is seeded and ready to generate output, +otherwise 0. +
+ +

+ + + + + +
unsigned yarrow256_needed_sources (struct yarrow256_ctx *ctx) + Function
+ + +
+Returns the number of sources that must reach the threshold before a +slow reseed will happen. Useful primarily when the generator is unseeded. +
+ +

+ + + + + + + + + + +
void yarrow256_fast_reseed (struct yarrow256_ctx *ctx) + Function
void yarrow256_slow_reseed (struct yarrow256_ctx *ctx) + Function
+ + +
+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. + +

+ + + + + +
struct yarrow_key_event_ctx + Context struct
+ + +
+Information about recent key events. +
+ +

+ + + + + +
void yarrow_key_event_init (struct yarrow_key_event_ctx *ctx) + Function
+ + +
+Initializes the context. +
+ +

+ + + + + +
unsigned yarrow_key_event_estimate (struct yarrow_key_event_ctx *ctx, unsigned key, unsigned time) + Function
+ + +
+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. +

+ +

+


+Node: Miscellaneous functions, +Next: , +Previous: Randomness, +Up: Reference +
+
+ +

Miscellaneous functions

+ +

+ + + + + +
uint8_t * memxor (uint8_t *dst, const uint8_t *src, size_t n) + Function
+ + +
+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>. + +

+


+Node: Compatibility functions, +Previous: Miscellaneous functions, +Up: Reference +
+
+ +

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. + +

+


+Node: Nettle soup, +Next: , +Previous: Reference, +Up: Top +
+
+ +

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. + +

+


+Node: Installation, +Next: , +Previous: Nettle soup, +Up: Top +
+
+ +

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. + +

+


+Node: Index, +Previous: Installation, +Up: Top +
+
+ +

Function and Concept Index

+ + + + +
+
+

Footnotes

+
    +
  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.

    + +

+ + + diff --git a/nettle.info b/nettle.info new file mode 100644 index 0000000..3ffca1f --- /dev/null +++ b/nettle.info @@ -0,0 +1,2768 @@ +This is nettle.info, produced by makeinfo version 4.6 from +nettle.texinfo. + +This manual is for the Nettle library (version 2.1), a low-level +cryptographic library. + + Originally written 2001 by Niels Möller, updated 2010. + + 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 + + +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.1), a low-level +cryptographic library. + + Originally written 2001 by Niels Möller, updated 2010. + + 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. + + +File: nettle.info, Node: Introduction, Next: Copyright, Prev: Top, Up: Top + +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. + + +File: nettle.info, Node: Copyright, Next: Conventions, Prev: Introduction, Up: Top + +Copyright +********* + +Nettle is distributed under the GNU General Public License (GPL) (see +the file COPYING for details). However, most of the individual files +are dual licensed under less restrictive licenses like the GNU Lesser +General Public License (LGPL), or are in the public domain. This means +that if you don't use the parts of nettle that are GPL-only, you have +the option to use the Nettle library just as if it were licensed under +the LGPL. 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 Ray Dassen and Niels Möller. Released under the GPL. + +_CAMELLIA_ + The C implementation is by Nippon Telegraph and Telephone + Corporation (NTT), heavily modified by Niels Möller. Assembler for + x86 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. + +_SERPENT_ + The implementation of the SERPENT cipher is written by Ross + Anderson, Eli Biham, and Lars Knudsen, adapted to LSH by Rafael + Sevilla, and to Nettle by Niels Möller. Released under the GPL. + +_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. + + +File: nettle.info, Node: Conventions, Next: Example, Prev: Copyright, Up: Top + +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. + + +File: nettle.info, Node: Example, Next: Linking, Prev: Conventions, Up: Top + +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 + #include + + #include + + #define BUF_SIZE 1000 + + static void + display_hex(unsigned length, uint8_t *data) + { + unsigned i; + + for (i = 0; i'. + + - 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. + +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 `'. + + - 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'. + +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 `'. 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'. + +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 `'. + + 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'. + +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 `'. + + 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'. + +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 +`'. + + 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'. + +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 `'. + + 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'. + +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 +`'. + + 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'. + +`struct nettle_hash' +-------------------- + +Nettle includes a struct including information about the supported hash +functions. It is defined in `', 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_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. + + +File: nettle.info, Node: Cipher functions, Next: Cipher modes, Prev: Hash functions, Up: Reference + +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. + +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 `'. + + - 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, + const uint8_t *DST, 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, + const uint8_t *DST, uint8_t *SRC) + Analogous to `aes_encrypt' + +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 `'. + + - 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, const uint8_t *DST, 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. + +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 `'. + + 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 AES 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, const uint8_t *DST, 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, const uint8_t *DST, uint8_t *SRC) + Analogous to `arctwo_encrypt' + +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 `'. + + - 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, const uint8_t *DST, 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, const uint8_t *DST, uint8_t *SRC) + Analogous to `blowfish_encrypt' + +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 +, 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 `'. + + - 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, const uint8_t *DST, 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. + +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 `'. + + - 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, const uint8_t *DST, 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, const uint8_t *DST, uint8_t *SRC) + Analogous to `cast128_encrypt' + +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 `'. + + - 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, + const uint8_t *DST, 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, + const uint8_t *DST, 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. + +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, +`'. + + - 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, + const uint8_t *DST, 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, + const uint8_t *DST, uint8_t *SRC) + Analogous to `des_encrypt' + +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 `'. + + - 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, const uint8_t *DST, 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, const uint8_t *DST, uint8_t *SRC) + Analogous to `serpent_encrypt' + +TWOFISH +------- + +Another AES finalist, this one designed by Bruce Schneier and others. +Nettle defines it in `'. + + - 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, const uint8_t *DST, 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, const uint8_t *DST, uint8_t *SRC) + Analogous to `twofish_encrypt' + +`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 +`'. + + - 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 + - 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; + Nettle includes such structs for all the _regular_ ciphers, i.e. + ones without weak keys or other oddities. + + +File: nettle.info, Node: Cipher modes, Next: Keyed hash functions, Prev: Cipher functions, Up: Reference + +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 two +other modes of operation: Cipher Block Chaining (CBC) and Counter mode +(CTR). CBC is widely used, but there are a few subtle issues of +information leakage. CTR was standardized more recently, and is +believed to be more secure. + +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 into + { + 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. + +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 into + { + 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. + + +File: nettle.info, Node: Keyed hash functions, Next: Public-key algorithms, Prev: Cipher modes, Up: Reference + +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. + +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 `'. 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-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 into + { + 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. + +Concrete HMAC functions +----------------------- + +Now we come to the specialized HMAC functions, which are easier to use +than the general HMAC functions. + +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. + +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. + +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. + +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. + + +File: nettle.info, Node: Public-key algorithms, Next: Randomness, Prev: Keyed hash functions, Up: Reference + +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. + + +File: nettle.info, Node: RSA, Next: DSA, Prev: Public-key algorithms, Up: Public-key algorithms + +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'. + +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. + + +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. + + +File: nettle.info, Node: DSA, Prev: RSA, Up: Public-key algorithms + +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' 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. + +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 +, 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 `'. + + - 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. + + +File: nettle.info, Node: Miscellaneous functions, Next: Compatibility functions, Prev: Randomness, Up: Reference + +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 `'. + + +File: nettle.info, Node: Compatibility functions, Prev: Miscellaneous functions, Up: Reference + +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 +`'. 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 +`'. 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'. + + +File: nettle.info, Node: Nettle soup, Next: Installation, Prev: Reference, Up: Top + +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. + + +File: nettle.info, Node: Installation, Next: Index, Prev: Nettle soup, Up: Top + +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'. + + +File: nettle.info, Node: Index, Prev: Installation, Up: Top + +Function and Concept Index +************************** + +* Menu: + +* aes_decrypt: Cipher functions. +* aes_encrypt: Cipher functions. +* aes_invert_key: Cipher functions. +* aes_set_decrypt_key: Cipher functions. +* aes_set_encrypt_key: Cipher functions. +* arcfour_crypt: Cipher functions. +* arcfour_set_key: Cipher functions. +* arctwo_decrypt: Cipher functions. +* arctwo_encrypt: Cipher functions. +* arctwo_set_key: Cipher functions. +* arctwo_set_key_ekb: Cipher functions. +* arctwo_set_key_gutmann: Cipher functions. +* Block Cipher: Cipher functions. +* blowfish_decrypt: Cipher functions. +* blowfish_encrypt: Cipher functions. +* blowfish_set_key: Cipher functions. +* camellia_crypt: Cipher functions. +* camellia_invert_key: Cipher functions. +* camellia_set_decrypt_key: Cipher functions. +* camellia_set_encrypt_key: Cipher functions. +* cast128_decrypt: Cipher functions. +* cast128_encrypt: Cipher functions. +* cast128_set_key: Cipher functions. +* CBC Mode: Cipher modes. +* CBC_CTX: Cipher modes. +* CBC_DECRYPT: Cipher modes. +* cbc_decrypt: Cipher modes. +* CBC_ENCRYPT: Cipher modes. +* cbc_encrypt: Cipher modes. +* CBC_SET_IV: Cipher modes. +* Cipher: Cipher functions. +* Cipher Block Chaining: Cipher modes. +* Collision-resistant: Hash functions. +* Conditional entropy: Randomness. +* Counter Mode: Cipher modes. +* CTR Mode: Cipher modes. +* CTR_CRYPT: Cipher modes. +* ctr_crypt: Cipher modes. +* CTR_CTX: Cipher modes. +* CTR_SET_COUNTER: Cipher modes. +* des3_decrypt: Cipher functions. +* des3_encrypt: Cipher functions. +* des3_set_key: Cipher functions. +* des_check_parity: Cipher functions. +* des_decrypt: Cipher functions. +* des_encrypt: Cipher functions. +* des_fix_parity: Cipher functions. +* des_set_key: Cipher functions. +* dsa_generate_keypair: DSA. +* dsa_private_key_clear: DSA. +* dsa_private_key_init: DSA. +* dsa_public_key_clear: DSA. +* dsa_public_key_init: DSA. +* dsa_sha1_sign: DSA. +* dsa_sha1_sign_digest: DSA. +* dsa_sha1_verify: DSA. +* dsa_sha1_verify_digest: DSA. +* dsa_sha256_sign: DSA. +* dsa_sha256_sign_digest: DSA. +* dsa_sha256_verify: DSA. +* dsa_sha256_verify_digest: DSA. +* dsa_signature_clear: DSA. +* dsa_signature_init: DSA. +* Entropy: Randomness. +* Hash function: Hash functions. +* HMAC_CTX: Keyed hash functions. +* HMAC_DIGEST: Keyed hash functions. +* hmac_digest: Keyed hash functions. +* hmac_md5_digest: Keyed hash functions. +* hmac_md5_set_key: Keyed hash functions. +* hmac_md5_update: Keyed hash functions. +* HMAC_SET_KEY: Keyed hash functions. +* hmac_set_key: Keyed hash functions. +* hmac_sha1_digest: Keyed hash functions. +* hmac_sha1_set_key: Keyed hash functions. +* hmac_sha1_update: Keyed hash functions. +* hmac_sha256_digest: Keyed hash functions. +* hmac_sha256_set_key: Keyed hash functions. +* hmac_sha256_update: Keyed hash functions. +* hmac_sha512_digest: Keyed hash functions. +* hmac_sha512_set_key: Keyed hash functions. +* hmac_sha512_update: Keyed hash functions. +* hmac_update: Keyed hash functions. +* Keyed Hash Function: Keyed hash functions. +* MAC: Keyed hash functions. +* md2_digest: Hash functions. +* md2_init: Hash functions. +* md2_update: Hash functions. +* md4_digest: Hash functions. +* md4_init: Hash functions. +* md4_update: Hash functions. +* md5_digest: Hash functions. +* md5_init: Hash functions. +* md5_update: Hash functions. +* memxor: Miscellaneous functions. +* Message Authentication Code: Keyed hash functions. +* One-way: Hash functions. +* One-way function: Public-key algorithms. +* Public Key Cryptography: Public-key algorithms. +* Randomness: Randomness. +* rsa_compute_root: RSA. +* rsa_generate_keypair: RSA. +* rsa_md5_sign: RSA. +* rsa_md5_sign_digest: RSA. +* rsa_md5_verify: RSA. +* rsa_md5_verify_digest: RSA. +* rsa_private_key_clear: RSA. +* rsa_private_key_init: RSA. +* rsa_private_key_prepare: RSA. +* rsa_public_key_clear: RSA. +* rsa_public_key_init: RSA. +* rsa_public_key_prepare: RSA. +* rsa_sha1_sign: RSA. +* rsa_sha1_sign_digest: RSA. +* rsa_sha1_verify: RSA. +* rsa_sha1_verify_digest: RSA. +* rsa_sha256_sign: RSA. +* rsa_sha256_sign_digest: RSA. +* rsa_sha256_verify: RSA. +* rsa_sha256_verify_digest: RSA. +* rsa_sha512_sign: RSA. +* rsa_sha512_sign_digest: RSA. +* rsa_sha512_verify: RSA. +* rsa_sha512_verify_digest: RSA. +* serpent_decrypt: Cipher functions. +* serpent_encrypt: Cipher functions. +* serpent_set_key: Cipher functions. +* sha1_digest: Hash functions. +* sha1_init: Hash functions. +* sha1_update: Hash functions. +* sha224_digest: Hash functions. +* sha224_init: Hash functions. +* sha224_update: Hash functions. +* sha256_digest: Hash functions. +* sha256_init: Hash functions. +* sha256_update: Hash functions. +* sha384_digest: Hash functions. +* sha384_init: Hash functions. +* sha384_update: Hash functions. +* sha512_digest: Hash functions. +* sha512_init: Hash functions. +* sha512_update: Hash functions. +* Stream Cipher: Cipher functions. +* twofish_decrypt: Cipher functions. +* twofish_encrypt: Cipher functions. +* twofish_set_key: Cipher functions. +* yarrow256_fast_reseed: Randomness. +* yarrow256_init: Randomness. +* yarrow256_is_seeded: Randomness. +* yarrow256_needed_sources: Randomness. +* yarrow256_random: Randomness. +* yarrow256_seed: Randomness. +* yarrow256_slow_reseed: Randomness. +* yarrow256_update: Randomness. +* yarrow_key_event_estimate: Randomness. +* yarrow_key_event_init: Randomness. + + + +Tag Table: +Node: Top544 +Node: Introduction1719 +Node: Copyright3281 +Node: Conventions6951 +Node: Example8909 +Node: Linking10201 +Node: Reference11030 +Node: Hash functions11394 +Node: Cipher functions22959 +Node: Cipher modes48587 +Node: Keyed hash functions54929 +Node: Public-key algorithms63350 +Node: RSA67262 +Node: RSA-Footnotes77826 +Ref: RSA-Footnote-177879 +Node: DSA78048 +Node: Randomness89349 +Node: Miscellaneous functions104428 +Node: Compatibility functions104923 +Node: Nettle soup106160 +Node: Installation107149 +Node: Index107992 + +End Tag Table diff --git a/nettle.manifest b/nettle.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/nettle.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/nettle.pdf b/nettle.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6c20a773863e2ee5ae3acd0144ab6e46f7f1a301 GIT binary patch literal 313370 zcma&NQ;=xevMpM+ZQHhO+qP}nwr$(CT{X+LjahH46ZhQvBKFVz>Lc=F{A7=o4cSQ* zM8s$r>6oEN$FJjypjZhQ2<(llpm=!bWlZhNT`UOL{;4R@i&@&Zm^u;Ai`f{un2MMh z+nbp3@j*GeIGGySLV4u4Doxv=Fe3DPQTsgOtUV9!xalVXKq8h5Y$Jd}AQ0Vvksc7r zeRJ8)+qkI##fmM{rFK_)UD64SLHua;tB2no%f_z510F*A*AMFs2u56;T_WVq$u&tN zsAi3PNNdm;vqVH?v})$SALx4V3WBjUK5tTk5G6hPrc~&(o%E&C#2jwps!xt~qQ@br zFiYZd1-3wx{)uEPMwR6+%Ppo7bs$|)ZdR)7$=44vckY0(>0EuEF5LwIUWZg-*5Cml zPEN7_K7+-T_xKIv zwbx)mFYWunT{XSvK2&QQ`&eeQ4Vz8zaY+x{5=pym%zA(TV?kOwloFp2Vb%T46rqH6 z$<+m6jlaS4{=Ex(<1JYIc+6mFv6)R?Qw~$|qKK#D#`B({8`f`f>Oe8IGx<-L-PW`FSM6A^a%Tyvq90LXCpC5B zw2Nz{;S_jdv_;BeoiDR!V02*ztL0C++0St+vKPr>DGR)^d{uzcX}uKGuYr$_xwfu1 zSgoKneJRmnhYeP1@4r)Ndmb(uH2^X&Ov=n>0g66*x1%$9U{5lN3Z^Mrq9gW8;;H9| z1)h_U!^e-bK1vxrbnLcLlqDnO1`Q;1V;{duIa?HcRh-|?7R7RHZkLkZ@S^%<9)R3< z4I~CcNoporS2wv$MO|oX4BP&4%%T3SBne4-GT&o#1=&mE15WH?FArsww2@25M)Jr1 zUhmr5Kyigg9B<)9$S>_jDaWp4|40qezjTutfw-!7L!l+vY}Qgd`hePPf*q7Djf9=s z054|?pnZvrC1^kR(8%)5%lXypKvvq5wX>;^gXY{I=F)<|Vgw3)D%1ot5FE1e?<-xK z39nJj+mjJZL8j>TAg$5Yf|9kR866yJ$uQy_T3b`jy60@5E06OLD={A8WVwk5wMd8z z@XUfW%E(=xKuw#NiuW>9_*E;R*fPoeaC-^=3Z73qLXkk9HATAe2#^mQTMoV3Z7)rT z6@b9=-qS`IRJr)<4*?G$l|yDLe_xJ737$SIMQ#djGJCr@6ZaEu<`p3i|E8OG*TWuo zQ*Gu=*!?M3^+vL~5SII)^03p37 zCy5nS-7w{vDnb4PqEv6O!fM;v9|gog0GhCy*FliK9eG65O!kmh;4_iB;h&UZP7NU? z)bD_jRUXzJTUUQsN5v{6NQIl)H428$eNjE3Y&U^?z)Tympc%o|Sk|#0$KCmA$QkO> zh>B3_s)`d2X$x3MO6jQg=%)F*xo9*;j-?T=e6H~x#ibsKtR#l2n9L&EtT2oU+G8QO zK&SlpoC4TMLK>@oVkZyXcwW^m5KNEhB;Ax8aei!jT6w&meW5b95ye2OhcsJ4>{Jkt z3FB9J+%i|&lTE^1YTU?V{_$N%f)QwfjwCkzjG<-sRyMQj^g9Kgh+{eWnH(;W8~P*D z12+n)H{(619F{-Ll|+7G+Q=F|K9(^tK^JZqHy9tB<~Z*!soUvw_faWQcpQ{;tlRCG zVSa4V-Lqr+w;=x)Ko&ct`adw^f6(Ax(BS0wzo5ay@E@~;iSfS~CO0~^&VM=(|K92s z#;cfz7&QX8E!w;H>g+AGkK}$iEMJt!9h%T}9w+IQzuk2MP$H%XL?xYPG_m5v8$xLa zj67XKHw?%_*BTTa$v?fF{;byLFCM-=rRsgl`PtX|bp@#yE`E1<_P>8>Q2|aMqq+o) zzFbvzvC`l)K;@y0RBX`J?dkjK_v+TQFv)p?|MvVXW`Tt!FdgXJa59zMF)0$Gs28P9$c+HftsX(>HECzqT?1{wKrY{NNcI) z`|c1?D1fZ`9ZAcAkviH?`TH>F#GtAR4&;92BlinZKKO7-E#bbF{f^8VogbPAmbi%DMyQPwElo(@(nGd5)1@bXQe?sYD9aHIN7tOBO z-Tn~W==d09BQVR|t#>L$790g0+?^13fqbXf{}WCvajM zD_(Y)9zl(^(SZ}sIbzrBX0OC;OgZcbX+sDx+ItgFdj~t?jD~N5J`S*eDGG3v$s!D3 zqO3mj1Muw#Jn%b~RPk9cF6v(h4> zZ$@@gq)rQ0C7`Ak{?f9^2+=|dlrOSU;69`AW8ZlzjuU+@@E#CW^#*C2hZAkIZE&Fr z){d4%s>4W)aPntVHPEBih9|ny8)N%?^bi4vm&ys-`ZNlnWDG*uP}drEuza#XOY9b7 zZB4)0&mu6>y0d1?wtX2FA_^UfXKEKOX0%gg=eqlyXe&W!yEV@eYv@o5`x7l{Udb0S zQUu%V_0<(hb%E(iXY+*4aGa~%ak9Y-My^kC@E8u@X|ecl+HDa#59TvOkEcymVdzg) zWj9xY&@)wohQ<9?K&DFK!<}0NGxRf<{}wp<0wh`J!fpHWu8r z3&im^)-m00P+)Pe;2(nVSr(9ujtnjoytL@ADm{^%P6~aBOM@_KmeJcP^>m~$DHq`t zBn#kMtw`+Z9(N%Om4vmlFwEw+4>K4+P_Qsez%#rBD zAx#vtv;_Ji6lEZ7yKzm~2ho+>h%F;wkoW;5AINs#G~ozf!NO&?430jsIAXpy4l}63 z3}{EXA~We629ca%S~xjD9B;xo(UnZ3@c0&vSAs*H_&~%Egg3!{DbYA+aRwP2H9iby z9>+OUbachh`LEy%SZ9vCe(b{tf!3V@8^pTyP9R71g&Yf$Z4@2L-e$6)#y}k`DgNMu zqd1jw^99VAPtg^|BCw+G7@1)}{zy#6BTXQ3Efju6X_@IHL-3oSq;aZCIZYs88b_ZJ z+CoZ=CAvgbIt`;qhi`wwNn=!3e;UrMw0jhq!8B5zMpAUew+SR?avI1#G>j{QPU)nS zinJhR`sN+0qw=;7XKfzI>$-$mC)wKxrx(>l4K?p|8gKfx53<@mi)j4mR4EZqTNHJN8<7?OLew&Wsts4cr8x{?>c?NDN}kf>oIH;h1QABSRMHoZLz zrFcHrSaO^?{Mo+t$;R`76#1Lg)C+8lUghtSMam93<*8d>(*W!pYtDKVueZV?77!q1 z;O=e&au3j;-#&Vm#-sp;;k2EOF!ukm@QF>Pf;loVmolt= zkkX9ZF4t16*$0so>eLv~{_tVoFbQ!d(#xIpkXbaZylXt!@&>boZOu0wwBwE`(zD>F zi2Kxb0hw~zkekm!|F%YrhptEtg>^KDih@bhyCFG@JCgTa)a}@Bf$Z;WZhmg+uGx*b zIlA#QD$@hY`9ReChw(m<)%;{EBaJ}RTO!U}kg+XDE6saZUkylPAiNI5VFT`1-lrZu z02W?v1ua)j7XnKC9p$|dxoKN7T+3a87(V?wf!<1VODidb;|Mln$b~}O_IwX7!2YbR zN`Je`>4brkjkoKRN@b&O4g@WE(|-GK#B7lHOZ&HD`J6rzdbL~4At;S#d1MMZM}wcs zUj>hnBC?3GBUnBe(&zlNvXy@0w5RILu-$$-uEEDd#YaTkE+3ZlO8=Z9IKE5Xo}^<` zE;>Vhj*oMV+5TjZ4M$fC>dLq#*ZfRUB2(QS+i3jgOsRUQBU&@(favr!T{zg?YC!;d z(T^_05(!Rmo+X0)5>D}#q-wX_a_v)?a%@g$+a_xXuNt6O7O1C@5uHR1c|~LlSm+C{ z93Xx$<(StpC4+fq3c3coIcycUf@bq{dwCJKL@1iTQQ61-n8C~N4LOLS&I>Lv3|I2X zZXfs(%mi>JO(6ZeLv?bHpv3!MH;+{G8sz}Dm9RIRM7Dqaz5(8JXo`L#jQGnH(+2OY z9LeX$6J&7a^Q90YNJori3R46-?rS2 z9BR7-g~G&++%%ur(dU$n%Q7DQc1C#RA_Spe%!*VfbVDtopAuwkBK5UgN9xgEa}U1Wyy^o#vb<)_d?m~h z^UI9%CVJIFT+qVAt0g*I8e0qVCC6pDD+Ud!-u4cMRXwS0=Lrf>BzOBt5)?wLEuKtj zy*urdi%yySAR($-*=v(eOX~B(#6mZI$2cZ7G!mULU|U%c-_|LMMV&gaxSPB$p4<#A zoCdMxph4p%MdT4wF0Z4}^DYQau1%F|Up~ged~-3w=T-|n>Mgk+Gspo0K4*WvBDp)) zEnN=SsjnjMmelIE}8nLT*|kQSf%>h81U&X7O| z@rKh2Gx~B}s|z0YVYsY}iIRPpd$N8u`m*M01?_{uZT?yQ%$bTn!24O4NrnP;r|V5b zGPR9yi6)_x)H)(=wSV@iu*l-v+d@R7p2q!zI%k(7~7{o(fJtq-q$oKr1 zMoIjlZZbhQNZcB8bzK%G9TOr-GvN;-ijLOc%`~!hC>O58(I+eu0JfS5yj(w8l{D!>+I{k+G%h9#$t13Q^VW0BPx3!<-w)mxBG@vXQt(ydFwSVdi zkjQ(cpC;Zt3585{t@BN`4Lb*3JqG{*D@BO8a8MZd5KyjVDwfN&^%0B~GiXQG4*=E0 z)%Dpbg!T)@Z(H{lgPd!My%|+lu_h25w0H~$Tp|{j15dH~XA+ zV`->Kwy0Vbp{zEjV66_cw@u+}Yg@9ls^kK7F8E~&mv}}x$@RVkYLr55=X&U((BQoWN^|}>QPZzmNZ8!-iwX^5@ItaibiB`*;?a=sI?8w zTZIB7JtDn06>_NH;GI)p-SNx-3Dg;=twn;g5^3r=+c7~-Ja>qA*3_fSkZVX5ccOg4 z%S#bok|;-v577dY3;M*UY}u%Z32eJq1PMGBw#eRi@Ma(RTY;%K=3FI0D z{_L8k#4A;W8yw855hOPx6id?R^%cmQ-6rdYF>)GS=@J8XtgKh3Zc=E7v-xJKWrN%5 zZ#Ks9h+%D$P*kJgzrVLfxvES(hM-^?JU{Besjy%#x)uhg$vk8fhvse}hQo5?N%=Q2 z!;(d14OJgLqm}CXq4BnlC6EmwY7L+D+HZNbQg9~yAKwjn13YES5~2C8Lfmo%^fkY5 z!l`x3WP`)H&Xy^nF75{|HB3D7s<%aZ2F#a6G2B{3vrW4jr6g8`b6d@Ks+-i7<6U=J ze}SBHQ7|>o*CKW*Ixu{T_p)_(W( zJNOK=c@V{>nncJW_vqg{4H0vIg=x~hTzP4``6aPQL?WX{p(vgQSQ_*fC(giq1jPl7 zT_P{2x&V}19eK3dIE}ZHV1uR+(2^giTm=td#aFl=0ztZ0r$uzsBnYVeih0<<_?bUV zu@fpZ&LKI(6LjdN==P)4?EdQ8B8X6%-4S_&CHROAYUd3?h>Mq_Z%2@Ap6*%jny(_- zA%lN}=?|QOn1B*c^pG`HuMQxW4cuS05+wt(FbfMuv4>d*Zmu4Qcu$5Z5)!Y_p_q(T z60nX;1$JtKvf?y_jnVbQjZs0_A|`5z2*^J5efGxNMtAQ;rk1-@g3GIimR;{-R%qXe z)cXZC(xZbUKM2p^72|gGT`10lZ()0ZR znneTI{sY|q2ekjiaYhz~{|D~>YZ(6jz@7cS0ry#LX=l}O#9ivYh+B^KL2yrg9_b}I za!PdMjwzy3b3i175E4Kn1K(dR^G7moGnvr=3aLdpeXbc7w-*=V>pR0&#*Gukf&Np! z^L24}KgaR(_VFVRZ})pAi&w;%XgKM=xw^Q&2PkNgkosv9MLc}IUMcR=M-*|s3(^ha z}mw+f`@4K^qA|It;#%|}Z@7mv$LowXU zLs$tPc%JU5um~1MI_j{0eLvHQi?@wpfn{^@hA$#J-rM8-qQ;kkan_2aH!2M1~g zt!`kbA}HV3{M*oGK>RL7pSTO%KL~%+rabduDR&G`%S~FY%jhQUrARc3QMa%pBM_W@ zEm7!%x(96X{C*W$3TzX#tu2|}M1pU-r>$Af!=_YN&4k*{ zTk5w%BOO-TC5VG;;-tMgO~-A{JP#;vQg6xpU7g-w6}|K-QHTXb&x{HzD-8x0WM0s# z7U4f0Q8Q3^uUrj@e{P{BK@D?{-eg*}ZD&6GB-wh0mY~elpH%TsGEHC?rxu=}jrh&5 zh9!YMN?d6md7JwY;#X z9SZ;y2&OY2K)JjFu3JzGRQcDaKaxYpfw|I$BS7Q>vfT8A&o2oa$B|}RHxRUcna^D# z(pBqW+kh!fe1=Pa>I}jYa`>(#8V0#vut+(SIOLK#Izl{)3ChG4BPCfXsPD?@(MO}q zHLW~FaT~hvVDV7EHqag27y&4s5L6cjb~I1bNMR`nV!**rPIuEphE|AU+LA!C)dhUMr52X&k$z5(fSh$t?bcJ+2;xyY$?SxSFj?8%k%pbPq zX~!$M4O%o18Uhwc$d6knF$PVSz9HXTGgB?8Wlf4~DzkS}Oa)au@sVFetO`-d*aXF0 z)C*q=Q2XS9Ab)lut9ViziNHBCeB)bInr&X>7jI+P#|^F|Q%Wfl?{E0Uod%lg{vC zb$0CZzeZe@Mg(gIVH6deuWqTu@JLcXgb;y@zGyj%$)r`9PX6OoI1obk+n<31<|Hk1 z2m;)R!z6$-!CC69LLX+fP5+i`CitQSBrMIEYiD8G65VuL7U`kOHs=VK%9$dg(M2hi zfz3}#-Lf(cu!aY>PfU%8G(e#CQ18?n8#C8Pv2YHoCBAyLB7iTFZBp)YDgmLe&r-?S zSqV$lY;-Lu^jeE!`!J{9RLQIq9?0g`9g1wJRReQ~8}CV^KO=Qqbk%Tu$u27if(?2v{5t%9TP;Rnm zIijjQ$f>*@f4zI1G*KxfpJL5w_e*x$ur$)kJLJC_Qdr-sq`9ADc}eQwf0eCH7zj4a z5wg~j1@b7_rVin)JTlcNgm&vO0aJ6P^i7hK91~vIBHu~|10Bd_tPQB?$Hh5L2uM{@ulA`%}Y4gLZqKeab*1SPt4(?FGp((5!7h zcWtx52$FEDu+nMqjhzjHk13Uc>;aTuUio0ER}+f$6S@SfK+5}ifS@O7_(%x6f1PmH zJKACU^_V5NWiz1K#d=jIYx<65kzO->otce|10|}Q2=!1|Cv~-6E0Jqu(m+P60*+@E z`c3ZcMF_3|YC_PZ3{0-u@>Il5PQKu^9KkCL+^(sMXwfqsJH`?0#~^+8vVaq6-?ac^ ztH0vI8$N!8G(B)9D~L$f5F-SA#dPcJX`o;Ln0ckBj9Kq5y;gfgPY}p0!9J>amvT%R zM#+ZV*NmvR&VV8FQIoS~L)Jf^A*?9ss%ufZ>SRGZu6K1{DOA;;_7h+)uwkRZkL2?- znJki1>NSiue_3BQ!>mxvy?Vr70zRTy*%!)6dGORD3)ZaLPgCg#@q8P3riUs<(7qJYVv$G*Ei zSpt&VOOLooS15X%9BZgYW%9U+Iox$FfvJl2r-a6r?|cn-zmwAI3?nSW{1AcjF94L2 z<7z-M_D?9%4R!z007`*_=e(N)lNKnrJw%?~6b3;uAT#p9qR_*jksBV)g#@^Gf^ktT zyF>Iy%X8n-DjXpKm_24Jy2W(|k(9YhpBCm3*R$k5p8Q2hn?RLpYaYu3w%Py%t|QYt zmJUyWd!<#!U7cazvrS7buR6s)ag>5riC=k1w;`~VS3^~aAE#{yfR+PQ$*nSfx&SE$ z=b)iVm!TFbn(T;|d9j=nVl5URa7C(IQiT`9GGSJG7a%KVla{x@`3`Gt zPC8wJ2*AozVbOK%*sHo#rdj$c<&WzLB&YzZs--}3s|-Y1dBePCeTuL7Bz=Ver?;T$ zejGyFSY*{NK{v=&326yFL-p*v6U14(bJG#FzKBc=qH?BD^&StIrvN(62P=Ek`Rr1#pkO_u8c@~pAhjt2GmEy^%r&I zi1bk|whvyE<4L#KiX{~uiyVum@+3$9#KJ*QEz$vFoh!m&XYKCkd{Fxcc|7>tqfz-v zpb(GbF+5uP*ybp(jdemMNZ(m8V=75jW^|#P?q-j6xKK09q9!fU%C5XrVEvy5s;X^| z38ii+%fP=uh;CrE0N00DzIRyqSkqT1<6>yHmdx2{t$Qr9IjXdefez{I<4ryDe@-@M z#CFScf09CwrW;;Xh#^Q4!Th!Of`9!KJ6odScG?UC7Jb8g zUJ9P5An|2nd7A1kdnMyog+C-P%k{TQmV}vChF+b=sG4);+CJOSDSmlQ=X=`ywH2R7 zxDBw+nc{;Oa~B;|rJb0cpMzAeT~hQsx(zhJCUSMd1AVK>U)++}^KorEM$UN5weUSJ z0tWNnz9DTddpB;K_&#Rb-#cHsE!<qa%o z$t2H-+7}(jK1Ka9BAyk%9fn?)UA8FevTL#Ml#;|X93ZfVw|^Q6v3_{Ccf1bS1(weo0(m6BZ`9a z#4D;>F+`cgNLt6aIm53rfi$h0+FQ=R4aYP6&3)F_N0s31Td4Hi1!h(jSo-sR)r|KG z9{U*?PClTA2ek9U56Y0(Bh9nI=--_?w9G@n&sq3zt-d6^g{Nmb?# z$%em;O512|jY(=??(t)e7OwR}_Ld?+(lM!DY~-2VUbXxqSmGs~#16||60iJBK|KC- zWL@;~BGB7C3BB-mUpFjI{)JRMVzlm0r`TPVp4`F@!?a}Troj=K<_(fl+cDV9s(&_m zF$O@%*+Yqjo-@hpmdrQTY{P|=uh0IjX{V)yUG{P&3fD~c`jd>~Ynw9$5bL{62v*{j zn0Ii8_hd|>{@ltgIejHke^+ld$#a&2%x`7vTId;74xpak-}$t2vAB0I?+@5f4l($j zYVco`_pcgcW@Y%lsV@uje^`AiEdPxfywTBi#%)jZGyf33w}n?e#CVh5y&j26mR;*+ z(ydczf^V`@qe*O|h`ot!^U0?Q%m_w9N1q8yz;Ldv5_1o7lzG&=dYjVJbS1-uu; z+w0-1MEO<{TYahP;yd4sZ%rnwntFSgv zfVvmb*@orkZ4_TF#wnT=j-%HDY@5;Pz8;@Hu6${Dd#y-fZhi5Lj1F*3Tc4|4j#iDU z2>aN)ry;x=f38KxfH1Qnb<4vPsdWf~xL4{}%Cy!YJbiD`!xDEP!nns}DN{temwk$U zSJTz&VLUln|L5c$zoUv>j7oDdGcy0jXI2EHSQP}URg3gYl_lKT=h}cAZoX~yxTu$m zFLYV&tTHvmtqXb2uDNG8pK63b0q#UL05y^X*#s+FubZZxm%9H^n+zX<%F??@O*s?{55qgf0JiLAx0-m`6(Fe8&kn<)@tSr>6uqk+5G6F2@*L+j{ z=pO*yAv?|bbdz_xb(Nver|3=dW*4nv3Jk@QTa}Y&!3vw6EU2N(C`tJREfY=}0NQ+bk3{^@%5@A%3z)iQSyndZ6CgkN8=POe zUtg?WyX+zcu5I+3mxyt51}=k==7cL2O=;EXKG+XWTXNLCO;+^uc>YpIwW zMmIuhvR(6QDU(ec*QEZ*=HcUNdGLf&_hR+U8u3jf!pExyEvut*OWE!-;s|+t>L*h# zMk@YzPf0#HV>7Q$yXIrLG0VfTiliV>ySJRb$A3ayVZm7|O=nG=l{W8_OfCyN7-xX2 zLLln1Km{yC0ohy0Ve*~()Ad@Ivkzr@MhDY!2-|M?@U#y#o~@TxWLk z2o!=Khp^0R_Sj}_0GC^gUCFe>WQ;a5h?^=^5locXjt$1x&Y^&-tT{N~~Qhr&KGdh@Z#071A0kdO0&>$0aJYf(WgmG=17ntFZW~PO3Ac>c? z=FeqDhz5hA2m0WnbqY`ichn~%1@!>LH>A`6Wm$T=$%HpB!|ZRwgL2S)Vovpx$U1X1 zsWzdK=3Py!sFRf}*Et%CZg!%VXQ33;j}2SZ5`HQ5)Uhtxu|2`W*-<-1Tak^B(h3a4 zw~=Bun|Qb$y(#)3yZK(Cx2j2p0B#Q_Yp*o9MXMA#tLnL@o{B?bU!zr0n;&cH&CXjh zwLt8X*{S*t!ULGpy#+pW2?iy~Jdt`Qu76Fz*|B-4Rss_a>;uHKbZ*f}^v)exERDBQ z|8azWBkkJ^$g<7a1mB}3p79BeJQGbxLU??x752rWPQ)n0F{Q$JQB-w{`xG!ApplK| zhF&Um3SH)DY3&4`LCmqVPHH$vNxC0TzhDeW%te7I2QFft7zLVZuN92b;hQ4}$u1Dp zSw%QH^s;bLW${F_bO&lBB~ z`BDqbR+tL$(pY(WOgk7My(l@jr#5Z$>7{zdwZ24hzhG*FimIKLnr>WSgRVk8E$Dtx z8KDN66FNJq3+4aU;w#rEu?-vE*3Oe430Mzjm-)Djqma@;!N9tF1vrU@R$a)hR^ zi{{--$=jsVtItq9)e}h8V35$IZd||t;KN33pGJqA5#q`&B?!TD zV9=~%CW}*hJ1^h#v(+|$llF$7=%Hw)R=I)+D^Vo?GB90!LQgeUqmdHKkcRlOm7-oZ zQv9Y7Qg-czP@dg_p{iqbzl9qlm!xj(vav=Gy?t!mvH@YI{!P=!72k|IA&l%Wpj%p;4o)YkZiqS^{h zNNtntzL8-VXwl$t?g_3KKHPw(Ro`_=cGsIvaXV?(^(<023j=xwax1OFiif6pWB`7~ znaS`@WraW)prgbTQmWZFN`HNGWIW#Wcn4aAQ09eR#F?@CT%IqO65xe`;G9~ALxlLc z;%D%)bb(<`QUN%)V3zatu#*zU@l2Bn6Rp`de+9iGL3t4r?Gb^P*ES#MmWoQ9eBh}%C^ZTx8cE>quFwa&$kmX!#8o6}T; z;t-)O7(-BjA*T>bO#}x&@bSYcB>B?JOi_CW<`0$yxJvJotC_S}QRRz)7*a5euK`hi zZxc1*NZl%}+QGz0t%#N`i60Cz72+B|h9LJe5cqcz)6qdoV{|y7zN(v&*!K*Z&05KT zA-z82P&{~?j!UZ9?(y{_EM*8{)BFgx%a5`dP>gRmZLrum6nN-tbQjAIhc0x!Ua-Kf zL`Mc0-PyK8pS2mRRpZ8fvJZE0Rx8WQsPvA5+}3V=J*csk5kO3Um?4mg@$Tn5O@Q5)fO*M|<&#+lpGfwUaGUgI_mbHYw zcNDA{3<_F^OXD9OHmGGyqzX47%)$bP=;0`qvPxCA^PmMmU|PI< z$`-o>!q+%TdY+KG`3u6XDEfy&xBy}}{bG<(u+}``_$|_T#E4dm1AYwvBSzM9>KTF7 zEES`?^7a6n+Y@|ZPJuq%>|n+ce>wQvh)Pj;G4L5*-Cj}WNs2vaQ-IWj*&Q?!g6TOI z0$}oK8-sX)D|!|ilEPpb7QM%PxOC6 z>h(F7@yXKQBlTWrO-Iqioz=!YB!f|B1yNBE1QA_Z^0+aSN7#L8jzNw~p$k<=U^PMNU^5_FV2GbF24DwAg$hV>~I@T_w9LI8~*;nB7>FVM;12Z@VDs#16#uD z+FWcWE2Dq1yk&?>Ru}v4PteYGn%eFTcCAGUo)SX&az#ND;GB1N%hh3z_8u)?BxO%_ z&;*o?EY9}r9m-20W;O%Q$WzUaHWxB-(^Q_-aUzz1C$SdC%u_3AMJHL9Jb9?Pdh$=d z+>T_oa@`+o9Vds{(w(ki$=x)j$&PU{Yw@S!Yau%YaIe!+!s^FQ&eUOWaAISlsf+9z!PdudCene7^~$i%9D{#x?f2)D^}^Fu$pO0n!5$AgnN^Vi#4E>Ss&0j zm`E`W<%gt5XTrJ+{d3IPlf$RERvsk8J1h6+&**DcJ^JdnoihiDg}7{_FRlzpF@;Gu zhJB|gyoUFUk0GKozV<>|g=!kRS`F)tFM8}W^Q{X6{Mqs{#01As)iOnpeWf|pNr;JA z?PY$Tf9VK-{NsSymE2%+O+m3>77?$lmpioXoD=VC4@a%nn7Y<~=m~Uzng2*&gx?s7 zF>+39^ZubH1mc+slA1E40tcsU0(tGN_ZoYD)XWX2yxaV6tHLr8(y9u3>XjM~LP=XI zgXdySU)B4YmeU*jwn`v~4Kj&4(w?M7+=mC3AWUa&csnLQo`T(=*4_Nyp`$?(V z;Yo4#`W-0DxwM``XRr|+7YB325NZ?2P;2}K{@nN?Y{?sO-)Xw-3Qklzwe*C|5^fvq zpRR6+MO__2mWZfv_F0o0>758CuAr2i#BgKkN={WRn9O}k1v$HI;JmM zI>5D|zrhufffY^UZk8OO`=$|~0m4l0;oW2!3}fFfNle?k+Mb&xQUR3W20Bc%Zfdl` zXGa1lOI!5?X4Zt95=+Bz{QR&MwXy;Z-#e zysGVKJ14WZ3%sTvwM2Rnzp62qrZH>>mkxMyY%R1%>Pi*sNXXwC2_L^&ac>AA5@oZ6 zi)gd&mJn|(*erCVzufb|TJJi<4qBly4x(%TI<}cUqapRfmU~7NRj7cWeaqzf*)eSJ zX6PtY)~-lW$;yj`U4g^}V6zAr)|-}9!-LLOnUWBHi<7=}J{h^|8&Ag|^m4V9)^Uh7UV>)SQNukTv6s>ULQ33T3JmmfI0@fvJb!y3WM}Oe`#O7SFx@#UDbrWO# z)NGMq^_p3Y#rZUZs{WJB@^)HXKLpF;{uT;~N3-RH8Y=6XUVX?Bob(3NlYIxU%eI&= zV&=R)u{}xyth|2MC#N{Zf}YTMd^HyBcmb-actI+~NuM*Y_W+Im-TJr8F^L0PZ_i4m zmvn6P1skjSGma`WJiD8e-OCa0*EUbYcr9n@YDmV{h)<+co);}#_+ilyAH$!kcUJ5w z^c=f#J#?dw^RyT?**STSR=b|vMV$h!&fmI}a@mx#YD3ML@!VQp6-GHpK=osg70`+2 z20bL{h|&YwvLbi(7X`TTgg}6 zIG4)Z;r(C4)Uc&L{Ekkqd`s}a^d0c*Ukpexh4%a4RqgYIFm5<{)^&w0bCTnv7(1VH zLccJiPIw%3lua?o$oXdX4u$QRtgEOj4~%X|+bot`UYzp^nN^N56l~~VjWAOoFalOdml+xJx22#=#0B`~_Kt zXt@YOXfDfugncAhjq}ZI%smiuJTlGEY)koMq(5;P;xTd^7b(n3>v+HTQ#YA$pRcR@ z{+&O~(aFC-{=eXkpLSFK;U4~vEBLQ_$jZRM`M-;TEFAyo9&-Ly?xCi%y(&Ax?wR_w z?tE%i@Lv3FLFodz?136h6`c?g5G`bi0A=;x7eC`KocMX-62OuwAw?8@bDQ|HhgtSM ze;W~c_8`Bhz2fFx?6;rOXCrx=+x<6}yLjGA5Vn)~#m&<-I3XpYvUsAY+1m#_Jz91} z8=nQ=hU}fqUHYAL?M3V2qNg2XEGt5zYdA&}GAdisw<5XzqQaD+?pu>?daqK~fuZz2 zzO}Gzk-0|D{TsK~#-9|foTAz%-Dk6FRL@)03%#;`C{KL0;EexSB-vSJVH-3^R@Sl% zZ4(n(Z$a`_$@Sau?KV%js&(wRxW#B+eqs2$i~Ztq%D#p_{33e=1V2@Ux0ptVZP>Ae zF-@5IbIS+Y>b~Uy?wSU<{l~DTCr0UHSPNWZ?}(t%8#44!u-gjF%qK&QdUL!W?8+Ne z)?LgUa)`^kSzaZg(0h!eL%zc$lbx~SmIssW(ulpb)Usz*M+eRw$^A%=oBRibEoS!l zsHUwk@b1TC<(Y&&xV9;9`Pi0A*yEz)VRA?cq~kL{-W(I%(0gyE7`YctjWdHjze2`+ zq;A5P47^^2sU<6Bh(5Z})@Dt2q2(Ny=ZVZb0?{x+rcl?SWYhPIvZx1g+bli_97oK4 zdUNii`Yg6nmOcr+IJK~X#QV(D-B}v2tn^M5!}zC1?}bBm)w39jwBys~Y_0Q%E`K?& zO)6H28g)i!AjOJl82FJV~Klq6&no{SVaP{RSy%LppmKB4<5yJRu>`-{S7O zWllA#KXw~>IERJo3`g!Pw8g@g$1MZ?z5ahhF_J~E_$480; zvsxSS&DXk-X-=gGSqolytnIU`)>J#Q(Jd{>2*X(TMALM2`^H-I2!TFH`VX4BYlM?{ zD#0j_^$b7eV|F*j(U?4P?-}_iGi3_I$0NOz1E2)Tql5$E;^{QV4e}T@K)TRu#{?&* zCQCLGs$7_Kl-hq_-=-RMS0o#4g$M6_Dk3@BBW>Zva7rluwg}a@@|Q5ca{MQ>$ihF^R#{GI3mi={6RLCLzO{0Y}1c^IjZq+NjjN;aY?&ZweA?NQ3pMQ<8yJZ zNWmH~v3bZ3_trnMZY)SA!uGDbuF2TzrCe51_2;R;zARP#KJ zZMCi#Y4^=sZ7Im4A=F!snp@f2Gc%wXZxu}kUneY{Yc*>m%ChRc&CNb^P&P|c$0KbD zgHGoy(gr*K^v1HdGQS5DGerhb(|_2{0YQwkUY2uqyzNS^$yK$Qt2Y=Tvq5LHZrZGP z&33Zoh*=DU3iwzvP@18d*XVhKs7d3WZO>lYp;D*;b-ynf15OD?qBlj?G`ujPWKcs8 z#DkL2pkNS=oGV#+5sEGB7Q?Sxvfv_hxSTqA-;AnjR#KLr(AUmXCrs5WZ}U8C&_2h$ z#0wTP0uw8ax6=41SrqD2si3ZztnKqQ|m(i=b1^&PUw`O?yhi`<84NK0-eNY2ge|deE&~qO>BAZn$*iRB0Cz z8k#sZn|xS%ox50FeXC7vcHK*_;D^dTdhCV^KeTC+{#mjpC@U=rDM z5%DT!m{X4ySnqO?a)fhH%3Q`%J>uvD48vv$#Yu@Fn{My{CA!oVUpCgv>!p z(2XC7Wd{;~Lu)Q}taz*^StK!;5isqxJAk;swX586^?}3R+vtNNi2 zt;TI`-WEQY8ZN7*dx@^*&_Gf^G`TMEqpg{e=G`mW3>VeiSuAn*_|B_dP07D=cTkkv0+(KZM34^D)oIr_Iov1gIepR-O^$Qs2lZdvl zS-niNdENA2(P3llhJ^Hh(XSpRU!EEa4W*AFiTALMZ5?_42SdnU;95s7Aq)o0;2tzX z2MJMgJ|x3?I2@a`Y5iA&%+pQlPt&_pg`G+NA3e#oM@QZy9T|NXUE(AOLa#rco?AP# zEXe4Z$m|RSrDXvsh(bs2GuR6^V!R{B_P_9tW`b9(_4ZDC8SbaM8ee#&AgLg>+V(`? z7eh2nUbf4R6=ok>>Aj`h?peY^nsSzmoX?^{oct#Q*6c=nr{(oN#ACv>^@r*sq4gAE z0`Q@~A<+2_2gr0ZheHyyf5|%>yxZT9{r&=?#yg_^C*}B;O8iSXm>Ad@{+DvF{%2sx z`dy*iS~xTA=D@gIoJPuN2BmA(&%KsXy4aKkw;a6(Hk#6YwKn35CyyP2A+x|-To zl6agbAz6N{CMTb!YHfbp=+Qjr@8rKf@0*+Ed!J9)f0!Nrn!n$jUbiz#0?$3^$LHtz z`#}bmgs@AaDCX(^bxAXuexjKBcX{z|qzd0q|P%(p|B{h71 z+PeEYMd|&mgRdh>^b*&=NIJTBEi4T(e3tC@^5`N)vqO<$DkNbzk=bSUg+=@ z^htU_Z9SS?Klm{F-%LMtJ<;Ww)f78b|xj>FN$f%47%i`M%im zrTQr?XqzrN;`p*UK`ex_OX%WPD@LWo%>eST=&$#OAE9Z`{~u%T)SX$lZH>l8#kOtR zwr$(CZL?zAwrxA9SZ}O4wO4EVI~VI_|A#T>=%eddAUg!R2Xno01vv}?sYmn@RCR># zrpt3B&l9GG+&&`qB&7*c737JJp0iA;s4j*2`h{fqad!QG(aP;@at5LQnd_DrMOHRhi(|2PlAzoLcRWCKgN$>q34E$D<*;i9O z0!mmar)0dl+tRUISh~2^o7^B&^hv(urjvWp&as=Y91Qf5t zfbrM*Ql?MDwKnAB5U`LKx1()kuNsJJz#jktZExT;+pJSvo6TE9d8=2oZqDgmQF4{* z>T`eDKl;*FMJ>myN3&e5N_KZ>J>BNH_PX3@_|^iYVJK85*bZTs8u zXM4D($%XA5ahf@aaHLrx%IzTo!tWIu3lU?GN@d$%RF zwLLpzA9f=Xk3Y}MBcZyHg~Hhhg-r|o>AJrkFP`@@M>c? z^=?uyZ+n!`YVky+MB+!9j;ESULy06F=!Ytye6y|J!EOsdf{B4Gvmu(xIY;Og-(c!d zccrpzF(?k>4KkDnqh09@elL zCcGT|E4XDo#)*lk}_ioJoz^~YS4H2BnQC8uHZ69<6 zE2E2u{LkXI^6i$=csGzWa$M5CK}LUEl0Y93jLt3t7tlU|Hd||-5>du44)71DeDaaP zs(uMVBv$iN10ShDw|Gd!3O`aBh{VqJ!zon1Vu47YlnJBg;-e_Ed6A>Z9%pgO5s$Mn zy#e=`X@(AJVC#j1V8`X8GPh;xJF><#cn70+SCdn4$Gh#w>6NFI=4+24GDIvCwqG%U z$t#P)!AY{91}KpDOLya({t*POWcj$CRy^IWJ6YF%@s`zIvPEG2fE zkh#|}T+zF!6McsE*wO{sFcI09jo|E#1CgJ4gzHm<*99_d^;c@?B zfR6+{y$gH;BR%ONQfdu)9GS#UEl}O&!KO$zd|lGUc2ZWKuKlzFr?6hk*LD~&7E%TB z@erg`f`pp|vYH;}{^TiD2Uq&lU_-;QGvr;j;X9yL2F$y=auN$ZUi0jegS&J*gr7QA z8y2g3{04=;*(qTY*0%KBo!SrF=a~X?Sro6uCJx2|ACm+)X{%mAh!*A( zCpIzGfa49`KPsz8_Gj*>v_=jKFCN}wmZA)(apB)7L7-IFfKk%rq; z^5^a{xJM#={kQB;$&Rv{gorlU&+^Ibw^Xc7+I-x*?<O<+Xt`?M0uRu8`*912}{SOxFpLLK$DX}cWCns570DrVwQVi z(Z)4TVS1XCkcYCbreg29jHGBhIA}$CD~U1T*`%5BPO{xoAOpR3RO&X?$k&6hmclu_ z6S|5-+5oMR>6%x?wf^-SL`B8>)IIp7jamkyLPx2bn}2c<2(prg$?ZMrPYL+RW6GwX#>T~c7a%60RvKQrPF+`3h%BI%CB5x_KK6fWQ6*{G6 zo}y&sO0F~osG$>;J1`ElM2lU&bf#LcV0P0RBK9?FOvZCmE!Xs}cQi_*>$L=XC0^+$ zR5ROlIem5C$wgFT=RcU?<5x5eA=~l(794cc?xk`FIU@aNa6He}FH>F^mmmi=#CSj; zbe-Y!awmiL$eP40hlH@pLGdCuFCUSw7Xb7w$da_x3Ob8z9EOY-o3hr|%}0l>d|R~4 z*Y&vw@!S)w?9EUx4M!=JI_E#gY(cd$8sttQ*3F|@A6LZiG9gga%XA_FhZ^Hpoa2I# zgo{j{XYnv)euL%}rN#s|&#BTX)u@umn;Yi|zl^!2m4cX0(K@)Rz*dG65$!Cpa3{rSE%zQVn+ zY|$j-zedfJEQ}MYujOyt!C~c0ExVY=)`aLIrn1?E6pV|;a5%RoCLZg`&SaF++BpG~3H= zS;Vi>Th7rC+!q(tBHxZ?P{axL*$7H_i!czrxgn2ReS;xUj?Qvgjj$t0$5l;qG^qym zKw)=*FQI3>1bR<7>qbN1QOM)8xPp`wceCXT@mxLfh-rcFMt*}ltS^F2l?~-m(v9qG z@GaSq&ryC-4R9}cKG;!X3)@hikSHYz9pCXX^{WW2bpdt#j&%Op$jeWk;Bor!syE6A zGK{tiOGkXa-RmGR_{oMpL{EjaW5tf@?4<3#<1Y9c{m%|`<*^+xWng|BO|37ZP4sCO zo2Ehqwzp#yz$~V&N{D1u3B+ZKPCh_Q^l!o;$#UlW^fAY9qe1F;KZ3?v9k0J0{$Dlx z{v9=e%eH2k3jy5d-+Z#T(WSdihMPF1w>7P=>{@7cX{>)8lUfEglIWA6>f7|hXAqHd z!(v(;+ORxS>#z)dG?_xOQ^ag>5bR^}3^K;Mi9Q3U64p;2Zu%xo3Th+SmNk}VZ&b@) zA6h(3_Ov^);qQHMdQ&qCWSoGY%s}}(-448_W*V~W>LZZlh7fYcd+~~dHdE!fxm=<` zaO%noLXH==UB&5cD#rAyK(p!FEcDNJ{jCqKA8Uz&nib9D?TFyRe!=%IW)&6Z%Dj@n z>K2hleafV>BKnf@x%`>;`=i%pouERM;e=#!f2?b+xqFSQfGt#n4#oh9hQQ6adSBUe zU&lQ%Q2>+&@uCau*V-BXXSBzmJwqTPgQGZUeS5mvFT?Ob1$NX3sBFb~fw6^qly>E| zIldU8rK-ewspJNw@RB6_BRjQ)UfrmNidc{}^vOCALF@j&$;_YeAKz!}zgxv-+{XdL zm0O>s5NjH1er?9j1-A>(D}#soCsqM#9;EFUZjk=PJcGc_NfLRtHc!QI?NW&xM%n)4 zrlK|9b5e}WV75mhZ~&>*#C;pxIi}Y0@vUtvsSuz?4&|$1JhrX)W`!9uF25qB$<&0C zpaj@j=$vXT;WBLXHFQlN<|ctYEvv9mW$&EWRe9MCqo$?>OCICI;O{3q<3aj(EdQ%% zSO!*unwzDt7MXMNe)b(Ub_0G6$yY%C(<8%IIi`}ZEK8`C=CI6i=^5gy^xpOsc|~<0 zA(nv%%QJz)Q*4r4s*ug_TF)hJM?Qjg=y}Xbu=x2vw|~1Rax0CX*|;Y>_eBD?)7ih1!a}-v&y}v#Bi`(_!lNn4fw-P11d`w0q&fJuHC<}n0-JA!CBWULmK?I zjq2?-Z-=?-Xj_@;vws1sRgk<-J(ej+SiStdFfci6w~A9_QeVs~HQT#_LrRNg+g>}0 zeahp#50lyo)I)$1{-ZPV-P31YIC@Z)Ja_fS+k(RBaMx$XDf zxgCF`{b#gfLltx5%TIO`V?>*N=r@KG;-jj~_L|HN^Q9J1qf1ne5zRv>LcrCt+&A=h zb*rgBzlQ$R&)%btb=}(v0Z0&^YrAorn!~J4N1?rbLAHO{_x2Y`L+*kefk~H#<9980 z<=6pteRsvyhtf%l2IHZmo3cujVMgH% zz*MbC)WEel?ZClBn?WIr3jQ<7t9Dz%&r6#tx!A0&W#sgQ8bNq7mvqDQp8RiKO9F^k zn^&+lP8sizjn8sqx3!}OED?12ge`P{Dors(uoF+A?SX< zR(80h!*U+*Rs)0_vVqlilV1(=5=+2?e+MD#`P`OKuMEijtyPSA_4#qCmXSp_{Jr|- zS6cTvnVyB%eK;hHW`Hi`tL&cKS@?S2wdz~kt{;HJ1@y#-+u++rgltVV!nRmcC_z}s z%nR!5zB6C$3#2A0dF;>m9kE|OyGIG0AVK*uUtO<4u*wYDieaM0q@v1dRy!q1 zI23Nz%7R~aGq*hMYxo9S(r9W~b$@36X(!Eq+*j~w&%q%Dz~_05hsQcPMFyWbZ&(0D z?<*fZTJ+iaqSk{WlyvT})M?hA(fbY!fmzsjm@Cs$S0>)8n~a2ynq+BDlW7j2)L1VA z{NRaH3}wJ0F`h!m1XpvJ?=C@uwB*IXpi}^1DF{oS>iOW^2WYA4X(w#~n4S3{irsX= zgA!3}YgTbHAx~M{;>JaHMP1E3jE^7FS7&)>WeaoSx+7TUxhbu$x5qlhj(V^S9uQ{B z7U(I>cv>}q@^=t>(bA4!>R^(K{5q2}w7wb&$)BMKOcD)k>`2DYqE56Pge2HnEl{|U z%d9jvR4+UrBq&AH;Xl2HdEbw~fhWGFwUi7Y1oN>iO}t`K^<$${0~oo~h<~Svy2zJ^ z=u1i0GDYDL4mKZgv3P}?i-${`T;y|P<%UV9I;*58a_8O3i3s#7XEal?9_LJ_iswem zKmd%y%KnRfYo!0`grMnF@FBs=N|3VZU5FirbC83e3qhnoBv@{F;~!U8H54_kO;s(Z z=p3%_VzB5W={u@_Cy<*fF{?v6;(CIkRhFpJy)_)Z{BBI;w9vaiaffpT`$9sjI^cxksn&=A?4+h_y}#znD3$X%0GP z(KyBKwK5TmigkmI1&CIeq9KN1g2;N4H~);Nekz9Oa%d>7NiXki`XeOa$^L2#3t1p_ zpq0v-4|_5HwRzzL+U;`6kc6>hWz_T|&QxeU^Xyoz_k1NqL!007E1L!)SY+XlF!8dQ z@sN*`9Y};CKE*S2#6v2V%qdkg5@@I{SMBuM)jMm1>K)VBH-CgW$|3npgd!ZwB;f7# z@(nlHOJeNay1Qqf-gL}&sAo(wNZLudOR&pBDp4^yLdS%#hlCI_={8~AXyxq2_nk5C zCw+t<<&8PYN9v0zDuDDsYAB^#rA_?0%61#h${a7boN~B$i!X%fIq14r1%|80>pWak zNiPvj5co$7L=$5}tK+v~CqMZ^At@CPd5GZeJkdq$js&Zhp^kOO6laEXMR#5YTYL-A zxjfMVEUdZAmIF!IvdIm+#Hi|)5rrF4uy&$-eyk5z4$Tq_AHg0ys1Kp&Y1SDH#?I_i1N$I!)Su8X zK=KK{UseJKM57N{vs@9Y^Tcs%tm_Wrl&A0ZPrj%t%W^xX_HX>e1U?1gtseK3NL+_| zcehcj*25RnE7AFltChGIDd459Xo@Hjz2&BVaRH4 zK6iHN*0_({a@?|V(C&395=3|)^lCzB1YG+$qkpcxbf|Gky| zmtJRL<6`;Wt;GJ{^g8?hjb2xsw%=y_)pJGTS`rw2m^`i5G>$G5q#q4&TX{~@szOmg zAcb3ayYC@2g>H7G3l$Er;^=Nc;BOTdzE)!4$83#u*%m*6_+9$!`o}L&e0Ghd{~Fl;4B~$*C|vCS zZ(jc!MX~>%P*kgyOad<3ufF-9ea7~u!r0^25E3Y{!azdoD3M@M=1<9u-5GNaqOAah zv>W@3-P=uYWHHLI%C@U#Kef~Mjx*UBuAj+(yL$C`{jTTto9Oz2;ebEY2{cIHYwz{n zs~_8VP|(0UwD*K--OXwr+BKjCJoT9zSG%j1tM|L%ETv`*_MQ=MXPq^1-_zQ`RtsU~mf%)=TWRAxY8Y}o3-`^#ScJEy#Bn%j z2>!D1x%m0q%CIa!*fXzHgVIJ&NFe~>7$y+o6;tbiQ5|Ho8O{vJaEyc-9QL}Kezeo_ zr<`7H>bat4@M-E@VFp3*TsefMuFq^NdK`?Hl%d!>o)R$4J4&?pJJjW2=0!OTX!=@V z6QGMjFWge%0iJ_lRD~0pae`fAD!~ToKpdt=&TiW>7X~GL1H+ljZP`43(_6QM&H5u| z$4br7jKyI=etb4#yz^B9QOv5CZIRe`RjVi~m?;s4g4(-?Mr*+cjO@ynIpS9cV#nEh zuwX_lm>3Ro^2F)wC5GeJWU8xfD`Ab;8{#}k@-gq<^KalHc%(nQ&z@cr4DWjNCuVZ!trX6&*GmKYzGvL3)bu3)SvPQGewgRvN0zOfS;P$XjROp0hz%1dRAoMxY*hdboIB-hlh0t%_N%}$VBRZ@20Hj(Uv6X2BqK2hi!QkgCH?CrdSyZ&{l0Lai$agW09pd$ zRMa)FMbbd^+cm5ZVI!NH|7} z^I%o8o)XtGT9K1=;e7Q{exCnKeg$j`Qv0-$v-i2{gof)YFk%3%#?^s7Iu^yI3~8%U ztgn!E{TYT0z`m+UcxmWeA%GJ?;Y}xAV+gkT?=wvF&CV;nzV|-IFjDs*RarF^g^<+r z#$W zCfiwP7Y1}PT}bq3y(cQ(ktpxRucGoc+At1iH#5^|kr(*rTd7N2DN zn}}bI8wUs7=12@KSh*~C`ATkbssi#WMnlHyv!wFHv6Pi9UuOCZP0B8Mxb%U$HE(hZ z6<9~lUsC>;N1Oy}|j?t37A$>02z^JQLZ?AELIAnbR(zs@N-qX5clkoga82Xx=(i+R9h6Z0Wd$c5WyBGY~nD%m3%903Dr!zO=1q=l_9e&u#gp6>T3kklF(9^S= z%%+l(vY*L{N5Tb4}$GjlA4{wO65 z$K40o$in5>@^(uc!#Q~NtEnYjhfcOg<=!Wg`83(NUZL6_eUEK-6TIGb3lXF>AgT&(`N9?pkE2_cO}lg;PK9@@)>wwkJv)SZupS>Bf- z2;qxro5kZvBORE})9^CB`DIP3k_P>JW&~@akMm_-WNyvhr=`$b*aT zj*tz+UP#=28Rlu%xVAVODR6?-^I2$=DjaOd=ofA)rY9zRA)oAnD?8^nzZk*2)i1V}t$oW7%hK_`@ z?wfHi#=X$t+@#x;elaG&{oFqN2T}LNaH{afmW(% zwk$jSy~X8{0dEE)P~SBCJSGi@zbOP^UT9}~Z};ovfrJB=kNhls+5m%V9H2sOaGMHg zl2H|Q0D%w)reZ}9T-Lgo(I+2V7W~>L#SW9K4!K=|y+FAUbTssHe1yCKHWXx)!VY66 z;*?=co}(;{JnQs|k|>FV5*}=Gl)nfbC84&F+HHMFo@Ggv!osMWrA|RSBrVd4Wl@3l z%rIA)`)piz5W!~zffp_Z3p9bx*nx&?NGrkf9QXJ&Vl0@guAg}Tig9bvAp@(5Kp@8~ zUgGY*sALCgml%Ium&Dq_37_b97bCN+j0-KaUy>NK^4M%6fO*^u^(86721S=|&y%=p}8hgSt1rBDEHoo>KuXD?k zcmC3)SN2$joMH3wPR%f@u{6$}$H$m9Lvf95-n5R5yudZ4JzWO}S<> zo>X7rU4~S@91awj$;AgmeMCEFmaFpa?Dbc>H?W&j=n*(0jRlswKVkW#G4nFd`-E`- zu3$>nswdnOZf?ckm{l?6?v%OK%6!lH!Ye%s*mg~NN9wBw1hD&h^!oY^KIPIcSUpPF zKgszK19L*wk%R)wJs+6U>V9T123G0PGWak1=d9fo(2Zu42lBLus_+?9@cq; zq?a>NT4cyTC-vm@$u4K{{4@IwvFf37OnMu*9r#$c+zS7h;=7|>BeJELxiA(X4nfWl zYcW`4kj{TG;aa0>+b?PJbZPRJC%+y66T5IX%u*CV&5B0Q2j7zOZUM?mMP0ZN6fZ1{ zo>T$baT|e8?keM7c^r5wVVruEd)4y8lw!nyppcarMzt090XAdmP!v7e3&dZy>sKc@ zFFmI@YH^ZDpmNEL4cM`t{+H74bU%IpYMutc<04$HgZjrYyK~}1OwBlJ5Yo8xA|_cg zjU97t?d__fSv4?tI1|$7kmZV*UQIEQU}^BOmfe}pc8N)}AZQUH4GS8i64tK#wxVm< zN|)_m_#yZtS?6|fDs{br$_n{rt_GGjc!^FXBH8)46Bb%rWOJuYF_2{xlE4e7))bI52KNlhw#Rud)C=_%Nl^31dv!v`!42za zK2o?WxN-jeqIr4GQgur!3nRTUN|oZfj411+Bs;l79U|*ryF&FUvOnB0MARc8UebC0a{bZ=dFN{+$_f?Vw6{niFL;G zCz!kwLUXQx0yHdfnl^}>R_4JsmwK7=tGud_Ew`G0-^EDCZ~kyyF{&SLBX{!onnBxl z?27s@$z;V)J0%CIpfah!_vGFe@ere}y0&+Ki@63}T|?k5 zjG>+2)zUwC%n)d2kXwua60*pJ)h6DGfBD;hiBn&LH;foF;H7>7YgkLY4}mGq=FgX8y$WTCqo z4cF#Uhaw+5>#sSC=H3g;mmV=Zgr>TJv{BxCkcQj~`P-C>hU2|jz4p4<#jmgQooJ!w zvevg|rYD&{z8sa!Vi15#cCd>hmUUhTshOdf(5^w;%?T6RGFe&dDZ!_2ic=T`#4A-W zIAUC4K@LlB0~wCc>LqQxTvf#pQjx(G?l5T00@|IoDF-gaEGT7gQy>O!zQl!^#;zdl zt&gZ#!MqYUY3|j;8zWN*k1M}^@2Og*Gd7i+0VSGj;a9+OWh@Q;B;nOaZ97f^j4X?Q z$Ao8yVH(e>BuyKXaIl?Oyv}G>;5iZ9B7cm>$bS0GDwriMl?L3b3bCz}A~G}>ml3OB zu{c=WgIui;+iGM%CtxlIgT&0bxhYPz2oW;7sFol`{5jtc<46vJ^uqqEWIWKL^DFD6 z=ry4&VRFgYQ}#1rMZT1WS55>A1~ez*^RKC1rY0{{xKW(vgsL_YFyzs!X*xW+lCrK~ zhd?f@F&LSp8W4|0RqKir3=2lDEWA%}GTw$uN4)8vwIfZhE$*~b7@`O5VhykbK?;pT z(Z|Bz^xxTvA0u_}iP28?#Lmp-`+Y}Gdh!+_Lt4CYhz-%!d%qd~sp?AayYeAWuhAiysP(N}$+4HzZfZvN3oN+(JK?~%KP zv?9&IVr24MxHv}82QtuRN>~vqVvR*^#4H@#irk23tr-4kfORORlKA9tmGWbZP3Gkx z;VQA}!OPKxu-Rk7JE$mD!j_M=43@z7>U|VM^b{6GQ^CC^^W$5ZdrSL%&tNh)6=Bs; z=JwY4@k%!YM1WDpk}C!4+_P$sppvpjtbR_h*A(5jy_5%L%$ZG!4i`tGeQmjooZL2d zCZq!#;8}cMyHiVAb$W|BoeGf$BjZ?JyObdyjTZ&|nb=&7%L-TdSyvA9t3Y1Vc zfPI&sX_l9=0TrgqCD`@EVu%SUNO8eJz4nE6C33RHk>L$gZ$KfHG44XHfGiK3bvJm2dl}FS z(nrs&#R)CJQ5W60YP3EC^!+dT5`~VwI$nXu!5xTt@m;e4@E@#dj7sFBtX6v_RHBu1 zf3OY)Zng$xcf=~L4+S!`CtfvGmW<*Mgy>_x3@B&H@+WN*g9N{2X^yk7XXNO$D82X& zD{gg7AYU>!_DZmq12P;QY2J}+ozDCY>Y7cf*2Rhsgn(gUx7NWM^QiN-kxP1(vbp*D zZxGf|?sV4aO!f|r+#1a2&y9Jltms_|I)j88r7PG09vPc4xUr}@$rP8EwJF()?jr)w zAE>H0r~CcUc|3G*dXPE$n8$Abml&9l6{|M_f_}zXwGqI4<8^t-SAO;Yup0ZdntrC7 zJueL~Xg_NZM|$d|cheEDz;5d_m3U4oX(KU|4o|JeqJo8B>)6LJUcGquq^MUGhB19l z?G{v<1S}AKyJ#73anbU%ZK5|K%x7g-R{b(gzu)<4WHrb*BfIly(0n*Skvy%}D7BIS zFr*;0k*~6W0bLLQT@|9+tZ9=M?;m4kLi3l{7EDIDL9geH%-Eoe7ESwnT+=HzAQ+^d zVc<}`6lByVNCS*HH;NAp1E^=2Hx$Q%AgM#G7!C3Bi?;inFR}l|RaRZG?Q_X;8q+Bs zf0e}M;A@TN@Z>HHG=EgQu9(~4FRcAg(KJ?zYc09?Q0e5Ubgo`0Km+KmBQY@zM{3vp zDntblw0%jzecc~7UutJCTBt>cb-9I-|FI3L4}lJ|=p3IKDvg6z5P@U?m`pwzGJyI< z^bbr8Wg{i%BCUFgbyFF5CW{Z!0+KwHMx)WE@l0!)yqaAvI!vS7FB8U$8Y3#lZ$OuI z+{2-MU)9`bzu8|^jiFTG+ap)T!jyZ5=Ma_xDGR1VfhUgSaX~ZDm2uH`MY0*H9z0)c zkrv}|&XX)PKixy838cuNr69S)QY!sc2kv1_0Bnn(5>fTeFNh_3a3U|94>-jgTS`ZN zbjCf~%)Du%*%64n@gSbr+pfsC=G6YIgDAC^zW;MJ4UjjvE}#3^60;A*ywDt4Hl{8y zhg8gH-CxD-t4o>XKrf5Ov+YHJ#OWC1 z5Wh2I>&C2}hGv4oG7);`UQxpwLa42y)?7HJK8Ux}wRK&MTIX6i)_MjoG;5=mxtO1p z%dw-lW$H|iC+xx;6y)6R3&<{49~vse3{h2?;Yxl*QQ|_+%&fqF-$l^iVC^FB2&B&b zr7=@+pAv~GuZF`iBr!ilEhc^ACYYiWr|JP$Vv*KaMxs1g+(CXbv|EhwFyYFl--D03 zTOvYOLsh%F`+^LgEph>L;QFk%zFb3TpfRYlcEE)TaI*HXgqLm|sM+w<8%s%z628g> zHDiuuLp~;F+2s9GX7aezX9(_B3$5e1V_Jm9uZxzztkkD$6KLZ0aGYWL`njtc^X*+YQypYN8OLeG!_#b2xsAzWFuu0KW? z2)xv{*y;-MN5+|?89Rfv>0xYc0zbfAy!yH@8PLSS%~d-Ayi|c8eoLBd&uP@U98*~O z#Z7PIjw-N{1ZsBl?io!GPVr|(%<*ImVT&X(c=)(}_!2O@>+rXfLCH-E1!?5dnt#nU z4yTvCidY30W+h6!m~gKb9UBDVAaKY>=`68-cNn`mH}2xG5NoTxUu3-eYj27p;pOw~ zdeP$M+ut$D)eGp6Px1Usu5a)yNFUeB7sJxE5%SJa>!~E>!PPun6BjCm4cv8UG7Ym! zwBuM*Z;-{CvX&0qBm0ToCMF@HBf_nFG9o;6L` z&FF)eO4o)++JquBXNAk#^J-~VQ}AV<5}88LfA<$JSTsYa)X?L>x|^z6zH6GFs&vjF zZ(_^Wa_?Q9e}WgaxtFd9o{>YzIZ)g!Q#cK1Ts=u2r(hG^&Yg+D+qu!o55hNCVEB(H zZ(#n0;E$Kks*@J-uo-jB@yC+rYon@2T*H87PjCtOR4#6UK>jzPj}3qHf03d8Avyn} zwle?!ax3S5KOVvPe|kLPM%T(gpAG#7|AA!Bp+{(T^phDoZbZ?LJ9tr$#Xxf;m0XT` zOF0`Irr&?A(eLK?W_C?}JFtp6{rKwi`p=t_|6W6w1Llv6z@5O}=RHj~7uU8)&iujO z$$u9MFWg26!7G8ok3UohXGH!e%REN};>*#x@A2jscPD2rmv7JO?8~uVnwRdp}povbG8PC^^SXX^N#BCwd~Bd@aAE70Z8a=Lrkr`aX7}}USm7z zmMd>|K@N2~AoBeh=j;yuPo9XCk37W%yLP{uG#Hn9=C zTQ}uG?wv8vb9+^H0qrb;{YOX!>@J!kYzDO?nI2w(R!Ml^1z_jt!w5tO_`Hk^}6 zmR^vbi=BYarFTXTek?cs`8=o9EhxhAo?lm0?SabZp0`|^c1wW+C8BsVq0-cWyTt%p zO7g&MUl$;XV?k$cdIllc1ZkCwyp)t)%GvT#sdJ}#)?=nT_>capk#M@Tj^}~?gd6eF z@j|F%pEr1iQ3;sTZ0W^es9DnFe3%WVTv1q|)evc`T<|n?HDSrLFZ4PpbWDQ_qs74D z4l2;8AN^a}SZpf?&D^#CSi8Yid{}Bs>4gbxMV+}=EbkQO| zxmTS_5K>`LDOPCeonzreB##G?6R6{+_tTW92Oo(9QWKtLKvA`@`D#T~L3g$ObpeuRt+)^ZAHInEu*}mf4xTXVN?F;MjlW8AO z0EN?HEh+|`LoTwr7(#`M0mAoYkxH6Vo{%F2oT&EO*7AO^y7UBLRrNNsT7Q+>BUB zcGWGw6JmUZzVgENqSljf`i5R9q2)J|AH}60ZeoLs^x;AtwBwDgzSu-0-<@zhEGPYa zvGf(KJevoKo0*Gq%hIon;sk_jN(MZ6S~{*Th-(0LixXn-prC#z7+Nd4J$wo$!Wnc2 zIzQy5;sJ{1d7I$z3XLGP7(PyUd);G^J23S0;RD7S-U%K$yDv@@8J?-0Q9P+D$q-&m zGp?hhU~Z>;IE6d1@D$rk(wfuGQjoL%VYtTGH?14&Dx`{^xrA%c98_hlNH%!$mDZW8 z+cj%^_{`JlACW^{_6qY0|HLk~*}iUGYmZFN)U$)&8KF{oZ6LBUB3h*N*J|9BXlFJ{ zGSk|Wo>+uFgU|BoHA*-C4S_&AEut%{A*%sbp^YC#atAo^&YC2LZbRn$;f2Lb(y(%_~V(zFt}&z!B10YlCvK1J^N#q`IUJWow~VL9?TDxKl%P8r|v zpd{{Kp8DSE=2C!;$iDT*Mr;&Ydoz$-VY7O^YzVlMz;Wr`5=- z85#%1+W&4bWGVdB%Z!&5>OGzM*Ba6Fx;G)bI)#M@E~5aeWK32solU`;2~QDyR+_nD z``0J`6QXx+w6`CD&pGz;vWJ?j5wK`^5>e`+8I9EGLX}tE32@-y>j%Z4a%0E4OCha- zKL||TvT>cjt!RL7+)rdM9#qFNtIJp%lr9uViB>byj-u*R2v#T7-Cr$_ls!%yI6oO^ z6}l3tHXY(B*b%Yjrl;bFxQf&-hlGfgX1~UGcE6FLWeA6*%wH_FdxWU`KL=YewRG$(ajDYntDW}_~~Vv zH6cYEp2Rb)dZt?u`Li{zJT0HsRbG$Qh`jm()yhtX<_5zFPt66Qu}FQ39Iv^D3J-$q zOPgz~3wZvJR4iBm_ap7>K3yZ7x~-{13yDv8jyO_%yb zKSN6byA~jZy``!%MddCUpNNLeV~BNnZs;J78bphJsb(WqHUndn45yu$>Hf+(l-kA_ zdGR6%h*x_6-E-RPnRaN`3Kfrv99t5@Y!fCj0feeo?;O& zP5MpEB^6EmHqBMCNhcPw`y zHy$%^*X^ossKuP4Vo-j!cthzla-^9jhIWx;D+aaDr&uCJ#YATCCo(-)v`=AsKDe}l zBi1~@V+-*PV|c`-k$_AHGqtYHkY5lJcVa-?3w{`G3x3wnf%sK-(0(97{y5h#x5qEV zy?D>igk!C6!BKdT9UrITK1IE#8@E@NI##}DbjWXSw7BW>c*$2en_@U6|CYD%2^JKf zmxmfm`WF9a6#iIfWJ!Ihszs%Cr^?c*%@_pHSh|Hf#@F4HZjVwcKk2tQlC|%+s!i_{3?y!XnZRSlOy?Z`%bul+HDp z+xeRDC8TMbMES+ifXcEj^OCt;@>>xxLL(9GJ$qJ<(qQ~^VEaEmlfyus(swN@f8}fs z8Gs|_=I)`XK>|6BzVzj&kgs@e@nH?rPU?A0Pgk2ZWwZ|qKs zS=@n*94T9g#j#63+4r>H_!_Mm?2P?p7R8|z>0K~Fe$HJEQz>$Nn$g$r&(6W}ZX zFxKSO&GCQCb2(Oh(ig;`7l;gLilolwYC-j33zJd?fXUO$og-PImC^0h&LgF;TIy+# z;|ot%JM{y_inu;}@9sl3(c}T@gJk6sfK~-5OYWa_!|@H z+S2_>*2T9*0wjkBYkl;KL3HBCQ8Jo52zk0f~bC^4;tKIjP zw8UI6aY_D7IMD~bRwHtH?-=p>CFz*-oF8=r)+1>ljt#MPQAr+8MeGIo*4*4`G}9^}H33-d}3903&Hv>@I- zV;_{&J`oj~MQ=2YPiqC;qP2(2)Y}Gn-tHiL<<4D>dR-nZj!&G*emhvz-~IXTlKo2+ z`uS3G^`y$3!mUMhtJ_L?-U*=+VJaYtzX|W%KuQfgs}V|1UVT<~(1gCMCAXP{yj_E9 zV3m9q@}f;q?<7GM5w9cyIGo_y0`mRdn@-MWB~pQ5xqMA6Tur^eGj15^vis`<{lVP(-T7(hcmQ=eF}bgO3P6T_LTp12aL6MC z7(8~j?T#r#+FY9&8cSv^OB@Lm%(h9IH$vq|_If=@_>ZWX!!TFd2{FRw#oKHo`q^Y0 zp%H1lqxh>F#z`VwI>lb$r+Z$7iGb|b!z1PmngprF`Lazt2HNV;qXP5+i^2C!ecz&W z2-BChPX!x$^0po*7Xo!`hR~>LKe}w{Y|A9SQ7O6Fo zTd%6>?_Eta#t|F=e-zM4!os+BB%e`imPl`0RkXU0I+yX;xDra`mnnqhv720d&yQar zO$&a>EZ2dWbmAWWell0f*xb-w*EIzOZ4tfUf*F|^r!Kb_r*5qmxCwsjL%gU7Y&nIa zSDOUS(D3s-Yg@JoX=|`+`8ilvI>Fj(dt#(5tFq{?#+UQwZt`jGUltPMZsybG*J5jQ z6$s4p2d$*LGt)!={R=#%AyD9SYJ#rA-=uRzCcG(0jhSpw1YEFkS$jPUsguDoel&%2 zP1gb2b}r0+C}(_CBQBUcJ)KjGE5Vs8qNWQ&TN-CbfzTihIy+X*gOxcxoJr=cP{vnz ztU^ZMeEQMpL{8mEk7j2Q%?D;@DJ_{=TMlVJdL|Kq5RNejL+Oj&g=ahDgOjc{-o^S;HJTx^8%JUD&jMMgT!K z*S2q#6l9KtMIRsvg3L&%MW(}S;bd3`^sde%8T#^t(E75pU8Z0&VRa=BG1@Khu3^>R z(Z`l;vmbvpF2~~rNdgQ!47UjKJ1)aeAwOB#zIMraR=AynjbNsq zZ7T(B@nX1f=jiGd9yULO9}xZ1l!Hm{fbg|fv9Z_G2RbCJl15G&7J`o z$+tf$&5L31#i_YRKsYkijZ_Pxd1bQ-5d5I!5=>swXl2&kD+shaqyiZu-uPQv7IT~= z5W?Dm<%QLUEn5gV8utk@K6+!2NqkoCa(0|@M7vmxoZMZ#j^=*x zE#U5>>@QDHnpHHjD@HcEWTnSeGs>Oj6RK$GoDX$hu3f&%h2yqf;~jITd{yP7RcsQH zxI+HTB8d}NCzf9s?KW-Gw2@Jru=Owc7)3ok*A$vwvN=^5i5ayy~HindOb~m zcCnCICWZchMO#BqgtELrL}H_NKJhMz&f_fDH!*Ua`Np~#*qHxtAwCrO3{nS=3-#({ zxD6^b&|;Qh5C*Ci3)Gja#BH7!CP9?UHHj0e`PkQ^SEuu>yVv8LVudRI&dC94HG+F6 zZ}bXpR(*&M1U06qyViis2vUVDT%8mQu+szN9hijFg>l`P?rClaf7s&XF25}8t_OmhVxp zC5zBUIgtrh$d@d5xr<3FPgKc_S}`@-J>CnL7XToCq?cb7Cb@+4>Oo6P{ca?v`}l5e z4)rM4?7nK*4_a};)-!w)^01+gTr89SjlrmKY0kf|5l8S?DR%p64P^OpdXk-T1FqW) z=pd)T34HT%3ZNUMnG(qUG|ObF(dC#;x56nyZ~?~zC+f2bK=S^6WSC%Eho+$6E=NbJ zy{#y>u%wXamJJF3x(5Rj#V(U&p0&Xzusc3C`QFMMLEf`amURVUQDvjasX5cYQUr*+ zby3OF7=4So05*6@lg>ezoLCk47up|zK60#46BMDO{rV`lqmQ@2)K$qR5H}TR76aT| zR7CP6upGehCi}?JBVE=ALkx6@@hAV`mRyBLcF>tRn7Ar`6seAp#~Suf1p)-U5=qfI zac@h&p6iqC+r8%Ce+_b%i>nyUfAnGb+Y=G*BrM|CeyN z7byDifYsSQ0oG}2-Q!M;BThfm>o?KYd$3@Rm;0x3f}^=WA}X^E%3~J{Z-pB#Uoyp{ zoxA#NJJeN(v|}{VJf8qci94vb@u<<=*uiN^OV3~Yl^Y|eh7N9@xv}k%i%F}?bfR`TXtvMA0h7d{38J)dJ2 zZp$+PF9ub8p@SO&PJ3*;hr@BCZ>r=omOJ#f(2;w89a<|72V^2-d^&og5Hal-N0u4D z9^$d_6_@ys{$$Sf@y-WAPRx>C@hU&6F% zV~-v`W`F1mua{lFEO?>7~%EfmS|6KzNY{kKX%0ew04eGZR{3PtO6~a2?<}cr0E-s`VpZb`ooF*U6g(A=&h zbU98iwV*Zir}{z{#Wj^q=KY!?8|tCohiG~5f)w+ zD!p7kS2kbe7*md?fBUR;BJN2Gb3flKBY?Z`e6RLdS+O2V7P09du2zB@40;P~`0QK< z9=gv|d~n@35v7?_rJPe&?cO0RY$vN~L$&Z)6WbrF!S#mtBgRdG4i$PxVU7^$+NmI7 z%YvdP9=_YVavwHI-EPr`vfcSvAc9q5l5JTRRz)>oc_D`bpN#SCKGq%YFc@k zXz#-9P0F)yN3gl+xgr!{+Oqet&Gg>mh?=6%H|ATEWfiF4@^M>hwbmC*br{*a0PVh@ zg_@(cQzPJO=Y6=25QFmv$x=94TDH04frS1Ua>NYVE);UM(eD-vp5~kLx{(L559>*quxCOucpY~LJhfgy}xcBa4?89f!FGiX4b~Zc4F}k}t z{yD0`i3txo;LsEQLPJgS7Lt4h*%!6KrUgO)%gIzGIlgHzE5teC&qi)?XU5}L zUAtwSlO!<|r8u}1IcUADl?w<5MUr zxZDJ)-81KQxkvGIxn{FVk?YVqpt7*6u*$4EOYSAEK@&Ed?{g^t=DEtJ>6YdfyXQpQ zDCaKyfL7)Ea1VfssC#Rh6tb0mp_^V{_pd0dra3#pmLx*WbMm=<9dQ31yyv^$micfS zv|4*o38D(*WvEYZ2_jYw_fj|P>fIx;%Zi7!hog)a75&!Rqw(4x4q&;T1u@p)ffCs& zY3?^Sssg{-$FT88LfE4Ihv~G^IwkVJe2Yc-069fj&YCXP%leL(6s&)MZFlE5tI+Z{ zu0RA8>{B|SI9_QZ+kiAWNlwi-qEQ+r-hZLv|DfLgpkq!>&i`9y%>CcQH~0UN_|{F( zYeM$fxg|ZOXGQxx`xP%!G!AScMP3G!fe9r(>Ctsz(#1hH%+VvT6+f+f!O>vg$;_dO z1|YsToj?D6ztBJwtXv(`g!_^9&F15IzlH7K>EJP`=(xREn?sc3gVQP!R3NDO_JI2z z@_USRMsox)<{$Zev^LJe&E3W0 zm96%k-mSDUVXyZEg6d=@Kae!qsPK+6oi9SoB1X(WQ{3b2?~yhqLJgrh_Py?PLO0fB zw6GWe0>d*@LMNSnjr$k9QZrsSb?Ke|g?C)@&rEr?Q9G%g6pu~Wi!OK!ouQ;`1^eox z-{Hle>x?`eR;IZGY529=n98O^u;q3?I+Gz`9< z?ln@9;?}mG$J;z7i{|1wZ8;v7FrIuVklsifzaP7sJE;}?r8yH5q-@UO1n6_1pw*1c z9eJ02FFM&joygNpmdu_~!Q#}$IL=I!8`jRYLhgO|!v}Bu=+h>P)RSvXCKO)i)*z(V zukU`N*4{kp)y?L~Nj2-lZfNJwa7h}&plm+De@Q53HE}d(YUti3~gRp$ye z8mNkiBf$_ZVi}pSCsXnV0(2*zu4ow*GGPaXnY;K4I7WxdBi%D+cFE(x+zh1b28{Ze zg4`WkMSG|QSY_&|hdT~sIU>9x>CVC8mNGZNbT?#a{-3v;6J8_fBscR5MPJ#bA-Dn| z841V^APtqi#HpC*w+62GYh3#I7a)FHnhk1`v7>dgLvU(pVw3M8`_bz}x+o_#u9~Y1 z0-V;SoB0|Fc5iihAV~=w9!*LMREw0h)n{GE8EN52qE%W))352Gln4^b|4d`JF9(Ay z4tFs2t;f*dr`J(V?^h}i8a5p}l@SY(S&}CkJOX9WQ^W0Z|4`Q!!JOQ9`!7#1#K|p| z46#d;i6{g~_X+tu8mbd+MM$&!)8dv-Dn0rz&0pthCY%eyr(AsQvk^K4C143L>sibt zw>r_R8TAs22C%i4yG=X>7d~!H4cWf=us3^h`{iV3 zraCbixJoiQH)hKA^fvWJY_+EhS~gIyLOKlBZ12XbE_`fzz=3&MA_9QfpAOBA{}GtN zGh@Qw+R<`U*vP=j>+17&8%Xpf{i z?qwjJ4~4agG~Zt&w1ngq4&5+ngq=9h63>v%y{b8M_hu^>-@D{!>g!cTocvAcqw=UJ zdG1W{n3%8s7!RrKm6bV9LWt7WziV%1#SIDE@9g|j3)|KWKg?pFqI~| zN`hj)8y;Kmgia(flzY?fM9`EIUaW-_>YYkbTYTinUEpp-7r8Q;ZW8u4F>y6DuqaQH zZlmVaMwp)&&1i9wSydwb%fQTQDB)a%ce-Cl>!djKKoCGL$?NI=J)?l2@r5uLg=;3f zAyPvfZpAGwDEwO(h0UcNtJq8g5rs`(b@DOh7$c7!Lnd$y57-Xs@o8bRGa-Y7)5R`* z^OJ*9aC&OS>A}vECQ;o4m7oV@&-h%3&FCJ*yyh>)C3LR7m{?KGk`jA+sdAyZFV zR~E-Zp7?A3h1H~dk!*s`Q*Ss~p%NMoShKJ=eL28eFA=X@J}{nF_^M1qmH@;yjOxeH z`SW|FueC5<2Tf7kxvC;D30x4{Jt98Wi!6irj|k3Tw$-6mn#o;y9UYdY#Hn#D5Pg9O zcAMI|Aq!Y$a0*+25!CPE=yf}*RHVK_?eEoI0jCc=?!F1%)`J(GsmftnhzOl@AyhOnQqA&$g&q{tECKm2~#b z0lQ|G9C7EwPDJ6)z6u6qEEv4?uSzP337K%4gae^l*m11zt^N(0&W(N%3A^Zy_l^^R zHKJbYi9Ki{D%?WJ3YWs0{7lV;n&j1_){Ji<+TkDTQe+(w3J>W_&NI!R!<7ynK87}i zj}C(|LFTjk=es{$PcsIF%y_35y+j_VIhLe@cqg>77XNm7|DnWHiVox0l-#*M&7mllMwvL;C_4Hu5e?2 z6o_g6Bq?%2%Lzja7Kah5s3nA%C69>YUEdmq?(=VRq5EV|Bx_qV51ay6hwN9uZluSU zf}Mq*5-e%4^$(Xzy5qUkvE>ik;uMKnU@BH~U(`LEkUAy&N`X`@dB?mbQ0Dualw&2F z?2M#F^NeJjh&=XEQS)SsP~BcLjQbc-A)YY{xCu!`7oy@i(LF{`qdVY}nNwPO02;po z+)GH~Rb}R%yuc}ePcqB7<-yC!71Yp(Mki14E`g<3m6o%!2DluVmjTkX3Ktt#+)5bgD{TUT9`rBXTL+N)CX>19UXSKRdCXon} z?Pe2zG(_-T`6NDnI3ki<${nq|Qxkc9-u^C0WVc-SRE=sOhP%DLS_#fR`i1%_57rm% zY8>Z3f}1z9S9DWcWE>$Dt^P?BnlfUs>U;Xk%N^ZD5U#*-G9}-7Y_UR-$BjsF{j&VLz7_uGW+?@R1Xle2zjOdjYt6BA$yf5%(}~}y%hI`Q<-{Wc=EV#? zXU%eG7AQ(r*U-Cc#F0|v5AVHhsL9vGD}Bh&dp~YvHQCVn@0qE{r@H*aI?=jsUhT>p zbaRH~p0@r%lP?iNSM&=;1sqinX)FAXsmuUqhD-H{i0u95&Jm%xsMXNU!hvI_--G1Z!GT8vxm*w zR_npiH|A6l^XJ5sATrLw;O?(MSj$KYSMjK?6ccMdb!#dps8MzSe5`fel`FB>Y;@Vc z568s&0*pm^tA8bZ9-K2Q`jtdi`XT@*R8o`?z^gGGE0;Y|BXcGD|qKz47 z3UQcYWl^A zvVEzQ(*-(x4slH6;N;^?%PyF3y9@U!%d+q4AT-W+NEEJYB_igzCHAD)$>tWD__Zm@gj@HP?SYINhA~ssbOioA^Nb^YU{Jr| z$J+vfCD&Rxcm^r0dtOpZ^#Zwno_)A5(m7v`v>s&r4vAO6X1)I%hwIvpF^=?i?4L;f zKvH8^uKqXb{2w&=AJoag^#AhJn3?{Ylx1f6-?6f~+Oc^5SlOIc$wyrec=(|Yr~sgt zqEVK3qGSq2M>vbFj&=0<(8>Xo&kNPg^dYE{b=`*~v0+Xy2E~iUJuO4h={a)A{uBuX?#dDE0yd!OCuZsc9$|yybSD zkSAs~Vgs|C-(|*5D)n~M_;pNrpZg!VipubYVi!{MF22EN`UDQLK?M{#K{~WH*^r#` z&o=>+!HziXU>BCg@0tdoE)m-PJ#w(cA{*cGT4V>4$Kp8CfO@`9q7TCH&rh0b!M$SB zD6XP@0mk6@K}HJf-q^7!7aoMP!4z>X)j`rtx3X4>b%)Bm%CJyzHE}cXL-9}MuwiKp zMCPy?2xf*dSAAn{Wfd3MW20X+4f28X7IeN`TWUj&q0z$%soFuCAT3vvg2GT3RYN^SBu}#(jXmriRMd6n2y#>i+$A z)0$viiw7`v)^b7dEL9^}3l|-vN2%|O*;|9mBo&rlbtt_tMA2HXccWCjHFDsoC}XFp zJ%l2C>E2Kd3Z+gt#!y7?73LT8+#M{gfei!Zr~tX6-MM%UR^rF;vJf!^I)UU#b~hc_)$?)n6 za*zCHa0_2M{UT92;P-3)bYda|&}W625`1>7LDByt(u9jgF$Gzlxkr%a%Jh`(pQr}yMz1W@u zilr@Jx*!;PbexnpzYazVpb=(QsB;|H39{g`l%wqTIDE8LK+o%!0NBMBretdUj@wmJ zbO2L$nI}f?rj;P1l#BkvCWK=QMRY7BK$Ov;RW@?uoZRo6{4NYj5$Ch5ezdug2?jMl zZq_LSL97VyLD{;vpG(camfG`oJ>R^X0?Q9f+kYEbg{ib1fW+Q~D!oVqr^3MTinEF( z5*>KbM=Aw<74wHs$Yh-ZSA~0{9fj|Pm_Y4swdsxyb8O8+(yr#TIAC1FOA339{QwL*0(YdJeJr(;VcoMcEN-6oqR zwkx|gWw98>$oVIVL?t|)a1#bA>N1n646ji#vCvo{<^q}gYrv3)r|QI>eePoWG~ezt zAnhcnXW~(r{DV<>r2F*BCEe<}nrz|!ggvQLBYaj2%7pB$eKA()~H)%zP&2NQZ?-1_Uu@mWyO7eXPl`G?vd zg%zihzVV!gwo1M6#$tNzYqGTxNKK{M{MsTtPb;3+s|kvQ5GDPV4~!1%`~BbFmnNTv zgqDPHKUUmJX>df`OKmVzTnw}(eLR~ZDL9nYf=#QF>em&?gLd35dLW1c6EjZ+cn8dR zAhVjUlr?hpt`w}j?67~`*IR%)X6f(FGe@&Ov*F)FxRO(kg{)EW`ZAh`u@>YY4IBd~ z+(8;qI9DrE8e+`A5kc)&VFCXF8j9dZS>qdjTVO>|puZ!+Mp^~`jiWErRkgC!*zw{v z{9SWKcq%W_Hg@-g7EFUM_MXmNWD5DJeOb6l545h`4TmqB!K_2 zLQ~PhpkX-8zqDUxP$a9pEB%-o#=vSG5p7?VLt0z^f{Kz%1NA zfNW`!he&pIxKN{(#XplUtJ{HlLT(%xQip}{u)W%GtncwjBbWL7F8SMPGFkE+%`Oky zqi=YaAm*tDkLqY+knWE${sIa1l6Ju9uqGB%*j>vnLL3G4rg9Ypub%l{L1kcR; zZPd|`imiG5>rQZ%s>1RS!f&Y{CKD|ac%Xtrcb2xX-}pSUR)qUisDsV+W-s$&An}PJ zHxDCCMukrpQ|?lia$8=m{a;xRr|sxlI=MGWw%{~zw;1p#Iv$bzN@f;%q&&=XjSNlQ zhuY@4OICs`jQJ(fi$!56;nL9q>M{#oi0`+@$LZV--E&`l_903&=X*Bk;TX|s)^byn zSLS>?(nDiN0lt!ZT%xs7(9^oC;?n*ga22m6jaCT=;ceXLx{Eqhz}=tyd;=ptWeY{n zv@#C%oSWW1j&cBDKJ4FXT734;UH_KXHnPL`oq=CgmNs=^Jw2$_Min~+Ha>&-4go;j z&fmZj7Lm&~+5;XBZ^qjvi9tF|#DUL4bzTu>QxSb0qr*$na3b)~%&s35i=`*_*-jB5 z7xe_MR!a2v;7aOa152C24(S&#CqNFvijwhfKO#suF^}CEz9Tx`%3``=+JhODOD)}3 z3sq{}F;&k)?>G9DJ>Xs5yC&Y;tOG7X?<)c29Vj4#3NHMfvKW_l`fX)|mCNT(G=OMwNxl|qJ);F)d?;48O6Ley zpAxF(c1VUgvv9unp_+tFS*zxHFxZN4yu(nzrvt1Xe@|SqzYCNFEM5J2d|`hF&8@1K z3ze9GD3TE5yfi34!~r5(D$y+vblBgjoZETOh-?v9!1?-hkMYF*o~Z&s39eR#3CWA@j_F;%ayr(>Xyw!t>1VLw5%PFP^X#VL@kRap$m*Fv{mi2B z-KOGE9N88bfc)>|2hCS(o{XV(cg_5a`g`}awPBH90`X`9GFsSL2{mh1-7vkULC_~42pV;0wDSQl$N&j+x6MS{Y`1MKgig!X}uwK&HZL_ z^CotPBo_QT<;Tn2{qc;|_w)Q*3h#&D+t=ms>u(|O$Xjem%194)u&|2A42pQ-NXZUC zQO%Jf+K9j@`Rc*KL;<5)k2lHxq$m2k;AH58VYxBpQp>5Wk8gF%dq>Mt2fKAVP*VQK z#qKtgl2QjZmEs!jmx3vn$9@*iHb%`G-9w8J03eJ+bLd`;m>x=B7i?i zH}2S;{FyKL_`mekI!=mST&%jOK&vG{@Aqgfd9)SXNa~1Pcn*6=2fLV6mNX}k!r2)u zgPe&IPWy&)%b;j3m=xSufkt4Y_{< z66vVz82tVhu~Vr!8X`dXK5&Hm&|0_HY z*XX^+<+X5^$!YB{VL&~Asfg6n-?zvv*24G}(JQY978Qj26MrqjW6~K^Dm1wibSVqA zItEjRy2~^FKG{EPc00B_@k&D|l*__oXhX&1GQj?2f2P1E>^_ZJ2|jAO@`6YOVge@w zW-s&5$yO6O6}h*nxG@&s_FbKjm3R!`?d3&%g=3WYO+B?z^cJi8dyt~&pVyvo@K_BN zy`Z=iHAW6**)17sIM^S3*6@l&dOb7ek?^z3x*Qh-TtCOxC#6j;rr5 z2VK9hJHiUQYX)9n8(#6;kr-z+WY#ibIpweh><@5r_vDF+{Uwip5)K8n@9;s?cyVF> zGWciZRZ<))LGhj8VVFp_BdlRa*@ZbS;_sk%Vgw4@+blGeKQ889L;a1mK8)YA+mi0**Jjw zk7o_5PeaySz6n{b8E{Q<*vjBR;`UeDCV)HXg-G>v>Wm2J_N9#*|Ileglv*jJWEd1P zIyjgtX?}DFd?k#+9JZ>x)nF=h+F!{NK1{dWnrTPfq)J4W6t}|GEEm3rdi~C_r-VMV z5`G1PQeJAye*jB zjIq=e+XziU^WrXTg`WED7A4s{rq6Db*gCpkct9rfVy2&S>JFdXoQws4Gep0IyehN8 z)&yDc25Q>ku6SCPR$KO$y}(OPBuY?-ShbQgs*5snoIvV!U%Ydh6 zgJ&m-r$!RiTbE}iR=~H-HHIGZRZ>a$;qKo=9xPJ;-lcRJV!OF>>$%+@+!t-ri{Nl& zaU=VnZUT(M`Z3BHW~>;tA1sA4B{1Jz5EV8%4fb&V>b4F1eD-lQmFKN86?gbSvt zR~f77GqFTE41g@Ar#=a%eg^UvcKCp=0fZR+EwdsI_A_U$OKgSX|kl)q3GohQ~8W?at? zLe;TKaH~>=B>Df9*K^zt&7YB`D6e)_5t$N{lFZuA%m04TWNc5 zN4c4mW}JRQ4#wpXBlZ_~%9orULDZszuc0Jfm(G@p%je*QE!xEBT+2ryGkS2p#M)eK zxXs=w#V^tkhL?2)z!1FzzUW1kjQvKCIE<)JlmY4D7&=~13|az|XX83CPqtPGQeT)X zup|%>IprGP}<~*oW=nZ>sdLqBT*TCFaP0yzHw;3!Mq2w){0=TwbZ*b5nu4r2` zbQiM;&NyiFq|d|Q@(d=W&N_JzS_b)9+dgS$e($0kb2sTWG4<}O61ea^vTrd^@-;eN zj_AX0wmwCZTXTb^4x=^{j3Cv0)nzgV&p#d8pznjG1W?<^gogFL)sA^EZoG6T6`WH1#^X>OUzcmV_854yA(2{JW7RwnIu5AwAAq5{@c(UE@hYwuH#Bo1v z$t>ky9jzEm>fjf;r)M?TW4-t{5oD?MQXG(hhM?TAj*h$=4LM{-Kh zgA750gpb$W9yxnt)y%s+&rFA!i0M zZOj0YVENN^#FSjhVeV1e8O7m{*|?!4>bT2NFkoP21EHVpSqnQI>(v%B^OB33V>kB$qRx5bi}Gj|0?jJg zX*4S{GuOvlY@Y1)!cTy?NplfQP6eSOE?r`E`B;urPo1Rys7)GzOoi3>xF}7H&2rP7 zBR>IuAWHbN-vg||MYide!y)a_;*bBF${ym1Rr_giyHs6#YyVjD=GvXKHODX1-cC;` z``KIF!kJUyk16-U_C4vF2mi9POI+w6qc>g&YI3H$-c@+g9fh`=^x3qZdGx#+eNFL=XWURDAqSktboYt63bu`urloAWd z#%_-)K^;u@(VFTV4Z{w7u5a&FQR8N7x#uihYd) zRUMe12U3e{(=vfR8WXULj`4a&Dsf4A>HN6IfT-Cn15JZZqo5Wi#xMBl5CK%%X38uL zDM=b~2HWy;#s*II7|}#%bZSwP`1*Bp_Pm?rM|f1q_@~N#3=Y57H0O)wK&uMjLRD%{ z)M{PH));$mVGe^4;vx!QbD%ifC&&9iF>)lh-oX(m!GJCm^!$d4iW$Y1lF!#dmzNHe z^UxmpNdll$xQ;du1q>5tFm`@N;*eB2lDmwwufS>s@sKYmZBCTg+(YaygdS9a zV#x3u6aG=+_-Gd!#3V=fOAVXin}tS4$YmAwJ)2Nemj-hXQI+G*BY*+=sush2h&!KL zMU|A)z;m>E5^lgAydfeqp{m_^gbIDUOJjIgCH~o=76ZUL!&g=ZG*{+0E46AuP!=Zz zrKx@N?%K-3a)Fz2KEb~_*)h7sm63kjA2>CPlhmgYFWK$uSm$WNJv;WA%o z>?O~gaT}$8EIG0w9=NU3xO+^LT~nm~6Da!oMrOHLh6)a$nqnrKHy-WKu)5{+;5uhE z7ubrAzCYfJPg9pf)D3#rxh96ZsHAA~=+gYS zqAErZ=if0sjFPL_$VkO5iDNLaQRZo{@7i=4Es?o@n{g5FT%^;(IXT{Yxw&7mGUbi-`6xOn(=1) z)g)a@dJ)hj%AO2cv`rw~91f$~o1aq0`EO<*5ct}uOUuRp!9SY>ZpB@28n$M+$QBz3 z7;Yn;(Ci4(OOh1 zY%UU5=LB~~KgT(2oLiXRj9^d%VpuJb2NEz382T8otO?}Tf)cO?_@?nrjVP*4V)a?)bFp8DVfy1?aEMHWTB_5;ak>$~q}Vtl{vxKRD_wW{G!}Vk zbuL|WwqJPsO>fb8g~4A>sN&WNnrF4if37VO$%p5k1|ahOq^f}DOY%<9itg$HZ;1> zDKwY+GP7jC6Yk0noCq>oNj5HDm(;=-AMpns;`UTR{Sf8x>RBiLJd|i>ih%$`g8l_( zhY}rI9TY%>nSuMaH#A=(hRz*yUn4_Cph%~3%?mQycpsizCyD$r4RUN5d}M^&w1P{a zIa<}4CQ8>cMDj00F6Rb>(eQD$$&>cE1#EHJaceXr&DBOBWu}zcUKK%zCJ`-fZncL6 zotc1pn!%^~!AZCGXs}-8!iOjW(|&mp*Q2o#YK{u#cwGO`bDVvQ!7Ep6iEicyksgwG z?}!gJg;o>z=dT~n8gLhqLk%J`!AMMggTfRx^sXIlqCyM@9YHL(Tr8NhqdCPzAjRKJ;W4QEx6u-3jhCO z?3{u#3EOrX+qN;WZ9AFR$s0Qp+sVYXZQHhO+n$&^-*(mh4|Y|b_0iMS-PL{F*R$4j z+b>-H>2?t?#U*F;bp`JYh|2s|o0f6Onu5b!Y7mDE`fxFQA;ZCND6{)?uEFpxfqgSi zo$aX*DQdmqDTC5m;Jf6cFT}T<{m9JfmKDq_}M4l*lH|%qW6ZzT1J~N=}U_yd_+p5zSN4nK3n%qJ878fm}!1VqzQG8WjZdj>pU@Sza@bJ%p{v zsz(Q5pvj=p)|X&cwD>@Q3^sK=0hmu>o`m=M+R6Ql+#~> zY>;(IQ0h{-iH{8!L@BPzCvwgGgv@PHFOvK7T=sg zOm5YGj-u*ixHA0;ZK%gpgp+0#cDigvpuPNdIB$w^ncVbySc9v*UM%&@1uGlCri1ZqvZCA+38P1TFrE%xuwKHorpWaT_SS@00cwBCgm?+;w-HKp!Ix5L%Q= z$Wl8isJFkiaF19nXXhmLHk=7LTkzf;o`84EGrk-sH(A)bg7(~{#bom=_bDu_XM06n znyuLVOP%Dg-=4n2yf&4YB(oArzX!6_Y&!11Qwi+B*cU&O12X}T)~kV41ij-fMzNcA z$G~NAoj-xcQz(FYg6Z5Vq+9>dlY1Htq10YKB(CGU2#q(c`$C#dws<#~XgsP3IyGT5 z#p~(mMmt2N(n3rZQrR}5&*i$4gNtzHS7fOgQ+R7GQ@Sm>kG?sKMwh8?LRc_=Q=Ab| zagP+bhRL^A_1kS^z#JtjsEPMJ3>_<%Lb~;q*BD2AbIKUsTkARx`$yvf!RT5HE z*nSAMeN9NF9<%*Kg%S>VSF?ZZd&?|{AlK({(TXQr(k?%_36)1U@wPCh54=V>@AY3q z`TwgD#Ky(N_P?WirvKMR!^HIeC#2!Ca@1|H-&y;BlJ9w8CM6*3^p`Ke=d#}*bD94E z;FTTOo5UsSNF|am)hFubYz#>UOw>sE1(elq#tk@4T8uSS*sFK+v zH7?e;Dis)moV(f3yp^@Y&m#?q0GNmgp=$u3-g15LL zXE9FmToqQK5UycDQirg>gbS)}GZ$wpYM*e-#TQalvFTg{YM)am=NZO5_%>2qA83o5 zEyM-K!?s|9PKxw_`&e}#|G56S^+uZ3SmOO>;sPriTQQNDhlccbRq|~&hB{VnV z>@`->jY>5HO>w*pgOdNSeiBQf6sa*2@XV~Jjk7x6I)|XAM*F4WN7vf}0@O=DPBm9? z^Tcb@2m}~aVtyGiTeiwej>A>bEP<`zqH+eV*u3U(bBaK%puecINaM%aQyo-?hQ3Sy zGXqZ^Ew~d&w|mrkCEI6pYvp3UOVPCPf&ckzK*Ui@l5hE)-JtOL?|t;|IJk@r%nji^ch@I8BG@CEgwH}P|QZu`0)oY)Xf2pEf8-60OujYVR4hlcq{;^jz=ip)q znx^rf{i}hqgQ5a!TJDP?s2O!P&N#W;u5d55WND#p0IOzcYLq*=&{{5q3;92(k=@O1`+q|@9P1N) zEhN+@Z2iNbYwMK(XrTCFq;%n;126tZeY)`CVrG9H)fVI-Amtl34lb!`{7Z%w?XR3f zu^sjDCJUpFTWVX^0Q9_7fnk|sVnp*a4=-B~sG@irX2rAmVmBgMOiTaNkvU7VhLP^V zxJkuZHMZbh`H|;Z+r%Cq*lbns9`3n}02J{t5xB3BRC>{PzZ_8goO=e<3 ztzB4Rf!w6ArE>-t)lewpYj?Me`nh$%BHLyYf7j=L z3i_q@;Qoo})vP)u33z$H%@m`pB#zLikt2iPdZM?1C(h^ahuZI%mYObL1R)mphf<8& zs9?XQ5iHlh@E68;5KV+6pE2KlF;FIG=GphN^UO5yT2>pu z!!{`KNCDN)koSFZhy5W!nuN>Hrx2KK!@NUH^M8n#+967rF-D;*V1O9UmQR=3zsI4% z5eR3Uo3*%@ogZ0%YK_RwBcK6WX*iGaV^g?rT9}E)J2FMIxzPu8#D4IJm?U%OBj%Ek!8s)GhiPg!dy>@+3vMO`J zNifZ-_j4#=GKL#(rZ5jK6;(*(w5>GB9WY94T;gA{WL|m(S{ z*RH^!sR;ou!sflA+U-;esJX$5EIL_j!a0;Ya@#bDb!*1^&cbGpJsT-LeiBeDFpsuD z2ofN2Wd}|fb$sDGv{I{*S-yU=Jsqr9h+1FZr>e2xS_cWL&|R3{P96htuvYr&SS#(& zisbHda7UIIJld#H6Cpj9b+ANVj@PpB4dG>GN@xaFGSn7&qBum#PSApfT%b%V6v+m9 zZcYrXwmIfCQ~g*1LvswMBza2(lM%1Gt)3ScL&yqR82soEPWd;aVQJ^H2rJVHZO>UMbDk-H$jPx+7f>(GgV4SL^fUEhEpWp=4; z!p6^dF0p3?4;dGS)r^p3S;0#Vmv7PQd->UMp#T@LFf7AGw|jlFIC44&wv6v8t?}lh z>0c3l;aAq=YCCGyE_Os&z~i?dC~qQ8Rff=vb# zj>!Nb$Dn-i}P2nTMgr)piDx~hVYpx1I(fGjSQa0Wf{Ma2f z3wuF($yUj+@6`c&sd|M|vpyIkj()Pf{HCqe##zN{WXrLb8?->mQ`X|$vJi!b`9*5F z*vN$?cj*xX>8Ev(Q%(6}1{36+bpfJvM4DZ1SB#q9BA}JEauve&lN!j37lwTy zp?mExt1iyiQvu*hpW4U44p;|+S|fWV4_$*OG|TV#Kw5B2;&P6ecIwc`d;s$M7G@ev zCg(A%Ko(;6q|-|dTj>wiVkim}4nz=5kc`@f+{6q5-gO~BzT8>caXpIndLv8CdKPum z?|xQCW(;EfH)fDJ93&S{@m1@EiRHObfkTm;gu3Gx7Pbk-)311~o?W zY#hGI7x}r_k9<`TwTUj|ZTIG0xN{PhD;XX!&kmU9f*~h}_TK9ux+&|MGha0%ZIO;G z$Qd{)D6EJguV?VmreWe{?ziDiv*h$;Zj9ey zhHd5^sFkpJ&dr=>>xwpGBi7h=rR}8Df}bedA{NcBR(+MMPao3%b!ZO=_t%3cukw_8 zyO5_32T;`!wGf_aA&35Z!Tv}~pHwRzrW!2M9lsnxJ^Vu=mpKplS2?u_xfx#&7AzBY zCU6VlJ&gvPkW+d}rppuY&qLi0MXkQX2R~ zH|Hw1FyqRIWS=}u=ONXCXVhz`540-9<}k9ap2$Wfek?O554mw!$|0vpr+-*DCF%Y& z?tStm&AaNXpaN>pZP`T>7ML7L2@Pj-!ON-HQFwj&2#PLEK3ZZ~a#V@~1YQSj3y zKGfHgrZv=YSXuQUl&W9*@f9?3wO&)dXY(cfy-GyVyF+`S?KI6JXOrtrBt5dY`47!8!L5`V0xczx5isy;xgbh1y3n{8xBmDO0}7tcJg5y-0@$uNQ_e=qcSJ{Dw3LV2*3Gi%2ZU?Q9fecuyY!w$6ktb&4bfv` zTE5K(nH^6SVa2^_CGLWeZ9H&P$7)ZetD;rMPBWP~L8vl8AX;>qONiqB)y9V-9A`iv$_*Z4L_$*^;{NG1I^ns7wqGpwkBJyl0^}Z zE%ZFCtRZpSof|GSDp+w+^!%DR^qiiOI^r!hD(j=NjMFxn2mIhdaaiw`Cu!5LkRe=r zQI&fX3QTs2W=}B#Rx6aBpPHRgqO9wa;FWetR<@Xu_{_HI z4X)o3AR%0gX1eNJlOZUzH_+0xOwe?-LPIkFQ;{#j&L*i+cD+W4)jD!ysgM6e^?+TS z**I#}iHy$##MdAMaREt)&@HIwCm~?-BUHQ5@NB((-eHIxa_L$VmHZyr{r{G(D=LUO zmu@wiOM>d%Lv?vcK&0L6R(3zm z)c3HOn+ewaQxVZ_F(u3dzSFgWgBmqN@@M=CS8s{Vnn0HlxA*%%>>VtLyaqcA)ZJFqZZ3Jx-3@e7GVZETzFbFm)Ce<&M-*ynjQf9`QKaX zO53Ge_SLJe)%qx~S{8S|boWQxjA{QFnIE7RTT)(aSm|tH>yul+6WQXH;uwut>|Q{bJ;i7B13Jc9hQK)!Ezg|bYu2VP7Bxg z=(h5>tpzSogc2$pl+$2$S+kG+FeU_qfnzgceuA3Vs=}dwKOJqre^x~7qm^DLo>b>` zA^&$ZtC?%6(dr=6s|@sGg1u5bUVq3b?IXChOBF_27rrBz9$&Fvdb&nRlRPuu2FMjY z^j?NL&5!T!d2M5O*+&Rs8>;j5NYBYC^LM1GgxhH?rTq%`WnF(Cn8gAP=UK`2;Yj$# zsaAm`I-ZdhwOyiNHia{h#K_cX<+ZbhqlAt{_4T9%YNI-n7(=T-8|&@&SK!+Dohm3O zX}S{Vogr?_ao6?=av9JdvEFL-%(uQ5e!#Qb_b9FFNU-(zPVW#k zGU{|gqvTmG0-Z8}5#n6X!6zU9d^0jcWY+yvAe88Gs-xY{zg4S+OATFc(;MEiuP4)< zxJCZW$szLvTz6=xJF=;+4lenM(K1*$*pzIIZFqH6lOPL>?AnKGQnSoqIO|B%}j@t|{uR7dr+h2OdLg=9JjPSd0C-eNK8={45C zdQ7FAFZ9V_gZ(`jf3HS|$^uMge^$=0^3skLdAXVMlWSF4+Vxq;RJ!0ST-yXIYI-{c z*FT&bXe_!Sx;k5Ft68Y!s$+pyGw0}*U_W-#3ioTlt5q!d!M0!|Muuu=llCVoCG`#@ zuo~?2=&pMDB!C+jACi5G!X4GV`kbrZot)whv9BuDthpa5K!SBO_t2)*w|=>Uyde!A z9i+IaGNP37&_*A->(U`sX_)!KG7#9K25*#qDHR<4!qCbbvtQDJ`54#t=>n3++g%{Rcx&jE7LY;&=LSpWrs$x` zu^KE~5qPiGXi8rAF9O8q-5ln5$aU(t|Awu=7MRnw6fe$zc?**PGAoN4?G+3c2Z)b%c-|-?0{RZ9IfqkrmrJobt9}!C>H~Ns&yRPi z;23)lyvR>B-aiXwI6rv5$2vP$Db9?P64f6aAh}b#!QGC=T)tlZ+?3MG91*Espc2~& zmQ9GnGrWIYo4YaaIEnTh1dRfO05c(S%Tyd-O6-#FlD8jC{VRZ6*cmx%f1STMC{^`~ zCrwRF5ATU*k%H`u5H|47@ZE+1`K|77o#0kw&{ce3zlGi$c+(DVi5z(+Vlg|Wp6RyD zzFM)r22YZ4D5;GzDkx6FgmN=iW+o|->7q%P1E>DxbR(_m2WZ&-yMFR`D%zN$`)1(6 zhc^M<*tA)wkYQ!nLN{Ff>5RW)%feIu1#?5ng|W;-gld-u#ojxe$iZp?z#|+cox1QnQ=sjDvF_0in_^`4PU=!=Tv!D>}oBuKsV&tpzu|oZoe<$<{ zV|HHlpoF7k_GP#8bm_D3?t7f=tF+?&Tk627OsL5&Drb9B_#luXY504|>O-0M5Tp;_ ziio7Jqi;LP%f(p#n$)qDw5UtxPlB@cSktUY5$UoC$wpsb-3ZP2Pq6#ie!nC*_7*_?4@Wl0<3$ z^*N^x)F44k{r`>y{(IQ}pN2m>BL~y}84Ga!&;7%^ybQ7?wq{P|L`+Qo@!2aeh+9}Y znK%$Jh+7*tnTVPg{V_J-=ZA50axgKlfpN>c!n69LGxXS@`p8lFmZw{AX|j!2O05W! z*zAXsiAYCeX+08#!b9vrRDAAx!^Prwlj(l79xb8@PCUq%?P+@4so$_u^FIJp-+bH~ zp3mL7S$dasOO&@aXWP%7ytEoc-*{P7Uv5AVoFQrd0aQUEKL1~UD$b2}%g;Uj{{g5X z#rv@{=@a(H{&zstiTfK$NG6NbGUYoiJ2Vx(*NdSqX%PsckIiVv&DEborGyg)Z^B}5 zN5&sHlc=36&4`s925^KGq9?bTbBq7d}9L>l!3J9*k{aoMnj)A9@y1+Gb0Uxcl zCQ|0u_!9P{TW*%VY4)`@7uv+Vc!LHASgxxd7gJhL1Mj^E3pYaH?RME9f`MBboaZmhUv23#MAt=K@C@=RcJ6}igLw}GqU3p-_RkFoav+A3 zyXmqFoblN}sx2ichQG$2rsgA%&cp}^R3E6p%kx)O-XpZaD`YBa<8oQy@C*lz2KNAW z6$-ng)rCm>XUs=v5?w^JO0()7?gc?&<1C$CZi?B{8dbL^^Xcc0>2grNVgxzq7>K_ zrAT2KyFyc&q%jGzU5A47zNz;UtgiCO5i1~FPi5}-8V>-(LWkcRr){C9a}kgzxdK`U zZUMe62?+IZ@D3qYsYRx5LA3H-l!`4n;>Ms7;?)iWqU!SuxT@%Pc8xK#6mS`d`jIO9 z4k-}^gVOL>evd8J_q8FPizLuS80j;3U4${r(+P(>5{O8dwA9HenPt8%VuMYlHAEX> z-D+-2_J8~N&6Th;Ad-G#QxtHrkXBvV>1sH%_W<`e-;cwu3A;s1s{Vo;4>JQE>1Qh1 zclfO*>_-~tA#bT&yNAvln2Ftx?I%PA*)vol5Cz)_Vl5yF1yIlIya0`ov&oYi@Ocxfpn5@fxmLFbr>7e5!s%8i`OszLo-XUtVhr>l$%J+!O10hm)x zXpZTLsu9vrjzzm9d_Fu(_?A2KF;y3q4L+Zgs0{W1do6sM5mhs)2yHgG1x4_7>ICcR0-4usD!a-7mw0GP8rl{1-ka>fEMRiNr)RHiJ-vr$ ziQ{ZB*4~a-{3)a9L-4e!2qkfst^^&roai72GpbV6s!l#yEBLL}iD-@leJb3^ zOeH1p)!T#SnF_s%<|okabzeV~xqUG8KXpQEd8cEp4% zky%|abP1jL%a$*iku4$@PMAps>C-8T!uv7%{xQV7rh`wJvp705c7-_-88*>a49u@+ zG*%sO&D>sJp;*Ua6B&J9NNoALQ{Kg|4HhB_X0m3iM1{8OF!_r!yfi`y;TDZU1q0H8 zAW;DJj*Wrs3pW8D__#l{Mb0ggLu3zHV*+7U&;{;gzhy*={8tJe7teK-jx`{HDbpHB zti_*C=x{y-jp# z{I3Eq_pmuvBNe`Mfc`Ikk^7_Gz9MFqzrVrUY|>jz7h?)c8Moo^mO39Scr%-9Bb3oy zfQIG@eLIl9FszV42Ae@+uRBc!WIc7NCx<|*>{El6fR7=>OUHM5JoVp5j;!qSW)R*W{55dv<=~7w;8#S) z_Vv!W5@XY$mz-C&3ZYu9L_Pjxf!xsrt;5-LnF$|5$jRxk6;;zk#B+YEg0n3exPQUy^Vr%W>p8d=&Hro^A8NCEpyv zOI{x+-QBW7O13ii*FBU&MbcucTg!$)j-9OtWY%rV+>vYqP59o|xvtt*) zC^L%%hvc@qAxfxrSxw!>ERw*1=0vQt+vIst0nBk+ zX=wx$Z6S;jVM)j+Td;|m!?dOUOpY;_CtiX^nS}ii=2$3DABX6@fNjaCgf}(ULX5L2 z>Jd*;cjSf2o5yN>gI*kUAAf)uds9 zh(SA)L(n@7p|)c67b|v=`~M?K*g0A&`ODiEjuItPYsa8UuCW)ID25PZt2z$4e`r9; zwO29Fx-3|!j)4ZiX;y1AmU?BKOW!acNey58CCwkbfkkmH$|`R~Y3e-+KUm6|_c7vT zo2RQ-OHAt~dslbKX>xXI>RJg*f;nxSQM9fa85@B4nwN26hJBh@Z$d_9n~pO0IQ{#W z_jg>bbepse$bixmxOhu*Xl@VXBLM3$rS5yymPvOUbcZ z1(KIaVj&fXx;qo6WTB$pQnWN`_Ey0j$ZMk)@^M9FH_CP7*eNGWjJNGB@%v6mt8(25 zc6ai-i&k673*7PYF{}ssBT$o+4k4aFe(78VmIZLQa(DsDEu6Xh*VWz=pq4ghqXCq_ zkGziWemF#a9!EW3i$4ch?sO(Q0YIwQYP5qzsW05%P1_9{cqY_ zz063&+f+4oJ7Q=FSG*JoVSe&Dpe%-uh*XUfG52T9sI>VGmfdzo-wK$0-DRbNxeu6H zHlx`<;obxru-Umhtwy}8N=9%Ooqp6o2n zfo1@SbDm?_U;_8-?1c7@od+o@G_HMQhAMjEYG-EtDH(H)jOkC`#nG*UAOfJ_ z59+)9a>NU|vd3u~b!by9@}J$sSsHwf9pER6O$kh8B86n2ba9rEyvR^pP17=xc-*Ef zKPH#-XNcvf%wXuSQHwmZ>QPsJb`6muZI}=!IY(U+W@&A7L`|2XDV=ktL!}}Lo6lt9 zz#n#$@bVc!CdNj2z#fl|=s?#K>wOM1~V1IyHpQ9y={Mn(^>3}n??9p?C2cW5GZ22lUI{W#_PIO0W_|52Ul zJf?V?<#%NuC(5OO!l6}tuz!@>{2-IEveiBjp%f|$AsZ7X)+**>?hBk>S{O?=TMUPO zLF0pCw6Ns5^Bnu|3~za_Hn2LK*aX%iM>x;c9kf)v5e3{ z*aNOu<-~rcpO3f#H!6t}>h>=6P+H(`L8pmCZD(eelrXqW1XWo>vKg87dGbPr!pMYn zj1o&^=)?Vw;;qfNvMz!jPg|Fxxsoe1k4bH!pH_|G{+LHC1Nnfm!CN*I(%#Fl1=UgL zn~8;8vjO3mu5z=V#Vw{be`-R|#4&U*O3{XbJ2$W*1$$t7tlZn%1 z4r#_bM}5zlzC$P$iN~ySuFUoW^x!QRQli4JOk*s_&N&xh2o`Bj5ce%oD^s4pY~PNM zgo*;QV4HBH%IU=FcwpJv5KfnDkW(>Z0I@%nds?Vi=z1d<;&BCvSK(f1p(->_fOEg{ znmG$eAJ$j(ukIn-fI!uh0owFSB^KT=N{4LBiZatvJsOul^2DU%7zn};(VqhH^6;CV zSwM55y?nx5Q7|G6qgT85p@?o<{&%J678LlJcBtRovJ`^8p({S*76|>p?D{Zx{;0<@ z%EcZvFYj>~4m>irScNIMeyia4;jU!KUkkiU01gdg2ZI< zZ#0(j(fyQ4x>)_8UW>xMor1`ci9;BN*fFt}a%Kj-Rx=H=*Kn*l)gyCF|2tu6&dA9b zDc)F&0CCL5FKuz_h(mbUQ;YnACv$4ucC;K4XHW=4>&RHK{a=c>lJ*0G{j%54e_+FP z+EwKC`W0n3-5M9bgyg;@G(Yh2(>>&RUv`1Y4T$`qX5}dA9Sm&m=h2`Txq`RQeuYCA zqKyv+LWD)QAt??uAs(=@9E6m%W;K~ah$8+2$`TAEdoR$ zY$of(30GM+1{w{FTK=dU<-rt6yU;~0O{A#U;O(hsEhn>e4itA`HS&bz8$9fmMQZG` z3%TXLXub$&uhxpef~nbE=sSaswdbSv&g+*@@jArW8g8=VFL#^gjFHF|48R#0$mF1V z9s85;;BS)YAtRd57>wu-=)6BNFQp+DUoJR%stUFY4C8E=#_RNCs7~6f1+%1Pye$pfA9~;aOCJ>!IRT)sn3?3BfW39fWM_J$T_B+cf!%Jg4 zTrh*J9$f#OM%AgXoazLaaos?=Klu>&q=pcl>|wgU`1vH;?ulSCOqsS5=V9uFJ0}yi zmyo1z*>)p@^ZR&9GR%wo{+?&($YE1B&x9`vAZX5jw4)<@SPs_m@X~S9xDm%#>>YKy zn?0O6nAncebFmNLr9CRl^fh|9XgH-YM&wB&>g8FXAMiwnyd4YQ9w<^%f(n3=$Z}c1 zIMoX}ws7rp$He0LB=vX`qlj)Fz07e{V=W8c+1~H$sDm9i4>Jw;TjuYY+;ihbjX$yf zV?`+zeZRE)>>z^|?ORt%bcd&q3vXs12yzx9IOk>MIFX$g1VnscZ|@YZ*~&M+Ri>ml zM|bqfTjAI$!s;LGrMSPG@P6#NKz%9`_@syA7>hkCx*i15*D`eUex-$gt#WLf3R(|l z&F9?^@m?ZiEQXUjWT?=mKZJo=vRkFbjg%ZA2)PE%;mA&D5!Ff z?YA=8jQ3*bQh2ZX$)EY!UY7>Q-_0aEiJ1t{U9G%a+Nn0|3DUu~fu?bXFzkF#hg@1X zzt^0Ms;2d1IF`d*x?|B@0bIk8iqx6kux6PK6N(7E=zp0iR zr&=8xR)uhwMZ`-O5C47Y;N`VZ#skO)-lj;{WoY={yazK+d2Sd|Go1f+h}o1>9fAYY zmIT`CIu zNL$OZ_uc=7Db*d}qgar8W)WgU)%0FQ`D(DLQ%J>op1@Mr{5BtFe|dxK9Q&7_;_fE8 z0wKhqHtQY*i3&ck_;S_Kbl-Uq|78 zVvYmv$cY|msQZ8;+B*BcZs^>vO7RUd_ZJHSpX?ChEB$}B1-u^;u2(6#t>2Sop-3P1 zPWi7<_#+xy93Ps!O$pl*&8mUPX8qP)ie<)k1+`{UVd>KfjmMN}hRoCG;7~9xCCz;F#fnE#7HFZ2Ijp;zbZKjyXX z>f@NzKf2&+nA;NCXp);`l8&wRDup&Eh0Vs=!OlbRh(|RyaAVJ$hotHiO(q@D23YyO z_z4EMd|2@ASHN*!0`__y9KYR84tQMdZoNY2y8XTpU46Fp^7=?VR|WLE+99JjL(=3u%2|Je!S^%~n6eS}j zUIAcE(;1=@8l6cIIVby9Iv-}AX^-IyzGF>0ha}kh`fZZyK0l|9_IomHdS-?g9Pb3& z5$Ygsvce}A($Jxfv6LgwQ$Qh^#YwzS&94fd>xph71Z9XLn3D~0$V3SWk&#m z40T~R+0h+h$ZqQDa*x*Z3Z3}p9%6jE7g+@?dFa7KS<6(xWl`i~oH_RqyT>HY!_nc9xdn5emgbr_-GI z?x5Y~^s;_FBpQ8KTX-$aeoTNakQld8Ris0%gR~~`_S;sjq*V!i^rH24h%KV04H{!Jv%>I|z8Ku?)mc4Bn_M)o|F7JtTZR&521D;Fcl^E{k5 zZKP?gtv_fRN3Vx%Wh+0d!ym{AG8Z5h6;X^#Q`(w+w%mxs<(Nay&CUErt%Cig92c4@ zMXeEZNNlh|MgM9BQnohW@$AXaOzRy{Eoo0n))>i895Qq`)K#&0(mUzvm;g&y@x0G0 zx%%He9AV(9dLmB0Q&A_n09k(x&ju7T1MIZ)Mv0gHjsSZ>k0g#SII5seS03n0EHAP! z$`5@RkcgKC^q#~4=9TGW%(Tt}N8M#-(43bq48COPZ?39=oHeFZ<^q0A4H)C%96BT`#h+d&gO=wcgi)#=^+0Z2NI6ELwq5h2bGAJy;XXE-4)Y&S^9)F*6 z8$lM3`^FTp_ba_m`TRUlm49o~OT#*Zq`t26D1a*w4SN`Ma8t?l$sxzHFUm||2f?nh zoAMN9-PA!TZe#uRIe=v+dmv>ufGMchti6f9Sh!+v3^Bk`SMkueh=>4DC>C9;dLU6C zTXb-!mb0S)o4NF9)XhM$K&`FItDxq9uXw*RA}i?qtR_a2mrYM3}WO8s-bcDXkQ3(<~|cV?&?e2Kos4mR!FyECD|&?f#$*(x;tNaTV!g zCGnC9@W#H{Ylkl-qk)C=mzD{#>@CuQEQQD>wiZTt*Idk~6{v!ksP^v$d1`~jh8L8^ zGEyFeT2Ry30W%H?15!#A632=KzGDxJ6eI`7`U7t)${j98OnR+|9%IR1Pb!N6qB@C4 zJ@UR{FwEGh6M_xjum8>t7+z|vRzy7zVQmj&?epDHj%@*7^;$lJn zGGTL2Vu)ck2YOS}y})Cw5qF0jy@gNC^tmJ63FyC^J_fd@NDNS`~WWH z!!RsYEN?hf zs4Y!4`yxwki4rd5BPy~(A$ak30{Lx(0$O*TUp%kl%1)9Pe6!hQM7&dg&r(AlBH)lF zr8LeMShRwAa~Lrg_Bq94!9WWmRvY<@SOw+Z?DTc4+=*R;WG-4IRKnKcPxsIW!x+W2 zxQ)Mo0YaPr>R|8kDGn@<^1C-0N~MYjBqt0 z=&P=_N2%zmMcoxB^w z6sM%@_H26*LBd6B|74$)0xAeFmCq|n>kvxod9d15MhJIghUg>Ae?wFzY>l@V8JMNK zqan822>4)S%jabX~^0EyF~M0HEuJtwRC}D0_;jwM=LABX`Mf_=RA! zFi$KL!riKYzWz;O;e-a|_NS&&N=q}pG*gm{-Th*HAGxC`BteA0k4F_R1Od; z+oUWxkUEzyhfxQ2g++xd9a^K*pGOujcg-%fk``pY4-2KjwfE$&dBK4_*9%Z&(EF7F({W&vS5D=_+Ltg-v<% z1mR9h94%}^rIBP%jLX?7=?J8{E~gK@$ZR6WG6p_52qj{thFb27=f?)@$4I#itYYG7 z5C#B(sT9u;b%)%~?+j^b6}NMtuvavk2a!osC9n>;;;4s9idB()I7EZB%yZG^oy-dz z0Sml@P$jO`v!f04_6XSEI?RHE6)(gHNz4#N5HMf4dm5SUv>?6`OfysbWY+6|p1SQ{ zG+2|u@b=L94dJEjBmZY~?XF^IaxvQihSe?@bJix%T-r$v?G5HIm8~+S|BxCZE^IEs zG6}+JqI7w*SZk69QZ^QMC!$GFyJZXxwS%;~0ERSf3szgR)qeKyN%TG`?yO@B5|p^m zfP=cE;lWt?%(%%=kN|E&lSi0a#vJ&jywSeUd1P&Fkb&>d8)b}xeJeC1!~%F#2IuWI zS|1h*dXdH#=-98w6xG)dFl z$hOSucJ{Ca$TOjD;9Gj7Xiq%H=qmSK*yMw?o%LBOP_uor{xOrA*#>D~RSZ8?RF+nt zrBgaZ^I}7`=S)HUa%kwsiry+ykJ9Px2y--ft%3TMVR05(et!W_dXk6DAw1<8t8-C5d%_z1nI%*TCI`x6R*@AxK#hwrqAi7$u0s!>n{i2@b>PO6(>_R7e! z?wU%UxuO*GGQDcP17D6movK@cewhpKqoh!FsgnRPXY!&!+@^`RPJN3UfM{d~#>KxpY9~_a`rNn$v^>^> z>^Q@+P{;y2Ed*0IJ1E3)Uiu4(e4|T4dP?4jht&XW;OzOUg{tD20A1uN*lPN6Wr%4% zdd(L^|M~Tb`gT&2Mf|8<_FkDa7sZtSeCGJ0$R2aM85{tM?`uxAsQ)ve@8 zTh=bw1gU|T|2U(JV7EDf3fZ=1y{1>~ut8prsi|>DwYp_9$#tIb4u~cQkqL3ENSsc` z4RdR?3y_5oi+@8c27Dz?zbisGqvJy*l*Y{Z*WtvKCC*MZ!g`i7#!V@&w7Xij_&2&- zlSeZL+h{SHt^!h@7)Xt%ni8iJtfvo1y3qJ!-x{ejRY!fP55$SRV!cJ2kuy%Iz3ym) z06{V3LLw(7^G6ny&PBV4Omwn`Po1%dhL{caqY?OKWw;!`CBIZt;damr6ifhOR{rn3 zp0CNfkI@OaJ1fG*ZYwlOI zS0^}j%odh$xJs-^r_YR~3{h}gj3yXQyh5moMsF&)xRdIt$h-Hp2$-eNh34VQ({UW4 zmz)Kp3s$N019k`8Dtb-GC3IHlxJSjuJ+gIp4@iG`F2PEmE|XhsNv87wuhvF(>gs^- zih0CZ9MD2AyA%TI_HcsJk4SUp^${HtRSlAI*egadm9hv~g7JDsL-G4rM&}wnc=?h6 z#~*LhyU#f}M9#xfnQ&JLthujQ!|7oq*H*vFXpwyg^`1v2`gGFZdbQ*1jtnu4zgzOc z^d1^~jzZkRnhZ)_AMKB3svH~P20yY0YHe|!Onk6!0x~HxFkhK^KAn}SP~57lK?VG6 zOH~gVcm{0^A>!2RtONzx!<^U8Y@@&sSU95i3u~)AfzMs~Z!Z?ZpDl zg|+7kU$l}8lCX50R9tUJv*P%%jUOd-VsD4L!8`ZvS&?2RF-QB@)y*3>o%{X%wu<%k zzv!EmuC3?Jf)rEmV?ap!inF0aD>Zc*eAu*bZ+NsTS@$@x?#JU>il~1X#IW$6-uauI zK6jdGXJughJ|CkudFSGnW5Ryq$-NMaQi$_f z1vbvAZCl*O;KX5EHxIC?I=VyOh!zPvZ>3As9=?A3*1yunEfT}wS33m$1h-04GYN+qP}nwyVpoF59+k+qR9{{{%C^onVq3?0BCOtY>}iYHf#S zcCwBci^sY&)zf}(VlcoD-~_AV15ip1SWu}46;t$ZrFmkYFpKm>*gshXdl76~{YWo$ z+dr#53RwM2FBO_?X`@oWU7+CKOQ}|WNiQ8-DwI>R#DX`t7@=n_2N1VAP{mA#NU(Ri z#Q-xAWpLe|l!2m0tntl|3{5_T)i)csSyGMn9B8^WN!Qyp&NaMhj`u7xP$jJ1+sBTRESJllKXZXHzAim9h zOL2?oR-8%_6#)mL7N{~RM4YpMWHXsmQ)8gz?fE=6WBWWKhc`#A0pTF3V9RcHy0CP2 zo4a>PW7HhxSK9vu|JLWOI)|5c)3DLM|5x7KZ++jekLJ7HpXbv89n29feTI3~yi?xo zp!R*LF~haN*{j97>v8bw5cKjtDaLnZkbf!0*;fFQ3Fz|oFP6et#G`CYW_}$SP4Xg_ zyTP>R;$*0jduL(4x7A@K%4JWw(_J7f25^M$ZRG4Y%VQ5-+`fM$M(8ieoiRSaBtrh{ zA8&EU9Y*@Ss!nhRJ~=iM<{09%g=o3Hx#EYM;Nt`O8HZ$ZF)hwt&Z+8uXzEA1y`-rH zd1E$@KIA%k=~#~*O~802CZiW#I4AgBR8Z9^J(wfIEEOqzOH5FB@M1SR6l*Y{~&q ze$d5vR}L`gODqgo>6ZgOT6$cS@rwjeVdMQUkk7^4WYJ|DAKkOZu70VG`g+NSJu1YA zPESbwrp}uFWRxQmIgV0Q=R6D4Ddn!^k@t02*1~KrFCKlsRR@CcmsN)reG8CD#yTAw z$tu=)+-QNA3HV)C9(7G9nTRwty_bNW#65l!D95mjE8y}q3Km-youtai!4?AAvRm?r zMJo+Zj3A=CJ>ugsk*2-jI&DRyF(W( ze1$Fz=>`K-2>7oj6Q8%|avJ8=?4Bo>zWJRf7{2KpO>iRE43@OH$5Ii@-&Ikt;D?-z zc-DOO9TS@bWpE`5fxu=mzVW@qll@%Pr1F_ERNo)o4o#cWa z==o5Q?*)CaZrd)avulnZs?{>BDu=NRv55T1hy+B|B_k}305Hfac?VZFK{`A~Xd>~c zpfSW+0w)*fh%Sp*97#MP{CE$j`a)jfhP|>7m=zI?9ZCj^V%Bz5waf4U-OdP~AQ$mkWlz-WrhRu#N@fvw|I^bMx#Z?x-Q zH*!B_0=(UYrR3b9cv_yDa6BXn++%^^72>;P*A5z95u+c-i} zCt1}rTm1K{spV)@K5rRJCmCZopOxN(?aZO0BCph5i;M!H)#%0cVA-haee9C^bQv9np%qo>- zZmVkAi&BQfzGW*j4n&R2MrW&C6oZmZhlI8kHSB_BfSF)WD=1ci9X04EE*h8{i5G%3 zFi{I9&9%DqsK~u4OZw1+x3!3N>RL19&v!m+Tjri3x%oRY`sFZ$i#mgDu^Pu1M+aS^ z5Gr7f>}RsK7OGUjw`nhuM~R?O1hRAQuyezRub9XG%C(eo@z%JL9s1NOZq~By>`M zMIp@%0amJhHGIp#^s|9<#ey&D6Kw-k(tIH3xYo1E=e4Hah&#;~{T8n}2&}lacOuKu*`$VX=t;U86R53D!&RsrJAR zpI8a6E&C-vPPT+oOg!L6yhe`!IA(ouai16o=2p*u?oo#iyIzcEfa@v){-Jh5VjpX&K z1{wyJ(u4$V3Ou<0o8avXa6yrKSpb;-zCgq|v^NgJz`_$Knl41#Abi?`Zz|qjpzxqw zx~s3tP!J``h~!@3B0yckzTkdpCZL@9*#WSA;-klK35&u|(7d}v0sm7?=FmPui9~~T zx8AjN-&^n)J_e-3J7o=Q!)el~Z&wF2R-IG#h+{P>1wZ%!vCvdgicf~e{?d9~gtn@& z)ojwH{x>86ctsmOg;Q%Ok=`{#@(iK~k7ONW=Hv*$j!ryAG4SMLOvh)&LO?9ZZhYH?PgGBi zA+pTuiSk@9xIur6Q+7;!(QcK??w4!wG$da;&CEz$ilQ7Bz|l@c;cKIe1)I*|CVVFM zPU0`7&hv|T<>_o2RvCN|1_)#Gw^aVz*TveoxPb9&h|nuwR$ZXFXhbC^KJ?S)oedUI z5>TbPOoec~Tz6J}82XwQ=RHAI`mF)NiG%oWDC0k}%$(+wwET$5TdK0CD7E#%9M-Og zMOQb%5sNb;fvthRx{0R!J;Y^`Ts)_cPt^?(^uS=~zz889#b*&0RQJS_FLo`&=Y;7Y zfP|&u+t;YC{H_$8;hE1v+94-MSsnaw0(IPs-a6sNlJEb73#*U$E^g*yq;yFOKB1g(K~Qb#VUgk9ii8q@87fbRLw! z#TMa;pDM590rt+!Y35FsXh5|EQ3&Cwp_H4zD2REjOU&Hqw_L!4V}iyWf*szIjyta7 zfL=Xou`f>~Tqm<|9t^X=W$6+IdOZFsv!4jNacRJ1B+8=|(K}i2PdedwCOIaFWqwbeLNW&ULV&&ZG{9vsa0qz_zNuT)<>&)*zX}UCOJ?ynoHlYXG0tNigoC|jK0a; zC5&HMKRD(WO)xw&D8H@J-2y4!%--oVCLSC54_|N|jJL%}TYs9NjH;d3R}^vC;DvJL zT>H#!+yDw8?4N0J*--g+yWlQ5_WIwtqT`;pV^WbiwP&c2?{Uqi$&=Y0tGMqjvrd2? zcis_L?>9dMJj*aj-UYKQdf@e(Cq1>))`xK*HZ*P(eYm(PkL*8?d!e=i#|Uw0H9B#H zU}XBwuIdu)QL$a?ebYXq?Cj9U{z`T~48gzcpIbV9H0V!yXKI*_%p#tzQF;G%z94H` zyL=13Hr%kCpnP%tzRk~=0MgcvIbwaPaI^}IEZIw(#br4Hqa~d_Pqtz8YBvQDYd#b9ya1zk}|R8#mq4 zy7XYGxo%;E&j(B=^{RwCX^=ND&-`WV4N)h&tKwkNE7kw@B^xkL!ti&x{MfC=UMlVQ zR%0t0>IDs)Rqd(jS$|+(pYPZhCHZ6^EAtl6BCgGk7;%HFF7rsyjQrhC5z&l3@>6#6vnGFK;_W8 z)5d9!YK7v4$|ex#B+Uv?$XH!A_xh*@ZjMwh4^hQ6Tg!GADNouNuR$c#-mDCPYVK!L zowX13m)LyO;3YzQhU5R4=^Hm|;>e*ImyXB48*`|$<>p99{$N3sr}|_44qrHBEHJ9}wsN#4{A_jMe96!kP&>P_X5SqsAS3FGjY5coAhogSDOTonngCe*i_FBbW(bVMOyhan5R2*KsP0yt;!*AOWI0e*TK#Vw1AQzHjem%D^9)vJ3!T&_VOjJ9SvbUQC9pqgt4u13YtpQ(-$~4R^Z0 z&~izL;2Rwv>3|L3*Hn`_uc;GCn)JVmQrlyt@PQBJ)t_rm+*#9nz6^WrPNHL^F^W08 zV9kAY0o97IR*`q@$5=~5d6l~(Y48}DpB<*|pD6t=ltI_ZAg%W(fi0V*5H0eEHhDyA ze4=%}QG0lNq7KmgAIta@Yhag*8mAk9q--P_w~Sffmj-k7b#<^Sw;pvn*1x;_8mCa7 z&=#GN@#{Pq;h0>;-@Y&_%SA~rQTrR}$KUa38xbB@?L2RBa@l;8A;S4AgXhu5_3NJ_Gp(LmU6quySa~>E*jwX& zA0qo7`{;v|?H^64mCqmlkA3v)dfqck_Rl_geounU`Y-$F(S*1-$nt9=0iNHtK~YLJ zck)?%jy63Q?fZsPZnVj%D+g}lA5N+KSp`i{UXTs@`hH^q^34( zhK*^do40z>-0D22W85dREYjaK%*%yYyrc)#s&=3$q>;f{7adp!&cr~2(h=Zf+^h-fQDdAdN_3YEc=_}Ivg#*_(ZyGBFWhsSZTa;@b{U#Rex0Ka8%dpoI z?}9p69hDc*!!Tw_gW^sqpPM?{vJX|bLRE{f{RKEEj6N-Kal>?>-2ds0{jGajkfi#gN z4Fri$A~XM>MEXq|V-oV@E|h0%O$A|3Z7Od|&7k*2f@g_N)tmxfN*`z9H-pTxOZ{1QBCw4~0MF^}$>Dr)uqsIHH9sEa|BlfHE0xs9&x^_g}$Ll%?94 zJjfy_W82Z-_#DV!pw8yqDJG^9gB7vx8uVewV*fR)&j*=|`Kv86W_2x=zq#6t{!J=w z2G8hvMk8%77@{}~i8h2!XV;ZKaY|(;An=H(2(wJ-r;ETlos@qzi=$nxpA9!w(mEW_ zgDzU^21htIDxjEZN{76WW1nm+(wQidMVp91R!H;4b(f?3yqj1Q;+nMLhejG242T#t zxC^oy2?0fjiX;LayR@WHLeQ7H4#DUw2gm*qHRZdER0y+zi2KI^rAIbZs0grwOEZau z+k1@4SaXdh~{%5m8;iVG*x2}l2zg?Q_Km;OplpdD3T4B)6 zocd;sE)nQ(QTS^!321`cH1prQI?ECkJ*`1EQ!G3I&&HTAd&l9PqL-u_iHtEhDf$7) zOwA}w2yoFWcmo3Nwj*d#YQQ*d?o>DFFW4T4r>=Kb@@^TT#w;WK+8w-5kzpr_?5uHX zBk=*80RbdQ(6K=MCInl2#zDIV_liXFXjx33Ga%&~RRs@yFk%YFCD~8Ld%alvW>_#R zoeD-Ajmw|RE%lWnyV&MlFqf_2LUB*S)QGt4=JQCCgFv~Pf}OdR#@eycR>c)S*DXZI z1eUwajAiMe~}=u)qw|)cgE;2nCgMLyw_=CT22EeWhsc z(GavPC#2QzU_2aWm#vU$98ppRE2c#}B>FLX7c2YD>C1($CYC(6tle8Hx#D-P)d7<$ zOG~}bl7GjVfWMoeua@r3k8~#N@INsrWcK{RS{|9&(TTF9Ry~A^#^krI6+782!(?uB zay(k*?Te8IfM!DJ3ctu9}mzyC!~=Xi^HGPEifTrQ=v>z=xYM>NJu)*di_z z+^!}%2ksTw2t=GvL$d}Bo%US-QGH28RL@1KWbJ`Dewhi?M?y&G%#1Mx z9fbmAg!n24J|0RcUd?KLo~dO+C{SUV#<@$-B_PmH+#s4E zFs*2JDay@^5}F62nL2|+4aoa5Y}^2`bW5%4dVfVc*@N3}z1n#TAs!sn~VFO;DZq8aarw<`BDn*ROhg>%cS#gY)A?t`Df?ja5j5waGOk2m9 z3bPjbQ-LGO#om4$lbbnbAyTRhOkTkoEL2g|6Iej7{nS(#jPWUWEjbP5P8JBCP?Vg3 zrMbfZ1v7RZFykCKYUV`dVP~hQj+zTR=BOH-#2NVH>2% zwFS>Nygwly)aqz6v9b@N@|;t1Mh>GGHj$@=XpU;4d%prz!5|XpZe$R+2r%8B$Rm;r zJno~m7F1D~mwfY6tjPlp?GRnWkgQlj>_H7pF(rFU8yeMcEE$3ztmKO03`X5o1ZwC*fU0)e#u7PFNn&W*yxTG##AGa%|tQ=eN1zHif!DBqp7JxkXytzIl?M!*MA zU-`?--Z>65B`d)DnCdUJW=j>0NFiS?X(Xc_0jcAU&;Lfv3FNfajJpP@r|k6}=&{*4 zuLOd~0!5_ILZ&WM8WIx$^Wkl~I)wb6r2sQ83EKod3Vz7bu1M*UldJ_F?aWe_D=-aP zCbhYpq=hb;>BohxGq%BfuFE6|`R-o~n(Qq85Hg&mi=0Lmpe6JUVLaPvV7PdUd+uPa z^RniAU^hHLpjcFFX4`X3OFzxbf3+v{?UPz)pgdQ^H_g|^UpiT!LHkZ-pY0m7On=Kj z5sZ&q>bDXZR>Lg|1<=b5#o2U4Q%=_2!s-$p4GYy7$)?S|GtqOQ!O-&Q0A4>_%&f!e zoyIek{ozMLGy9XZ>Ax2rNo_^Pep!H|_cc(EFAk26^b+;@Zs*tT+x5NIbYG|6XB>TZ zX*5y`F!;q2hUOw*U+0II-^e-h!FM}p_iJ0Uhvv{vy#+q0EB9QpQ6UZ%5cMIHmraQ% z1Ss);k%hRaK+jVUMJdy1XS5>7qk?mqX}&#E-bA+wD88SEVz-ID{UhJ~v8H^iK#;fW8i^lBI?L4#hCgMRZ=nQr{#C>lc!UoX!naQ04RCf`$UCp&cF^E_tG*B@R;>-*GHA{^YeWSBA$@f_J9M4zxSz2{RJjdPn$F5Xsc>JJvh5GxFpZU)XF+0|VRQ)^=N2Wt~EApYO(S~^ULz~xem5kWTeW9Lb zo);-KO3jlAt13nLDIip6a8v3_q0oAb!UOGWZ;p_m0Kpbw=pQb;dtax1=JV$8K(TqFf4YUk6VUH83RJ-gZcLQ6}*g z_yTifw)=wviwDR7HVR_V{u#yD=_}uIh6e_R5QWYL$eZZF|2(P6K9ZeX;+*Qi?3S@f zS}=BFleE>rdFHiKKAi5j(_qYZ`&(}2*)>&1iWndnpaPy+zBeCw3`YZ3?L50L0w6|6 z20H+Qv%9FKGFP(yrI37Xs3H)T%fVl&t@)`S4RR>9cd?WT;VCtzh*sn04C^^wi?=YTQ= z0-C#Jkh|*dS9Go5dXdb@{tK-zv77;ogU_>z%jUCYT6pmwxky7|%^^6hh6<=VyN58R z*Q>ucM41Kjz^QC*1Y~xqudMq1tr+cZyRtYLqRxEhl*!K3gLq7hKjg ziyQLd%hv?m`VT0BG(L$cKVX5piuaSB*jmw)y$j=<5Wv&k9i^i=In5!J#1_ z&%c=U=z8yovu^qDzROC0rKYOaWGT{PBF&5yv4LcXElKFCoj>63$qy>0sILe6%yjXA zB{eP97ioJMJ;Rg!Dm6%JRaTZeb&tM`YvIrxHGu;V? z-nwc^CifI8Q^3mM=)#nDVMjbPsi;Dq<`^`6nm0(Y_g z9k^?BM$YxAdU07#sU>-$9XeW`uErzlLM$?tq$-j1T0>pNQqk>rcejGjMuQ9%i(@Jr zh5c;82p>5(ER@p>DH&&iT(EJ3uW$|Zv$rN+*DGyBB-vX101Z+~hh)(tL&AL` zRrdE`K5jY3WBb$!IAo%xB0N#>yX#gMcye~Db96H-drM$hR;tD#WmzgN5(QiFx5Mcy zarYZp^9egD=98=Ykzl`yx|h@GRO}{Yg=D)lVaI8&K3#w^|zVXtIFy#2rL_5ZR zmNgaNVy8Iv8Dpk+djK=4#Bqgrcs0{DwOu0~ZQtc%kg-nc#lYpm{bh}B4WQwe{Ch5) zjEGZabCk7Bw#6wr%jeuzmTzCB0T@;{XFFWfv7rG$RBzZHg&wkoZdxNf1hGhGMB7(~ ztEifl|1!BJcG1DlrP2aCquSj1#p9;UOT&N(==3l*LI0M5i3L@ttx&a?uQ4Yy&6+Gi zT?$vTOSV^RB?{&?xPFZ-0+Y^I5g$Z$hQ46*MA2_Dl7^{10hv|`m)t?j__A|oxD++e z$M^Ln=D~;KRM>I%ata>F;h_jgMj*AYC!~u?m1=U|d@53i!%f%A6*-XQ`RY3VmYEU6 zA8N#fx*3RTDUJW+ixzGGiKoR#{NpmPH{njDvJm~X|6Q8erL-Kbm*(i;H_8r7l*Wg@ zv)vD~0@35uXR8S-f_o$MH^>#@mgqz0ts0C9rXJmzL9ym5PT_cyuUJttIOOuVDBae2 zV)!<}9(Q5;CVvQqe1%&cNihzH;ITCq1oP)Usm>=O+OAtz#13;V->U?+l30)XsE4hvLErT?)8q z7m^TrxmD?2dqAmb_?JmEV^R(C5Zu==n%LvSJ-e(&&RN}8cR(nt1nQwYnn}u}JSMMa zYfJz#<#M{mo=_%{@kg%_qJx=-?rJ1nkk#g)e!W8y7^oDCLab`FO-{8FcH&L?=AdSJ zy!zrIE2>ES=9wdEQybo@>Nzv}>?t?v^u`?Vam-(ccgcHu_aLsjVf9d!7R=V(xZ$QFP^`mEnKd@67*;F30?T)8%wD|1n-fKlBG;x{p7V z1g{~VN+_TWZMK=!kYK_4j|tz4@;d`3(?%Ik~ibTmXV8LUYHFq|w3SUk7T> z2mXYz`7k*-I<&lAKOFipIrdjAOqSM+L)N=_LdX))9R8uBcYbZQR+4Jc%Dt)`8{%NU z8$A7_o&l9HPJ{Zsi~po195SKQ_XFOJ!LZoh<#k&`q=cz14Q4AII4k(&L3Rr1m`}Kc z`{^Oa$cZqmTMaf|!xsfv-*O{Xhl)TBqEj1?151VOeOs9&j||cWxq%>EdH|Aj>6x7x zqMZ*U9>TCg!j*w;^f}**v92_TIE_2-@;p9aP*WPbr#}pXR5yDcu>ZqkwLr#dOyq?3 zLy)>_`msgF_ZD^zTAY-!koOoR&DuUK0@lWw!KfBWYW(PF*E2Rv%;QFyk(q4P_R7Hi z`M9uU(r)RatSy+f3$K=yMSp6xrb{`zRVNA6uAvBwL+TPvob}Gd5jyx1KspG_#>BUP zhWYEbvl!m~&cF_DH`)^K^!T{-Ma4cpkav9Ys*A-pJ?(#b65MPKP{kMm!2!&tXsNMw z6L`veR^EWq)A-Gx0CRG6!_7gpKHB6fuzspQ50|HMG`{oW8Ykd_w?l6Va)24fxm?%?U*+h>xE)oNmBjvwlLdB4 z%a=ua9!@!f7B!C+z%H%gn!6NG5KrBR{^NjW2ni`v^I%pRc2;WtmT|N;#CmXWcWt0n zHG1zA<0V3^mP9ovM&&T(69v$i`wi!|H%AOoGK_>GP`V-0z%1uI0wu*OJMtG3MJSM? zUu_X$T#(_tF@aC^+R#?v`__Tu=gH&+i}VA=SE58_i3h(Ix>&w*8Lf|af8Nr?p?`$x zw?}SKEAlv*l{u9h^D}w7XKt2!2e)sBTj`cuh-0u@6stF=IozgMis*=8;);j|0fNRs z729mdszF%*Ch85pEePEAlSrag4H+m>DTvIONrIMX;844{J7$rZe5M0CaJ~mtkwZy_ zJresK40t@f$>-}-0 zug=$^{-i{DZyv@l^U6+J=cfxHl}FE{Cho-UbY@`eE((#)P@M-Wv)}=Ik{IbNekBoG zusL1`qj1RB5he^_rgQ^q3+pRNl`^G3L_ebkM;s1h z0Rio=AfhCUQl6?R{{-QMElOU>@pImy4Jai-9M{||3s#h`?(ykK9?hQO9X1J8V@k8> zB9sxO`cpWKD9t*74?NlJ!gAYrl()n^X(JX?@0);FlS6LlOKK7pRt4o|KU zo&s|HjB=f)ksX3KS9mJ(m{3t%-IFfw9Xm%ozp>9>{KyWe6G= zu$Xl$xFiFWIgl>$E<~S{gLe7DKLp*pnevGzun5nlyd3u{)7CPUr1+)2)G=*L){D1F zWV5e1XaQAu>-W zs;QJ5EFx5>x(R1}s;aO69ed(Ndu6Ij`(VNLtR0~TE@&=Jx@s;72%y|o2vGzTF7k7t zH|DEETZcW5b@MpCm4ggwnrfe#Gx3ZLB${D$*&~fJewN7I!&J>9!p@Tv160@d+elqY z7VzZ-LZu7nrwx86XJ!j1aFj^>##8a0!<5$IFK`L4t59(5eLXNSO|J!~CB0xY5fbbV zH)_R=^_X7PU5(FfXM?DLR<#fUfHYimH3smSz)}*EDCTsfn2}vU3UntQ3W&%z3We>{6AUzlRFP_SNh#n*k4va z1BT@otMfi@?Wl%hl5r&eimUTBQg>Xmo~k)5Yuj}z)^OE$j8&`$ip1W2gLq=L^$O7a zr3yk{{}Y|bOlqgHhoYdJSq*>=@7xHO*dytjbX+n%ee3*4!ai%QqGNoVwbgY+i_>C= z-nTwvOTFI^q+8Vo1&wtbO1+*hgXzG*;|CZ9(T6?dZjErZ1|4Qm4hTlU)_y{Ma~s4B zekiz?V?c0LBLE76vZ(U{mu;n9VS^5ycZ=J_o;D3}b0veA?+H;VA`oGkf$I`3erDn& z7{ysFZZKK|lCPl`H;5Cp&|p*geE4+~9*6|XcN&JE6s&Iy5jlXn6_U`Ui81Oqa05#9 zMyWHovmE+I*#m%#!rN{p1`+zl@LWz0%s+ID2|1iS!qShNUb7S&H@w|>Acs|D%j-!t z2=im%lAZleIY!W)8pVnVyQjZP6gkw_sBx{YR048->NNY&##C|mym}xMzID`ThxZbw zpIHClCezh{M!zXCg3~Fq9fuz&QGpAvh6qW@eEK?cnJ_~nDk)Y31N+W;z~??+stp_y z1T&Oi?o%hDexc**H-S8mn~4d1>_y5EN0l7QW0iXd#5UT$ss{PngcsjffGXGc4+@Us z;C>MnT_>s`n#v0_4t%9Ea@*F{Uhs8C8KzFEQpNFZ0)YOMpT8SiJrf9f8X}jAGxBXR z#z#S%!SKrRy{MaQePP|_-&hXFC{Qu&L?WdHxz1s1Jen?vlEmIkKI{j^2@1NA8d%Jt z|Fo$bZg^bW`6yhBNY&Q36w?t1! zic92%v_es6wN#nGsm?71yco$h2Me$m$pY1hq<>z6Q>dJ^f>)D>Np1TH2+Zx*wvSR7 z?XAAJY~BXx*r;borUc#5F9-4maTZoQ8~PeAkgQ37mb3aDIv7XJ0}7!m3t|J6#e<#T z{$gFsxRNZ!ls>|MBZ*5+m5HN75EVeIO{*v62`4y~RIx_EJ_%`{_ljL(h|XrVIWvkm zF)KE!K7CQxwZ$odNNb#!sYe1IZ#PjdK-U9lTce!zd9f{(aS|Ed2aS?`I3r&kAi9DF zdyrB=3-KzOk_Iz^F)OudEU90LxT5^^-b-*jfNeWk$~wjheb}QQQ#OO-U=S_1Hl!j` zfn?>tHy4=JLFZh7)mO5j0$7zty-D8Xi$_g!0s@qgdM1Gay7L7Q*^i)5tdI-s8@|xE z4N(RvIW$`o)=aYiF15VEQ(*8+wsV3%(K2AqZUPADSiMoj$#3^6%do-Z?t$X3E|^3Q zv?DT|*FA{qk;y5+g+-b@c0EcE%|iLKMO2dZLF-`pw8Eh3wz5?z3qC&#H4B5nIxPJsF7g2~n=|6|-z3zt<5}e4UF- zc{9Cx@ECYG6ZRj?W+_UOw6zxmsiyTMrrm&2O; zumP1bK+3OB77{%?>wNtJ5ky9Kkeyyk3;U`q;A5Q5xht!YsWgN>9@OBsAE-UYOmpAF|Z*e3FIa?7}=H&7+`m6KD32& zBsq|^%Gf!qxb#@iPM+9gzquA@s!mLT<`&Vdk?){?;;`jTsg}y05vj(<1(r`x9M%L*K;X_{*eWE;8;vSq%Z9E>USw1B| zpVm$?_(!?1MQpBc$3c`P)aYk7aZ3YRB9h;M*W92VF>%f)w#B^FGf@<^IP-x63rKkdyc&ht^(hd552d@emUevt!Dw^M=LvOOx zInlDF@n7-+QdyfKn6sC5k4@Y!!COcWk~amHO+UC)*Fg8Z~2=u)hc^|_RT{63)cUtCoqk(ZV0_s8 zcFp}G+(`wkR5K?;sOF#I7?p9gz38|>M<(0JhN!$bf6T?lxzI!oxkSTFJ63<5SQ+$8C}{`FEdvOp;3EVDARfHxV|nA+I_ZceC$-M-Di3*THG zaR_;TKs~cg;Ky4&Sbr%5EK9}Sa*PXdYmziE_FU{b9U}ZAHUQnN2MKHLV!c$Dwpf&6 ztD-#|9)}m?5a8W}_VX>aSkr9zBHztBVJMS#{WXREKna=p6;lQ&X)t2;Z(e)zmOVN$ zFwW;Jxvnr`>|aPp6y?-#mkvc@RKjgi^orvo@fHnDFC%i9E|eh8OTGEH4Ke(y5ax1g z>-v>4?4na_@^@6#O}9yR3}*pzOQfpTTbXrpic7K9ao(bR;QN)1jxR~Y@haO|5+9H% zh!aPLXZm5*NorH>-W_?Z8~l=Kp1H2?)rp&v1)BwcNM%?9bl7Ma_YFj!-%q-?W*g~t zs&ng|1=?5w^T6x$?VbAGy$2-dp%HD-(!X?~t3Ug!53bg}{y>Lg5*Ph1Jm|ljKUSvy z;Xy3_i}T0we|7%i{}T{Ke@BG&Ki?MkkMpO6QifbAVayUyO<#>#6y-+B>9wJ?srCCY z12aBI2=Dn)v%;7;!T__VgXhGN{R-pR%ZDD#gZ?J}bDN}Yj_-dno7c^aeEJLb%g6os zA+r$h_?1UqJHzh@5nL3KOBzKni_ga^tv~rlG2=TYU3UtvpX2NK_8h9wq&WXR=xk#} zXvD)4R>GiYNeypr{mRN#jIx7ULl?4VphuVFACpaG*4vu%|GCt-7bM6B2@h7z7tyyM|(q0Z@BM z;$I<*kQ&dg{-ZNNswG|Ox>U!2Beg!_9?^$Tu*hO)=ck&LhAv)7L-^V7qPKj~x$*Vr z(094vBP5F-8#1WjZEy8xYpYi~-4suNRe|gVxszhc!&QZnEH;?8W&zw5V}u(^0R85F z?MlWgkW2YQ*aUs9p%U>ICp5CZ-+(}(`|S(@)3Og0JHae*W*Q8W9#$rb~gFm zE^>bhSe-^Mua_%WIVzgndUmprzJzD>rt~hm0g11O6a6pqX){1=r+1z~s{nDY%{i(= zB}XhpJ_2llnN6{9G-J9C*^*B$n>d8}SgKkoCEihUj!A^6$mCqAPh3iT;A=C%BUy>Ze~ug1_hj?ET)(hn8Y=ni&?-7j?em>CMXdkZ=ZMF{ujkF5nz5u zytc$N-N=QPkjwx>{epB5ccRvx%j_~HtVcrgW@e$nm>n9i9Pc?y2e7evp#Teb>sfGz zssw1FQQ$SgwxDsJrwg`!W82LyiO>x)#k)%CTNtK(}R@C`kc~5+dOoRS>1hoa{>BnV-;rEQzu7x=V#l=_q#f^Qw$Wr-ua*GTd|iF<2@BX6Q^mLNQzVlV z4^o&Uc%|1y@V(M?(&)xONM&N9W^tDb+fNOsl7FO#(Mp*n*Ylxx_b3c=8X@t~Na_>2 zRiT5B_?WaCHrIA*7Yz!%;nH8dH1bN06hdEnCIFXb(d!+QK{bL!x++ z<*@X1@QDZZlR#P<2=nrw1~BA;jJci4w-l>A$OZ*_r8n0ap^kWc-ehh6U_}TJ5gQgd zsJ268jbZ~4w6yEUrVye4naEkVu+xq9xAy?UWcU5sLKRGON-77*tWGBudacY7^Lb|_ z?zOMXSeC3*z2UL&B~=)}yFQd#Wn8FLiq*6>mOF$yk!_Jora?l|2tBV`!6yVp5`j7$ zVu#f(Dh8bpB`Jh>IN~-EwDlDh%SPqcL=vKzqw>;W$N~Z`WdEbYF0-%zwk}6i#2fh6 z+7^5(eUVcF6n(dJ+=$O^V-%KagotC2+El|Lajz8*)$eMFKVO~~?-Tx98Qpwi9pHt< zy+nF8oO^L5=$>F|cIIhz=HDCY@a_TE{DS;B>gQ+)POxCX!UqbnIB=8SijRbTsKHw9mL zODB&%%t}8tebM_cQ*a(SSyN_jQNZmp-i?z0O3*Aw+*yB_`f8@{k}Bwd`8rhY$yfE! zkX2gGYOyxw_iQR-KMDYOj20|wO_F1VYF>bha{UtiA7$?lBudzz>6UHVwr$(CZTpmM+qP}nRi|tlr>v>J=SI(BdNFsG5t$LW z$VGnf>R~st9v=lcfmd0j6DEd#fV7r#OmPw{-#h`E+&( z$dnID>ZuFu?~#E-OYWZtEe!^u#``SjgI5j&rTb%~e9(&qSdZ-?eYy(P75CZhAMt5mfn?h=*2&E$rk|3QxCR4@Ne)7!M0gHn~AqDYb{`~ zI3xTe5|;sSpuMvbqwHgl)n{#8bJP%}xDI`<*Fp8?PYJG)pn4w6F`_tAngYBwP5(wi z0Zp~-0q^oSA}Sb$x1_pldIR{FVPO#SNfrz6olFw?hFPCQtd$m@eA6$Pp|2nr*+$r3 z#^OOqLMR4)PW}n=~u(hP4P=5Y{?ev31 z7=3#wN;xS6z1{-F(XutO!mjP;Wg{s1Xh#+UWS%3f& zz@Oc^7ScnI1J@IPGOaZxCv3oB;g9HhX7gg-=In*Z>*T3_R+kHb@`X6KmTvNm8Y_5& z_LJGY6cLrz4W~5pU@F1RJ16u8DA^I+u()&q_tu-oxddBjKf4cDa#M7hAY)%R{;Oo+u~?Pziv zHpT|D9V&GGqXlz5a;*erRn409o(>?KB!O3i%(2hwogHulzApGkP3Zfj^t^O85rs4pw1Z) z%vwDG37BjOfx>OW+jwxQZ(H4$wbUBUIY|Z;??ef$kHkC@GXsYNYhg=KB&9KdEhU^N z5cSa^Lj1|>xYRB!XWP;GGvU*Ai@08f>XJJ#= zE7^mL4C8?Kh1w%mSai(V1lyKjoSt!LZ|kuI6EcEpNsbOxGtr8Bb7OX@S48wzIzYn@ z5`aH4q?V_M-DddPO|c*`Nj^m>0gNrIE`u$szFRHRm9IIAjdEvywcfS1F`LUsUSj!w zjbIhKjxy67m~C|`;t>gii59WmWF^jBMz^i4G0XfG3P(p;3vLlU8@}}YTdCwYD&`0Y zFm`5P%3-U>(a9Goo|S4Hbwp&W)pYC5ziCWGD$8QP94cR8$Wc)(K1NaZr!{2PIJv9s zM!Q&Y;yTUGmUVer74LCKJp!+upxn4iN~=c?B@T7^Rkd(^J14f3_v3&`!VPQH%n+we zBQleK{nOQnTDw<5NVtANy%jAMg3KXV_>icDo-g8N=ikjv%1X533Mh6s^9gFB*`Bfy zkOSpBWEyla*$8ulEJ&v=xM8BIp67LqNT7;Gd zGFRji0zN32>2s@wXy{XH>Qv=!BprqtLt8w~Csdt^6*eSWi6{6}I<|(zb4S;$0&uXc z2L((a4n#9m*ucp?k>*zjn@N&9<3mEWl?dNR$i~}Nt)sT@c1<(2n16lFCMfmR0(Jr( z3712&ih+|PNeF%BJf#=*vDn za-72{?gpJ@oN_$1Du!^EX_;!uuFfDUJ}QAX3CNwvE$ac7OibeKS%S^Zgo5TjL_N7@q>m;(+Qq|? zW9+&N%}&uME7_42saEA&M6=#c3cN+C6_uI5WE?#Ho zUKPT^1!JqAsRannXp&l1*t{kYqYOZINQ<3U@j4~5>-6==!D8gj4EfS;ys(;#Ar1pD zqGCU<9+p?P3JE39z!-{touazMX~kDDedq5BQhxLG6^>C(e|m4H0K5F?C8rS$?Sr-g zWdQu`21-@re}+~oDbpY+&IOp<6sMC}MJ*)rmd6NW!sd$VJH3*3!3^#AUjalwaXrr5 ze{a@I*AwNCqY{cfC8#+bP~72CikVRj!>j?L^xEEe;UK-WCuTw1vjYrg50+UvX2 zOa`U#mn}VwNU30=fzk8gZKt z07r>4zo=oF7Y<4Mxy;v;JOFjH+iiK6#~zApoY0q%pmZU>i9w@z!1^|PtF9} zX+8YWe`YY6I<5>c;zf)iQa|PFAm!+m`b(-m)mF-N%g#T258Dj%u@i4wEcPB zV+m8I2G_TxH;j_6k6$$r$5aD{oOH)9nX#K2JjwlmsKv$&Q9|?kWE42K`@{zdF#d+f zKR6nfOs}k~b1M4(CT4p`qQNl#rb=N`7TB^4LR5&H;YMM>%V&{IPhp;L!QY2656QGN zYf;PlMHy}OY7d&5*PE~c`INk8MiE`I7};Wfxx4r`x!|^SX>8OqQ9Gcq=w%M#(0HiW zo}-EHgeJXNx=%crTSjOkrWUbNJFqT+(c{m(1?2WC{K5$={B2gflM3eD=5`9dkFo$u-$S z&%j=|vcWNqZh~H7ui07%BY4-cD7PE4gy8;Q;dYHi)q zE9}gU>diMGAY&(cdDWGqQe2nNKEnIX*Tu=|(Y3W3Dg zi19NhdWiv=%84$^@wm$d7U*vE;S3K+2;!x~Ijtay-0MTc(@MP;5mdIOM^e?6dFol0 z18Z?-%*KcQEJRe+9NQ^V{Bd+*|>q07@S!cZZO7%Q+pRXeQ8!0s95kIijXE zsf#httK4ExkB{JU0aCj8%x@jiNF5bPl=PpaevnWg975%wJWZIYtaWlhNJOc!6GD~N zj17;==FSp9`0&9nkIa~7!Q<>=bWPm=%%~)zy7okpg*JOY%pjhiyL{maynZ$O%~P)C zfReS;YSC6Ownn}gEx6mO$UYkytA|6qH@!A@HCfJ%u~F)!o{B*a2fV|$M^sk(z1v1c zST$3tc`pC$-BHxF-4sPF~1-3h^2t4PKd20DG$3q$-s&o#=S!kCP zq!09bBAKT;00#Qo`sJnQj?gp^mWz4I5^$0+?_q{7N;~RQ^#RM zNw~gxb)Hk3+z&*Af!Mq+>z$sMl`r$$4L{*xmX43W3Leh^XT8DmE8VVamYy8;ZCo71 z+{L)0sLGFokJ!Pe;W&IdnfLr5H;HYJL61~AKyKBpp+pMu$7tYSph=qazVP z-%B7vjq!TpPtiqK_wq>t$i+3(SONM{nH#~JhZEt} zD3`T#(fa(q_$qV3uTT5rduL?xx%;-rCe~-&e7P%sLkXL`9GY@kAEP?KqMD!F&~s() zdX#~gZ&fY_8e5CanAB}?_fj$~+(&Z~aSw5NVOL32n&A|_Gaq^{u~Gd>sb5!0`8XF# z=iQQYFM~8M?)X!R#O#5C*is96QJ&}-MxJ~0pP}xa>ff9=o)0&=pJw(;*z*3K^wrKN zCNO39b!jb5U9P&Ct9iyUM#_=}4;F8}{nZ3#X z8?BLt)Cz;^-%F{x+%SRn^VQChe_bP{_&eh1`T-o&$u<^;Sr&30Fz{l1dv}@uq=z`j zL&w*6e(OLWoHOC@OUf*=rE}c<7BU8sO+I?)?2@;BjM|KUkhJwvOLz#|__*Bo{Bi(m z9lo`C>=WOM&Rf+BL@52(F7R9@LG>L^az1x)WZl{yox1qMmG6m4kFsEY8r9I?fqzZW zcj9O$tb)PsC2juclq?v2$0!=ky!N0wA9NZX!yr9FGyR*}!wxjYKU_)rt$-v~KmJc( zj~qhOEM~6URuSfbU3ASJ?ThaThzKK_EqKHWt_&Dk{qmzfq7E+@Y+j0iQm9rCoQl98 zF~A|WRMesZ6NumUAHX60+&4Nk?5^PdZG!xlweerLWM&4=|Awxx{12g6mjAz@*cVU&>}Q;y3qLjCIh zLM4~vg^_#T?zU8gm3iAdxxfB6+>YSE!>XN+?N3|`0b2}nF3aS4_HudDqxYRq&#A3W zOq{O_OzgB>#yzi-q}+|x;u|V5oqWCHp=3M=S@rtqRn66pb2gdz{`oURMpzOAuYY4- ztTG>?kNvQp_slL;G2z_N3%wG^NwIK?XW;&eO8&UXpYCvKt@xuw?j%tunRE;P-B1RS zmyTY)8bqv-M}U0L5>3m#DEkXs*`VO({10%&_WuA^-Z9T9W`m(`R?9T5yHDiA9vDuG zts!1r^xGx9Xf1+nFDW?EUT&ef4tyT8!nOlDAk(vFr(UU%<~i+;-Ve1tOVLbezZIhL zp7S*8Uf=bHT8o?Ht?qY=0uH0KzXMshMwhLA*};a#o;&q2X2q@oRdGY~XlI4AFyJ!8 zWG3C@AA@po7j9j14FTCK=n3O^T?vj$P@ZS*fh?V&sgYtZIk z+1Z-&Qt=VsVP#Ej21}hSwEgZW?SgJ*33L;jOWAyB8;3lWa9-ysWW)56d@u(oeEch4 z*vERer^np+#G#wI=ohSZH&-B5u#+>Xnfo2~sL3{6Ewx^u%?R%ZUYWu6^1#iGw2 z4e=$sk{&xbBu!ux`N{cK?~9G65Z!o!#C$-=H&Tfyk~%@(Gk^;f>93~Zu&odiu#wQq z2^KFUOYc6kIc}ylpoN6Dt}mgW1gUL^F|xg%Vr5+=#XJ!wCk?Qc2o**o;hf4GphNFE zs{SX&irqrxl17U#i@0HV2w4C0Xm+xU=a=q!!4F+SDyn(pc9>aNFpx(AF0#lH_$HJ? z4;&RHR3j@}`9MLiNlMf#;;xP(YYNL@os2ou-$rbIC+$mE1i%{>P~IpY=KPB)Ilg15 z%f5I+17hxMZ0rNm3_jnd;~!wLMW@nCG?8$;k{cE2|00x7$W5Y+1uFgUB!`I1ymcd4 zk}su>w&t8Fb8%ME##-5CmZJ)>uKtsqscg>G3hJ6rvFJ&un@7AKO*cbb#I2LG!Uft~o-*Ep9#kAB+Vd!%ow~{1S7?()dt38vA}?Hezy?p zpHvSUp#81Q3AOIA$iZ1Ohgcd0ppl%MmR|{KS@yZC%ReZA>ls-1?7-;4!fH_rky%e4 zR7TjS7#7D+BWgpZSmT$L2qlb(TCUz)22m*C!PHZQ2GriB*Pl4*Rh3SElrx?G(yW=F z_@^yVijRHjdGi~=uTr{ZAMwO$TU(Wz1&kEy&7bh@s()TAqOe=u;uFBnr%@A$gt6u!I{#!-eSU zucNLaU`37#jKK4;)Y_9E2r}AN7rrI$G6ci^_{&ziXt7w;WiAB(!kbo#pL1|)wpcYS z0-0DFJ?w7A0?Vc#h%8KZ!4fWYnH)6{@FYTp56ZaejWyxlNKGA1h!90BEJSqhPw5yh z_O@FEnGy3zRu4YO8L1oiL(mqhwmgTtOVD15fmWnORof89ZD4j8Y=o2@@iZJt?K5DJ4ysB1FZod#xgVBMT{(IeHNhMFCQFg`S99&bfev_ z984L)o40uAMHXR95)P9{4U4uOX%=S%VWcfqR@VQ35!*7&1b$oX^PK^>^yxL8z96@0 z39`N>suk(kIMJ4flLq;EP$$`AzFTajHpnj}_P-{11YFQG;-hoKuJLqCB7{LNfEEC& zn(<;-QvIm3n#tfFCpvtE-xmY9lDVDoaGF#v?VFqXYMTS2aawidjKK`E&Z7O;S5CzO zq6-)OPTWsoQR1qHl+2@h(_Itp(-rKyUsS80Nvb% zd!PZBiiid%(GIj|aa7z77=YKm^c_PS zQ|}=j)coy3su+6_@5sOd?InG*SSJFU_sSG?$mJb)%v&=OHk87*(W!J!PF8HKR(X$6 zop1&!?&(&ml8&Lm;{tjy?24_JPj>n<~#1)KZ9JVq{$-%IW!HZI2eL9cQ-7N3_i^&MxfH z?F_F#9DH!WT?VGD?u^;hUd7Msz=lOaMUmEMrK+|oiCF2W2}NPZCdzB*Eqk+hq>~a0 zZvh%pU<2fAW?uOmI$~Ny6!WYLAqvRrqCtidr=iY#cJuy(JdC5=Oi(@hPsKosMMF#bt`@R4`Jg;w!ij&J4!5OEH`W4?0 zX6@iy8ta&{L5F#^SWB_Pik3LLhH)r@cA+CdR3|+TkWRT+(J{7LEw-Tt{Ydih4b%m1 zx6a|B`68H6uLIT+yo_h#ojIX`TI zH5HVK&27pZ$Pw9KVy8RhQiLZw6X>pFdpns!Q?nj@u4*jDhiQpu$johuYqoLrbhcuT z;`bNH!X9q$K(+e;&c2jl@o#+50)BUnlO>`&cuxHQ5XqldQKu~2+=Kmf(-sb zQ$AyLn|W`_d6#K1mRzKGU};D2dV3XWXlbYr>S(Ou4OM|!c|M4*Kf_j_!D`GSo1nD9 z*${{0XCTdAm1-V^NX7U>suDC*)0<&JOh#iE#ggG^FcAFNu{a#5zt7#+Itsj9-w@M+ ztdmV2#E1)i^4#E0^Eyr;#Kh;tUQMtDT#B~)?fI1a754{F zkglL5fs|#sQhEh&z;OI?O7xr)0O@p*vW9p+L|EkvOT~Kn%m=GF= zwZUa|KGb2av{*I~B&PBuy)f%xB)d>n+My|#;UAzs5_f_~F>Xd0lWF5<5)tKw=e&^^ zl`(cV6tv?Hng_@&$!76LfW%K)b0o~|OH^h=nUI!0fdZe*ZT0dR@aGX|FyUn+#nYS! z#Je8U%U=bHa>vgsa6=vTU)dVguZi7h=PmxbnmRS;=}%e=y`FFmk}IR5IyA%-pw(D| zWZFn-x(=p)Xi{{)wK3FVyl1SNDiOK3#{Qa^)x;BdkfJ<&$Q!wrC#E)%8-wNN6{itL z`^VOUG=|9-FjB4`Jkpx1eISz(wIc#bXZRRrXyd^H&RclMB_=9Id)RN>Cj1qO8!x0{;GojgMMLALH5GdnND z^rAB#gpvGjjCAiahYG^Dj4q6i;otN}tefG9@7TrKs7C~*hzlqAkG+6m@$w%7^-h&3aZ<!1Hg}@5crX*shO~ZaQTnR~;w=(%HhtGs>$34nBGeFj z0sP;;(j^@TVqC(}YSF5jyUPy10(4&pUR9 zX}1ss`bVjAT68AHep92|jrZU!uXDR-*ybbB>mCSNGdCH<^HP&p1}4i(LFHvkOuh++ zQqeRMi4&JNZPA}(8IOy4f~yTPL9~x!UQ{3%atUS=K9IAN=2rI0Q63*wZq)AIh)Xg% zYV`~^?qhAHLgt%!i+hQ`A%E+mg5fsPR3;!xa>#y^?&CHPtxCAdh|?XsxDYiV4|dDA zu^qfy%}gcd5M%pky_U6sVD){!r3k9~g$!(Y6-Q9t_5u-9s#)xP&a(sCwh(lH7ELz- zPp?z13@SaW?mI}IC2|`9VA~2Bg0-svQAi?hFgCIx+fB_qZ%l zMh^1%eY0Pqc)N;Fia*C=?no^4mxtVvDcvDs?g;tFk7Mrs28&a;_`8r2?K{u0kh6K$ z@2_(0Xnz(Cxzk0fcRmlf4XsFapwudr2Q_%uaCrIHgD4Bq<0=a_@9c} z5B-!9Ullt}CjC%c{N;JK-WA*YmSg=;*z;d{$oy1lJ38?}d1bV+*b^VHDgJP6#8owJ zt|kMMBzF8|k!;F$dV<}ux$@A@qjMfcZ74X%aJj-2Q=WJ|px3D{vu|;kD z@9Q>qEBhNc+lhyL53{t<>__KJ| zLIk4);T@M7)^8T%J~L->)`O|Df_ezRg=X z$E8`caM8|LO-#?$W}$Nb))nBXzG>hM0X@s+1&?Ns4(?2G@6vt!XsM|@K6IH^e9sHVTaNx!r#tOL_N~XHTu`v&Fo9PlCc@Rd;4K_ zcm|*?vDox%zAz;a4h(M@H^1D4)67TyRDLUn126~#s$_xnP9uSyC>yH4ZIKqN0X9b{ z9{3)lIrzZMDX;J*_|Zj9_203c)?a(-m1Cv`a|5^-TH{91wfNT*JXCWX4AZy*&ya{i z9)WCHN6JoJ!B0K$w8V4g^leO3-iJ6IB$8`Tqwg>t9z>(hAb{b(6w#{wyT$_oj4mqF z!eAs&ZVEZ*2!f^}k~eV&jkdA6iIYE`JumWzxtBJ;1sFVS3En@$n-vt#IS&riAFA7y z-wPPxIb(#oCBP(v!7g!^FY#U3hVLGtjg$tK412(oQgRj%WetdsD50Zc&9TrLkCu%c zY`va<27cJ4#@W;Ck8kso7)~ec{HI}Znr-pj^tYY0VXMIe-4w(bj?j7@|G7-RBw?N| zRvED!xa`eW%to?je?M#eq3xBlUnOv`$01*-o9DW-N zA;)U~X+{%MdVqX>tH`hSV@ZesD6iwqT|YQy!Qr$0EzOY8z;x|XoL;}C9ntEWA$*(5 z$~)a4)Z&lOm0wTOhvH};2y=A3{|nm<5kqNVQpB~#GeOB;Nj<_#XZ~O;f+Cn|_)&{~ zqP#x}^^JHwWI#kmvt=qu*LRf_c+Hjp=YNzecX6I~U zx&*SAS^RKpFs*)lC>@xPLb!duJCZgA_7eYPvCnIU)fWYLtn+sS@q!1 zqz~yqAsuvWrS{Ja_6;J2!c*W50@VtzpZrrxrh|S>mJ~i&+u`{gg6`H$U1& zMc7Wlz~sRB_(k4jp@_cH2y_5KAy!f36xiYJj9#%(N>|P5bYroi5xTqTgs}Vflt2gv zNHU=!&Zbs6F#tjk`q)@hHu8pB;QbF;+0eZ8GCw?MK%)0x0w+ZCdT3-(%<)plpg0$X z7bNX~N55_+^^VQ#okNcE-Jx1x20bR;z_iuIkPmg&uuf zXX+=Pq?NoGTk>5+UJF|KZI^uf4#TNt#&s&^NBk&f=GAQhBgB-bh+P&%(_TSQ_6zoB z6b>bSFv7sUQsNLHhz&LhmQHIz&5Ff?A4B0p(-##oT`#U9SMWyHa)$-II-c{2o=!7| z_YG7kk%cBjM!hK)$4pgNJh=Kk96ygOys=G#?pg{!OqzrYNkJL`(e+R+9Q+`p?Yi)P zv_|#Ud1++*cpEo|vWh^F=4uA4;^g}vo7jTl_@{ttWFu^OpNz~F$8*4NN*jisYzlHu zKRbk5(&VowBTT9=bVo2OyK&(+q77USj#Q!@_B_|elE~+1x{#xI z(f*Nwh~Q70WbbMEuenRS>UyX&jQ}QDuJy&^m4OQ%k`vcivsvT$)n|Bt_WPf!?jgb~ z!7RfF8_dgTR)v4yxvq(6d0$bn^Ng&~HCW5g{WNKd>w_P}M+1=&`323Z=9UuW)C0{k zlGy3qT5jtibi@PJH{;vrF@-cd5V9P>C8KNKpZIujR6X3>W2TzC$hSicfd2CAS&cE} z{?&sKn$V+SRssZ00R-tEuw!Pr$auSB)Z&gAjwieboZ_xgmHCAUTVwH~UbPhQq>VL8 zj^Jd2+wIcL4%siK9QSgN)7)*c@O>6Ws5e>RxouqXe1T$yTii1CEk`fsO50%2CVN7j}D29$7qdUvx z9AjPZ01N}$Yx2~`XonNzTU&ksBF>WB8{Cx4-iyY$ddYQUdn&Gi4HwWLu|E zZg&LQ@_#orr0`&Utgm!Y7vOd~Tny3Q<)}}q{uq+`TvwJiHmsR@$82$3WdnIMD-_Ry z;E6g(EsLW56?R{VGJ`1tOG1fmwvvm%=us$fbrMi&UPUPjQUv5pLH=F;f#k;ks;E$= zNC1vAJ3c-g?jc|MrBKsU)EXnY#Diam6*d<4B%B1-Js)UXdtj@)<&Q{3{hmxRpF2Sc zicF}~Dp2>+^Td>QEacDB5E99}F{Hg0p~3L;_`)wwCe;?m0}c9!qEN2SP*)v_43nt& z-F2?er2znmwq-i=QcR7RF*9KmW!+IxY+`HV?D%o@W}m>U`vG>LLx;1Hvx1Q8mz`Cv!?$X4OxsoIkRa<&|N$%j&44- za6?%e;jWb(`L{*kiNRe>MBR`A|EJH+xCyNBl%VmCSLITPEUmaE9l92|ErHzOA|-Q{ z>tDRDrimg@WzY0j418_HO3`G+%U?|Fk>lIXrSy;3sSLxN6>&$;i*+J8^GuDR-Ld1_ z!-vh$V-&Pn*4QcKIW$L3(2)I;oam{h_R#jv*~Ll6Hwi6!VV&>i?m$7;?ajYdeI<1U zQq0#hBhD#-IaLH+hMrR9uQMtE3Ckbd|85Q&qz!$xMv{)9dcsVvT&3ArB}I=u10QvP8u}iT-4bL5y5cA zBtce`lVo;j&G=!&YYx|Zu0<`voi6E>QBFhH8ksqpA42qG1!BS5*gJCbAA}EBO9LtB zxUF&@rBn_*_1~FloEblfLR;rcIwjXi|WI|6QfSJ zM)vpIITC??V;0t55Uw||I7?|qdtx2qai;<0TE1?6jtu^2h1f(cl(`U=P76;$@0JBW z)l1&tr`46hf$&Ja_z!4>!?V;UL=Rr&PcNJzuJS94L`I&)_~!c08lsou?9@Bm{Gm0T zZ;#0f_c|8>VDxQEoM6S`vYG1X=8(ZY#Hd55^i9t6@I}Ti5i{CXyugj1m439@o_v;K z<}+Z`+JMEYf43o-GkX^XIX@u_l!gMFuY4%CCxdZ+Y9vG(qkaMJkza{Te}Id@Y#8hm=TZk&>!_dD=7L(J0CTrZGbh@v)`nBdkpP`C4sp1~yu#cx?WId>G z^>Kmll@hDXrklo&D{$H2zRGkQ(q*V=;Hu{Wd5E6BgxbAj6Y&)&j8_b}xo%g@PNyJf zA>;R(*9JSR{$#FiuOoc}X*6;-k`A^!9#thVf`gSNc<2Y4Cf?a%)bCkZ`jUf%y1B%V zkPEf&bNlzC`bFlOs0pGWpw6VX?i}7{s2=kwWO?7jYpN1fKA{i{O1^z*f6{G{fihCC z(iozJVLA|~7PJ}y09;%g+y4V;zAZ!%g@;7yHVI$p4%ji85CD|%=sEFg4y{oy(@3W@ z6-TN|vp1ltxO;%bA;`9E@-g1qV`xkD^ub_Lt?t1L3cx9OaF74XK@D4J7%<0`oZ(Y` z`v+@bS9H$=hc7?#5^aKVjhGkeUhMXr?ofk#TV)aI3qZjr(^~7aG1H>Wu#b``;H_Ut zR*WdjQLvZc^g9pxwZal&xf336lwIk~Tx2vm+HZuc;&bf#4RlRb5nM>z5xxWIOsJJ^ zDy~nCg6xlDx&H2;AtI1BeHP~l9-PHl(H7@BDjlniYa4Oiv)Il*u|n#o(++1BXhubl zApvEQ?OFtL$OPhrY<8HcaxoaW)F>sJF~YUfY3`dIupE-UKGPCTPXKN0 z&2D^tb+~@kA6vaN%Fv1|9Yb|r%rIx#F>U%rrF`$+q%BS!x4@+o@-9xd~bS}lms zlS{k?Jcxlmz~u9U)GT+IUt_oK-{4TZsP+H1?D1b>#(&X7nOOc0O_cS2NP@8bza>F* zwe5BOGmrL89Ng=o>LKsZS9~Un3?drUDu_!6ivS)z-$gwk z347EJG04yj6Sk|vY5q0DnDxpy#DBhPt}dR((>#XGE`Ie|cQ-e(058r1!y)&>)y4IF zh4Kp&f4Rn2-G@5OTOwRb8XSU>}!=ZM2d_-3Wszjy3Y?g$jRqw=%dxxjkm|Y7)QUg&o z_Y>bWomghtc0-)-lGn&N8okq_s~umR`rQttNdlOkQ&u@-&e2cbH5+}GG5+aqUfn-y z>!^d$X^HkUf?Z*9%Lh=KjvUTH1F#k73c>#k%Q_5jx(4evfQ?}wVtc;D5(X^Or5aQN z5XDV1({y9Re|%EqgO}p1Y4>euSxaRnx7BI8}Ai zJk^Og`&igD*yGsY1w>8vM^lH5b7IA#uKn}RzLPqY^GX^u-EHVp){Rk&E!=5GjIEyQ zo;{{D`!*m6h37V|L(W_ibaYkG@B4`X4!669o&+6155s^CFOX^ty5TY0k0*tbjxZ$^ zoRa1qyQ?s7ElSn%{__O*A#M^!m6^`KYe0W{<~eHg3*e!+LU5}XEj7?>NdE_VK@FFK z=$Kj~p$@haM zHFENqSDH$DITrERy)O$kz+N7ItEkEGATfVtL2XAn;O2rEUIxGwxY+xxa*DNS%Tf{j zw~Ps{4hrzeEc7Ftx+b&>yix=Do0o2ov`EmzE+&IX1r^Q5|Xk#`c6b{AuRWPGzwoq|aK%^Pq1PGHP-K5=28Ps}1qu=-*5*1kSrNMh*K6zy-B}FDF33vnc=FpYzAc z{b=~8^F5B8OK6###9q$hy&^~&$66Y@bYpo@w?Hk!6*ndam^Wx&B8k+=$1kASoBmsQ zO9B%FG7XJ1rnCt#)0}kN2(#25zm(Abq?;Dt?Huj~S5FRAPw0t778ac2p93-xH6=#DJ|Db97D+boauS=%Y{5}jFU)76NKo-b z*p^1YT5%pm>`9*^oQDb~3&#Q7RXz|^YD;OQG?|Yw{IvlepUwiTZ1d5?K(5)Eiv9_f zvk-E0=lbu5%nAH0uJ0xIYMCBjTI>qw^-&7g-jsA=RjXaZHfW~E#;PQRUjUjK`3``P zK%t?|M3;4p6)Z7)~`m-jA~Ls26T?yXaC6 z@G3S!?<*tHC^A^AROBB&X?RVF3dI1imF0tWU?P@cT#clXoaGRgOJ?UG!19iZ`AyJP zG?uWY?uCOnckVZE%hJ*g2@9q_TwnYuiZoNKW=L%)ph{!K;stkfs!kCP);r!$OUR$& zgh=UVM{>nnG5MTq@Ic&zvEWt&a(=!r)`%KwUe>@u-Od}N@Z(0L#}U^K#GG=Fsm>jD zq~YLlW5q0vb2jx)bW6cO8S9=Pel>vD%uDQ+3OD$#jkdvNaIm4?0}nvnNR6&}2IuXR zRyP7MFRNOb2+j_%DAw0N5K#EISs7TXyAGw$pe9-g zvQgGrQbOxdk9wB3pdPQf*SKyQcDeB+{*Cyg*{!aR$K-}XKo1Qk_FP_)FY+QFk~Vb; ztA=y|D;kFp>onaLg&`t&k`wD_$wIyL`?6$pj^HaEL{$e@Aw@7sd#s+Y zVr7C24TVX7h51o}M>lLi4W=IhkcgaJ_kvQ$q<>HaZA*mo;|O{4O6a6P!94vF0&S_L z2t_hD_k7SNxtAOY_e;##_;_gtGZO}pZB$OnnVr52AX62S-zY!24))}9e_*SvnxvWf z-eTOT5ALek+BSoTrxA_>7Uxz@7wmkNcMNU~ah!BPQm^s7N?%%fbW_pO&eQa&1JUf1 z@&OeJv0))|ih%V!@Ya4QmM|8hYR6zsu2kS?oLDWjLtJM1g7srwlDmRROwI5v9=V&) zJiaBb!Wca*ItJk@scWq*caLUFaV=Ssk7sbg@o`=H)n3Sixg@dPi}C_APZ@*kd+Pof z#@1Bjq2wTc7wKc+es-VX)OQl0OK&f|kjnv4+uWs>pjZrzu@NdQ1^OWi?Wg0z zO(tYO41U-K;hbJ-lFV*Loj*OncNm#Q0aphYJYm4yD>tCT?4)&|dJ0VI+P`N7&B_D! z1T-#MiYfLygJmo-sWb-30KqphW4CaoJn)XpOpY~^GEhl8NNt8_%#ekfhsch{aUs5X zV3K*^rXT=+d4Q#pOhoKr3iup?>kgoN);(MH&%Dv!arH^oIr)mz378WB z5a9Jb(^A$gWOPv~GH7S{JZr!o<(MbV>3=+~MMWDcr&wDu>?)@{6z+-;XP%zuiOAd| zNZ|Ab<{1^kb)J|O-NS6ksGv5iW33N64hAEIKLxiHu$-HOcb8@ zB6rMLG8&Z%Jv9a6%;{Qnay7Fy=ouhPZ%}U6)+?l9cSZgVPT&%OHW?Jn{4d7dsXMc% z(YB6l+jjEAw(X>1+qP}nwrxA9*tX3|>eRcx_U&_V_Qn1M>t?MvTN|s7(TgQacCW&jPDvF`8M~SVX z=hLgtx>r?#21NI_Qr8t+-=`XxFkN6NL*eS!@I&uOJnh^~-CN6=!E|o2s}IuUmlH z#JW=}DuvoRu!Bqk)q+w-$rwy@CvJmh9R`#iD>*bk$^MB(T&@&JMNF(2;DTJ!??AGA zs(i*O0rdgec72XDQ_CrH^-tWUN&3vmq0caD2R7HRy9H06^w1&rfpnrdao$^L@*Zr) zOA}9}Blz*D(Np>M%3qN|nIm>_x)iivi^OSYfA&FN%QYv=A}|3d3QWOklKF}=L0|-i zViu_qyDlhkag|H;uQROC+cLjvY!aPn{DL&4o9-T5#^hh%;pV-Wc!saQa~_qe2Iz(f zDYjBV0jd3b0ra+>w0zdpT%IeT+|3&)#bJL9o0en`7e7)wSc7)=lkKN-Kf7rar}&3JWeN~0#)+1f$7=_87>T7JnRt12ht{P;JK*-hv&T@^Wn45Lwf z^;l!)>i&YE*#t)m-+2aE>^|rz5ecEX!yvK(VQ(mj-a}kptL$E@Wf#pUL%`|Nge2xD zp*jj5=lb`~=4yDIDci6H5W_P{LC#m`C+n>X{*%ZMpI^y8H@m|DAs!;$+rd!rI zgh?5K$0R`UsC*EFm|@sqLin*(U-SJ>$2>*f{JsChUa`41;ZFNkJj3hy&%ZVL_*cK} zBf|l|&$IK5pIi~F5w7R|lyCgs9T*%01Z0uFtPfFHM{jJ+LKmDwKy>zz#^Z3ThagP3X^Ru5) z*4y+{KD;FDH2yLBE!HVILEFp4?g8XpT^UQ=mTZ5*%v}GuiqC6XTu>Y*?X0T>H>~@7 zb?wlm8_UA3gM*pTCIZ5(jfX=mQ!STdg5dy-&cBy>f;yknU+aXv{vc4c^&cN*Pmg9;?V>NOp;<)eB7v z-g9obfJ}OcsubyBjgCV*nUJT3E#q(Njuoa~$U~3Af*|+l%P#QTuVN)b%&p6khEZps zL|!@e!oMW1thuK);|~XiI{ossb!z=4{P}Am^oJ{%Af5>Dfr7a*u--Wp$2?lUDMKKH zH;-N+hW0Tbg$8&bX`XB9&f&}xS;%!37pE#b;b&#lXHDRZQ!6qo`Gw{*+#7i0oTMoR zzc(g%DmT9?BPlmz1-x}ui{FH#xM@W&b`pCeS~2uw%mM~q_@~gqe>{+cUP)<9fuD)2 zhN#d4!Ev8wX2!!^Z6M=hJ2LBxuJd?Y@Ji*^;%z7{-yM8E1Edhmssk7CSO$J6Gc-L{o%1 zK-C;opVw)TWj9jrE zVvR_ddj_z1p}G=1HH7I}^p16hb|i#+$eoi9GQ%-c=SWtY#4`>_2of9PtX2gRp0c`a zFl&&aUf&j?Pf?Ms%%t@ozCy2E^=dYgw>@JL;B7J*su54;@?rw~*r(LCjOPN?hh;>kC?Ake@tLIXf!xP;2$WY(igAR$qFM~g7`;GvS`gJ<#TJZGfE)6 zx|(ozoJ{G=FGu2_sDwz9f0WBoqmvJ%HY-8bfKuTZy#3%jCm8Y*tha|)^K%6tfoqrMkwoDL53n(r(}R6@BvEL3fPac^XeAsa#L!|-*5`V`^d1BiXF0&CT?Et0~6AGs4 z9fAnT?+0!ut|B@FkR($l5NFpqH;Uy7zDhoLN5dUWZE;e!_Zter(;@%`I4n4rJ>DH} z<&yJ-D=$iXGZUpp1k5?@}4Q!zsWPAvW>Azz&b6dDacRA*3yabI?SR$EDL2 zbps^!OLz|V9fgN@Caw=oq>zp#91k*p1Ps(SE%RKA!+*$H4J)DR%i&QhZs?Jz@M=-f zK(HEzDMSO90V1y<1Q22bmHhzRA}Fe+zs!t-&fIyCyHj@-GB3j~!$|Tn1c%_m#c7jI zk5C=!@OthGC^;`m_wgA^@{BtQwEsxKl zb2<>UD3I&Gq*Dapg31SH>fm7iLZ2e#UvK^qDDm9^5AG=*=qVkrnXxqHY`F68?WZw{ z-nS0o8p)LyxGN#7>r_$-ibuzX7XEAeLFdl2>{+qyc0~SEYqB;co|Y(S9@<%mU2Xw_ zq50ln?vw^%rT+AI6o@!Xl0!4D$4+rnsCUKXf4FAis`QTf1xEqrLbXXeb#-5z4+Ye0 zGX?tv;Ehcd^~VhAX<*=ypERF0Yw(>qWrw*!46&2FxFQU}_-#J(L0192(x12;1SFu9U z@UNosAGa_y>>K(=_j7>NDem*zgOJpIt5jLRu|-m37*+O67OR0RefefRg6<(uCC|f; zsaN(G&Rzo5i5lonM+tIQ>~Bcv5-)e=PuYpBDO$HuMXH%Vr5NP&Tjp>`!NvLUm8$kR zNn%pwOi#|Tyn&PE+!!=BcYtz4Xwzq$6xBh7GApzeonR_K29Pc-E}G+vXA5@sfZM+2 zU}x{z3z|j97b`r27Y!#;^s(`ulOukq6k{m+1>$scb)Jg07*2}C8F&RC=PebfqfWPu>QuJ3NGx*CmV!d&&H z%O_K5TAH($-wXN7Re~T_sg;?tz66L{VaO^np1C1n(_|~~se0^(4U`B_O@k9DYiJFs zziNaZnOkfJ8gBDJb4%C^VLkTUK@6`bxnFG1G@hva8_671^W7q5J@?yGXZVwP>Ky@~ zP9TNif}Bl)vea`G|EuUf?#h1<=*(;$5H3(x8Pt6Uo2S9UHz$DLzVhU5ng5p}K>XS! zUnnoGf#Cn_VgP7!J8ZP;YPGw)`-kNI7JsNCqdzjy&=1)_W+19Wt-QrE5)Z-1n zc}Tluz_y)w*`!3C`pfAgqO5xOd8P}214BJBk&H!bc)?D&DK)2=*$Mz^1|_1(v7Dz>`LC9I&J0-g=szS%&)n#>AlJ?-?ZbB_Em< z{D_Wkq8(?XZ4gdj>!~~1SrL&nO%=TUZ(a6ecTV&cJV$_Yt*R$B6Wf#^^K+hB z&3KduiD;7cI((^lOph9rJ7}@QsL>Nr!vQ{1mdnREF(Zbq)o;SJI4M_03OFiY##X0O&k1yP;&I;Vot8Ife zG_XFo5xh}6OVU2lG@x*So{aVypc_^n2?3JVuoP$_c*%&UEBRzs(3rd=aaT?f%08~} zrsKdYwtl=^4Va98CDAnaQ9tI``r1m;M}0qgJ;5Z@-~5%VFIouuU`vv#e=_I&0AFB` z?6`60oBUTt=3%>AOT6(Io9WSh_T;OI^)Aiq`A56{QqR&aH(M8R#1Ls{Z=I6NZu`n? z&~{Y2`R9_yW{jIbnt-N$F%5`sAb%w3|4vR-=80k?)Ndy&UDP%lV^cQd-EeCIq+rNV|}y)vnp++u>tVMTr!#UV@GaEHSoZz$0CQ1zAt(1 z1`4&1;Bb$RBMzK>Fa&;TPX z%%xAJ7H?HBq47VwR9Wkd1B_h#`o)CB_t|jS_yui4MFoly`Z%g~oHz)aRLl0j#KZ49 zFkZ?KzKX04%|^8i_CDPN|0WH|xXpL%tJ+Sl#k0n?2)bPkd=~^b9{s6Ht`Kbgd1?0wl|4 zeP4d~UTLi;{Vqf1LW-SQ(myA(X-ID7oqg(qD1Mhpdgk`_y?T~Pjn?Q?d;z}0?)Ve2 z+76ct%Cmbt+vC3x#QQ@*ig-DEshko=#4_0bg59F}8HY0V;keTJrGgla$5*kD41c3- zXDt|wsXLzF_hYXBFBx(V&%_3S8OD9)3_TFf4kK3HppXq<4_I&Wi4UOpQ8mXQZ_A5Y zlye3u?gwl7{2}M3#(I!=7KI*kSdE zNsduxO1R~v6OiI}5k5&H1&&t=#K$PZg*B|Mcqa!ARL2#v%1=$4s_e_5C}*%qn3SSg zCVFMi>Kd0EBVBNWnk9kIcoBmvLmg`D%u$qMR+)>BzGUjQpNf{8tcGD@Wa=wj6l7R} zFx1;xXe+C@(I*8k)_PavGPnXmOX}3&h#<_Ktu!ZPQ<4FWY&jadGSm0s6vfmi7%*{a zo$x2JoFGrE+0p67sgJzd@Jgtr`S*)!MlCPYLWY?Y?0}McP*5LD^lw)GH%`>ruo)!z z_*mmnmqf8`P9y>4y^Iaz{aY9=Dw-lEwX!8TZ{L5iNCt|11C^}V-O?A2gGAy3 zEZ5f(jCxy0eW$rs+MF7cm56Xht^!XH6iWOS#FLG-xWi%cSrb3+$GN49`@57fjXbTb4%Gr?(%|&S9hZ|lN zdL@#KMnDCxbuoLQS_Pjd>HLEXQI&8!A}X=Y0R5XViohta>{a4*{~+=M&*^M7Sgd}+ z8*U!9h0oumNzSzPikmN%Km5@(MY3yEp3v&j`rQZ?!^X2=mO`eQ^1FJrLf$;;I)|Zx zZ`DDo6$u(ixsZq_zG3>kpyQJ5hUoF*bWevZSw7EFw>n^%S&*UjPG=-=fC(K^NgKSH zQOZGF5B7xn(6=TkH_F45{>7)0f1NKUV`rcLH<0_UnC-vdCoX2d{|)5+2l$Eoe+56S z=v@8B1@O1;oUn1viQ|Ru;486+5JiLE5IJ*y zy}f)tx16!a$e(4EL_NKJcBDSF^TZu5gY$y;`1<)jtlmB{GyWq3*m+xD79Q#Ng2);Y zEv?<|o!PN(pf0_)bN6h+OkU(32(O=e)yB=BxW)UrUo-bMoRsi_FPKSG= zmIFnX-#LmXcM^Tu4TTzfjfLcv+1=eNR=WhWzOGh6XXhK&t4eEkdncBAM5A$5_p~+O z(?=FhN#7mzAYR3&k0{ww7_Z!Bb;Ux~4a<7dmk|YR>MqD`Mi`_s)K8fDPJ~%e{y}j*l zFG(Ba6sgP+Me@u3{?&|!lLR$xXz=4~MN^Lkh5Wc2LFHqg?ck&L`Lh4lFAW26z-lua zhWT2Lv{T9JN?nPSne)7S@V?!1URx%aHK=bm7p%bK?Pk+86=7`9#PTc|iD+M8J|#a$ z+3U?`x0fxtXHi+8rd&}DN7Xq4 zhEe`vWh9bIClVn-7EVwWSw^<=BJfd6b}fODhi8~mYr3#3!{rhm7Nq634b-WYFKgT+ zstS@BkVTA2Cch>v_z~BHcjQ@01w0jB=x0;r2xX^e`L=x(M0hP59pudt?;W zy3c)*sG62SmTv{12EuY#80a!kI0jbxY&a8;2Z(!jOBL ztx-U!a_fiMm9vPSgA}C-CI8TEQG5q7TfTWnYJN#ipW`<{-cGc$dn7{bLKJPvn;$d>#s-BE_pf^U4-Zr)BB+I)H z$qovssA3rdphq&%fDBY>0%Rh3I9`No0=kRIws6FEHIk|5o$RC>-jfz7a zN7})61Ubnu>#mw9Y0JyG<0_#SI7ku<5e^}1@*Z;cp}T0mfT!={sRRgUc_N`lm2S=q zP)R7{?T2xt(JuhN`>@zCqfiagj3MbD9s!{Qh&)X1Zv`T6=e;%}#SYc6BDN)oZ-72%lcBU62ib-Bc z?5-Lfn)~doflY?rINS?W1ebGwokok*5GPKf&j>JX+eVou)Q(_3z9mi8IfeG(2?&_Y zdbzHTR6XYu#`3>3qLGJ?DvmGk*elQFWRcK%n8cTK5IX+nv1zM&^qA&PDtE*no1Dv| zn30Ulj&X9c_*H1g6Ux_bw5b=~swC$a@Y@O!e~@YV_x?2NfN)Oxi5f;|DAVyrPZvWh zUwU}FtYqgv5IdJ*CRE@t={1HPH#G8yw;5<2LZ4|FVW1S)tcs&sp*YVf-G10iK{O!UjKt}sZxYJsid~n!=Neq5uUZjU zuxLx}6d2^bux)zFoOU=UGS;SRLp*p9x{@Vu*;RbDbt@V4F`=@YF%|S{#qh|&CSY>< z`ZrPhIN|{)Y8v-?ks2qU6RnuI%`S*2Y^#QXw+gh^?exQ=I&-i$TiZ4Q+5)6M^8%C`nirJ-%Yiq^A=3?O$0v*yq7(4b8c^)8wZaI%1w*z zf$(=JG&ahqIDA;Vu$Z1&IM*VmF>q0c4r4u4I5n_bRW>jO2K%_7F2qA-E?P_$ukD)~ z@%F~59{6y`2|yEJn7!v+O;`1HtA9o@@F5~dq`NkAQx{!ugLat_S47~!V+o6t@(p00H3=~_nayrV@z_}}0cE}qma8&KwiqVGdhkqEAy~7W z%O41|Zw|d<#LeI78^1a{CWwn1S|1r<-I6;!RJu4ur#tW6&cSS0t?5WFK6w_)O-Y?g|Jcr1s$g zrJTwhm|@B>r>Fh6qepE1)X1B#zL)O%!`Y; zEN#DyPb;NqXTv4juRi)timLtTya(=l`KLv?B0r#3)m@AAVn7y1R2o1jzxxY zp;~oXX{<8^ErPp)*@l~_*_zBYK~Zz-)|<8~2?}Sl)Fd#&hP`by@kA!Lqq8llNZVZR z2Z5p)7b`u^GfD9ek8>(dDTHgx#=5sLzz3W)=hlk&$t z4_qX4#)6HsGDf-Ezjm}1kd&p@j<*bfKJyBxhk%u+8yu)hYY*(Z2nSO#4?ikyvoe0J z6_-)2kBh2rt<0E8fk}BMXNw2W!u02~>$*59p<%)dtSr?Hq9Cfh11jmCh)lu0kUqY( z7~hzrZAvnfKl|Jnr}a;-V{j;UsObInyuf5ls)2(HXw8#{fM&BlQev!7!cuT)Tq3MN zAgOzOZVHep(sv_6>+mFxfqoZ&{Y+db+^m;Ahs9c`#Ob`1DLb-)y&(`i>shX+W$+zq z$f76P0(C){3h+{LPn7jloG{8gx+;W|15tOMGifHzZ~JWG-v?#|AS+8b0kn!ZBMxH%!fDJkvuRZCqPp$(wb2;t?WxO;uW77B zUUA~6!J5BJ=`{mvv91K!2Ta~`o<*t#qcS`}|6@b)UZ#GRFeDEqz!@Gw3h%R9fyHQc zn9)H8@Nx@$(B1~~4~yG`9lMn>^i`UQwKLga(-Cnv&CVS~W9A}Y5w04e!MUD7k8bddz`R|!5HHNWm} z2qOeVCR`l$*C^aR?_VNyVGM&Kfj@{vv;&;m|*(NWMJl{2=4dKRZS2{9xu_ znH(@ zF`%Cd__!d`xo$fNpbosT#E8XbsgcM+8G#vy&DZEb6YZx(*WhE8%q(B_S!K)GvyXxs z@fE%hPHY)nG;LGyJK~uRWvrs{b^`u{qTplcT%ehn-13Hkm=V&4wE?cQ3X7jm+|>KKCp*tQuiO%74U^%et-F8J!zVpGbACq}@CIcR@zWwX5UcU}vNt5{Oe5MFeHUztEo%ow_$g(7 z0gB6K$XiY!VT<_pni%k~`5wO$m7d$Yb-s0Ha|UU5yO=O6%Y5_%oTp7=qOXUR75C#r zDt{^5y+t)}nqKc6QxHFQfn8s0e$cr4Y4Yf=0^lD9G4`?^uS3$_g~t$YuGP%&x?K!Y ztL+y*CTopU@%C#OC1J{c!m?dz4j|gya)(JO&2L7ap^7+D#vHGUSe>dvrWH4x!J^Z4ot+a9C$vIYWc(fUL5* zu>f4QTh<7nbY_SgXA-!ZEw`D^21sM9qv$dxAf8ck!41LgBIgD}web8tr7KLtF2~Jb zy~)W44jm`>3mC2suty z^%12y^6j0D*|?~6plI&{(lj!(`bLzAr|%YiMrMr64^FM}7=7;3=nhjglw5O?n*JRp zoE#gY8vb-E*S|+K7}HHiG_g|sUrYK9X_7To&@p8QnsIxww@s)|rni0c5et5GQtr$z zw&IhI>Ybjt6%kfP=Nwu}`gOhJ0Z|75YktrE9byynBspOdlfJFhYp>0H-X|%kO!9u} zmP6wD)i*T}7a;Ih5fnViLs4FQ1ya?dY~g3t4qrEfR^|2dSI-c6&{beEpnY|e0Sn4I zF}p@RU8worllSoN|E)L>bLc-#zG7Ikc?E!O!2DIdH4YS}zV^r-|8}qdH59zmw&?|z zs+^=z?wg&hWC;>HWT(tD<(cZ+Vw&m(&F1^? z#=Rp*u?=JkPv@Zl=xLD{$ikVgKx{alStQF*iPDjYvgZ6WYB&B)Z6sAS7i9pQIH-8j z%tpM`h*+sib&KcX#>SZQ(f$%wE0SE+_C$7#UkWh4&4mnVBb{F=O(Y&U7Y4)?!~cw?Bu zXm2x8K-pD(tR{yi^V6iw$fwJDV-3Mk(d5k;(eK=h*o{y&@Pe!ui`@Mp?cRyuC|k=@ zCQ=Lz=a+fwg?fB7L6f+YE0RgHxUH@j)Tkl;w&@L16~h>e+VYJ{2ZN+cJs!nySNv80 z4$3W14q9X;W8v0=$aj3Mc2#*?$T(ah_!3A3nInom8`P}r6sUlF23_LaIG_ciTTO`a z(55B^+I|WsrMC_jhoo4-6|k}D zj>St-6F7zBu{f%txhdCENcXt%Dkg;D>X3vFG33WI^3G4{vk7oef)R|X=<-dRlXsf@ zT4p?WRDd%`EW}guI5sBygF|-^C<*QZFFE$F*MN%0&$(85CNs2EaIB5`Y23e^@_|8x z%f_{Gc-)Er>aqC82eW^ZNt2``{4FOtHHH?eT+QaG?pY`$G_EAbV%iXL<4|w=&i7wk zRtb=(u3A_bqv@w`7T{s85W8qWc+3Hi&Q8?p4g__s{^xQ?A@OAWP?eZ;4gbh{ z{RVrpG-2>l(&{Uy2#VY*a~r;Qf3bI)UrRp52(O=Qr*T-rMW%BO6)-+SzAv9$ZtR~e z56T&;7_)wkduC}Ig8HClwInw=W^%%JDydj2!)+R)M#7a67G3!`euf9M!^sKs zxw~=5TcS!6B**#*#QEjs&--5nRsD~rjjLwHzSlEGySb5%yZyhI<^p+>tOq@R9*Xi;4B6rRrcFEsV=fDth)T2v?4T^+x3 zpent;b#Qg0#wc|S!1V9xSl%39dDx$b?(gbg9ivma9A3NEj07V6+;#8BX`qno!;2|p z9psqbQx(ih950s%J9ugN0jtMnoWsY!qxX2A|e>Hqpzu&pcAnyC_Qh0J0qYC+W&xM!J9<6e4kIsN> z8X-SOJ-oOGdog?fp#TNJbV5EC<_vpqexj`fa$F6ksBw(UE9mcI}ED?@gqdo zr_dmUS;MD;nz6UcamDfYiXAi}Ml%rQFW~(+ZI94Dc+wLXo6`JPmsx{R=%T6c5e|Ej zUSR8On7^n(zIin|++g)EILCBLk(=m%W8kM{wxzi+YLOma+`~Bt6I8WVK2Cup*l(?~ z31b^OV_$_7UXD!PLvYeHIFB3?kUuYjCJ9>wb2D_FlA>9I=BRrtu!!#2f!UlF5jmLp zEp4A`H})*6m+*iNQVjg+B*U$FGL<>t3*PmSenpYZ*w?ApkO{Omp>n{tl(Ph2$qZu7 zl%GGA3!5AKS5aUlA(9@V1W!OG8UQLG7RTuaveu5jQwYB~+PdxlBIXKihOYsWR6)dD zbCZ_hB!6##V*oWV$a*NgqlRBQ;aGhrk49H9Zr;f55dwz%W}R1bz{BH7eG*5%mQ7cV zTc$PrG;SFh{0$$kbh1GLh7U7Z^0H|?nJ{L?lAB1q4An}|^+;j!OUZ?SV73(FUUU3O zrV`UK*y=)unH%zl&`@NSC50vN)K$|*_>z^2)6*mOTuAfGrkSAhFY1M%HzxE7&^YMl zZZJ6mM#=ORJSsG?eZ?hoS>N3)bE3G+sHHCO^)2R>xBqO8ruG)fz88@;J5Pzl>(e_A z>9PjMn=t{xOS)6>fcg)cKX*`ytVNjO7sln3F^e~N*GeeV{Q+%L<;(p+Mt`XBYjk=h zwiy_S%a%e*$@SG zT&jpI10x|^!31LFc}sj8%l;KuHdy0F;}m&R4t=2Ao#Ss&{9WPG=bH6;@zG-IEJqJa%r`&Uhx# zVMRK+bV-0V8_OOu4CM%3A;<#;w-apRv1Sbj*XY!-3BW+kBw1 zT&|Vp!O7PLy8IBN!9Wm;auc7_K?equRpI!^U7xV!&NSEq$`)r--)g}NgI2u+c%Y&u z>c7I9Li1sX&jVPuLA78**53)zAP;?QSb6dmca3)bB#20bs-mgBBD+Q@lS}|as{ZSk zrkNXVYZ7a`kD+9-AQ&gGZ>ek&h**H#5IO2o5a^SG`^It#!g)iE*UuE(K(!MtI|ACn zbKx1T;^-j|dm-P^SpO(_w3T4}<1drf05x`|EbOF}nNpWz4Pe!&O*A;UZlYYdN}D#L zK5hd9_OE`hjQGdibDg{VtTOV!uX)|P`xuYK3&IW;B;5z z!U4(()wk35&^1xh^7`^3QNIZ~;(XkCB_dwzzqwupD=7wtO;qaeun@Hxf|BC zk+cYJbpfaBnjSDH8|HxU&<8U7s7gwRT9u2kx@Qh>v)YWv+yYq8=7MrsBb0fY#*dQ36D}$3d)X~E?ITH zX?5*qCI@Ay(+0iHa>JbGYcz9L-D`_RuD$-%hzS)ka!dCl0BJ6MgAS>ps7RlC)8^7( zWQDzr7(H%z+gld{H1#jP7cn55TqiUxP-|Ep*(?#?t|PY#(u_Ld)Ft&-RwR1-X zU+3cf9D(IbotYH90T$I9^DQW6Y2;->Q&k(OCM$EVuZtF{1XZjFrb|VKddpH)G84QK zNs+?aeo|uWlX)01*e&}?*yQ3Ws&6f^3Y1R_UB1`{jMNL(5HCC^NWmgN`O7BJ{>rYB zTt;7v>qu}7#xQ@hc=fg{jElKj!1~3PmzAhDj2WfPy;sSr^>=ejJcN8|H=X&zuE}{e zq$~L;IpkK&AX`QtT?Xii<9J~Ztnkv9hqQ&^_!z7q00p{G$9z3yt`HTE+dC(zLxv|T zB}*ywC$sLAfte3>h_w>WBOYL~8%Hl|oCHnWLMPj7QM!=~Xe{##z&Zs%*cJoZ&+CnW zZ&S7^yZ}4l`5CEj&HTfOQ3I$zt{(Q+Q{7XW4pm1&b(Dgq5!`p|&@(D@4)1(NzZSt+ zi+H-5GA8VBjM1RC$Cl`ryt7nz3COe~VtN>vmtvA*TGCvGF_htbU&!b@(8lPc7b*ob z{rux|#WMu;5{67I%GX!01C@GL|4e6RO08%5n84uHp#+~A$pc$zc3(_;fU&V~my2bb z9mR-i=3GYCyOzModv}B(S&x96B#WkHqfEI(6l76GB_UgMTMTSk@kEY-90ru+ojRd6 zx91dF>1fcZhf!eg?4w4KP1{PG${b{MI7cURmE^q(hgFOBn@*MtcmyA$JFLnu)#?4aC?JNCuy6zPLLbzpTS zEA8_X>=VM-Ei*0KiCyi-2Xsx=+iGd{-e&GdR3K+mMW^$m@Wvz(E%?$1Vz96&N*)+t zta#Zc51fzWl@n)!<-ox^#bii52Q&w6QH^!xWzQ_;J6%SuIqTEo&;nN|l2_IR>n9}b z#YF~p$$sAZpB3D&ge=0f5&5xX5odcvkjasfRZ+sBK4c3Tw~vklc=D!w*e@C{7wMO; zwXi353~{eGOV~h2>_npfJNp59netsbwd6R^v39(SNVC4m7TZwEposeD($UdRY*op4 z_JTQt?KvP-Gw6V^b_Fe}4Jhz*bN8TlAS0w^=#+p?Xndc?KRHNu6Eyu&+EY;|Vxpz+ z?I=+sADq5PW2C#anOat-cqN?jAYbFn6qVghZTr*L!>+l1{kMd7dDUZMzRPWk1Rbfr zjIU)5S-tgjBe3A!mY^*QK^~6unk&igzNBhLA7&eiwHd z3zoJF#yb(+2kP zXjgv+*a_mN@b@E7S?{A#@Vz?Zom2+VPukj5e#6YjfPyt!Mq*(Ch9;2!<7^-n0IpV{ z@dWi$ZR!~VY?_!Wr*ss^Myi;YWDf*dp7vA_&yHWgv4|fJ9QV9Ick|+J9B0g-3>4=K#RqjCdeHD?x)W^6w z^qWhAk!Wij4eGSXgJy?sA|mmtXZrFaW%yQ+Bg}1O?JBklkMTGClT?l z1e@uUC-12weaFxq`}Cn)k4TOi8$Fpd_AT7afrakOnJ^QNwP{IbnacW7a&k?I8<;7fMn z(TgN_x_Bymrc%sc$$fzvmdO+6zSg4zqoc~CjC+I&iwQI7{V5u|_R$IHtuls=Bl766 zBCU6Hs~k@usA~F0#|mcN#*9>aBa9W_bF zB3K>3NRlAklpon}6?6@!Rw8<2!53t|g{^HuNHo?CI7Y@n>?K{KGjyJv0_%6{V^n89oBDami|sGL#r83Z&GpNpwYNy zv}9hL(nYGf0~;#&L#ojr6H~%e?J77%2lEJ}+A}N8buo-$in@B2|D-Y}-^er3Js4b>86nax^F8YH(gr!}eLHXnb&y%A^+nf-xRW3r)n?xqrAgB*Y(~_BIlZq_vd>&uEBUx?q9uN1O|a3Pdw`@<}aP9Ts;t zZOjoJmtKR;`j;lpMvSnwlh`_#H7h}q6b$5e;HboAcZ|xQd1_H{@G@}e&}V8t{vgFo z$aX^|hqqPYOGQq^Q`hF%q``cR6rH(2qZ>Z`BZ?5d*@u0uD!#_|+kWD#tQnzuT(dOc z+#myUHUj#*O~H^Uk~{`qLp{HJe^Zl|Je-3GX>ApX3!ZL8+PO9&#*kf#v9hswU<4>SDbP{=D^s-fA6Y%Q zi>~$j5!bAcp%9TRQrB6#v9i)rVqJyGz}=iokOK95EJ2ZTh*?p>-!~;->PeM6ow-TD z+6)My=2Djqzh`R3w+%qd<}V98#pww`aZXX}q%fc%XIPI6hweT2gQv(}#;t=o%G0WE z3KZXyb65m<)yGums$8R&w0j=1d)+3q;C%n|gBz3vr1a zpC0_7nV_!D2yt(k2Z-62NgJm}hs++xla0gG@ZGvtY&tBF&pfk*B3}bOJ$yb2>jGF`W#%m6Ypf6GFYqM;V0t+|5}e(8Ptynp;^Lo1g|DH2EWJps@xd%ccu;D z`JNHx-uQDQzIPF9>Y)~X7dEUh+^N5OFwIS7_OQh5qaHqe->QG-lozn+IEoylL-o~& z0x9~=EU|R&w9UX)|He@nbGHc9G?KNl-0lf>fzaz0QnpU|E*(t6Svi5Ln!ET7F1?s52BxoWO;Pa~nCJVL?!Y`5k`?JmAh=VblmatFBBY8uh33Fm8jBYlK9>l6W(r-vf*E;0nO=nK)ALFS0*XjEacdn$`Ja3&1e! zy2|f;7kP)5{i)W?PPrOyi>ij4h`&DM$qHt}XOF5{V2B-!;xqVny$R(GjQ~5hcuVe9 z`x6xM@3D@cpYb67p*(lox)NHMxjz+LjbTA#l16ZiP#dfm1NW7`L1wY2baf;*E`gTA_y&@{E+&XnI}a@? zg^eU2UzUr~Id3DfM%V>g)(y0<6fQxY3V4@jj@z&FFo1vSg@G*%d zf4z+CjG(6^MLX$RwZ!-z(2;A55nBg|B-`d$*@1}shTjQJbHRK7)V^W%;IY$elD`aG zeNVi|t-o8k)+;kdNQ^e5DHy2pAPSQ}6rvfpsr#=k5Rw@quFg!}S)qBY20MxfJoMt3@9^R+7X4S?#e6WI?edfjmL(G8Hqxx} z))Ny{^XWyK{o`er4SNqhxV=?FRa{>d*s%noK;qOYhb_(NUEWl89VpKbZ}r8m*r(sU zK(D48-RMu8dVBk^y&>PG?ptzk+Jo2neNG{wFNPf4XV4CL-ZhH&Ts7%y&pr>$)WP?9 zx!K?QFkRKTemqHxnIoZ2ppUb9d6a;!U{GQomsL&tvVNI~-|71A7Lue-Kz}Ria}a;X z4lgaBY4H}RXO!azfnR=2DLIy~U!s}{HULP77+Bujtc=A{jtjX2H^bGSn^ahw-z>#V zgWq&v9Nv%l=*CXka3Ik+bF&v$>QNRXubbGESWFa~2PWosGzRJFF@gV35ryB5T!?^kkde zF}y7yjbkFZoREb0;qq#6gHIhf_LVpDlYL7>Ds3dy7_S6QF!1csJ=n_2@!FX!`G1Ly zSM_Ehm-Jw(cDh?a($9z>!KzPsWVB1E6!s2Q+ids*;#G3;;7k3|71~Zes3&6Gy{D|EwQ(Lhsz!h{~uy6Nte?VQz zV92aMiCM@njt1S^5g1jaZwIdl!94ZZ zJGqo&nHY2iIDJVq#mR1`d-~j*{qrPt;X<(abM@#s`CqkDpe_>*-n#(ho@M8pl`U(Cm59>W=JJ+Z z2e1)UHsMGj6uaUX%lwiHmv=(S^TT0t(6v@Z9-sW80t8w@-r+&gbvts0Ouufp#v<^V zwHfd#?omFN$D`3Q@$mo+7R@BnZ23(UrAkNQ7# z%KuUy|C8@vXJTRaZ=Ldg$#<~-pYk2Y+Lv}XZHT}Bm_GAkO7WX_-{$^65r?f7hlLW# z1R_Wnu_RNWHWLj;!;%ZXJs?qA4%CtPv*SO=a>9E zoW9`j^IrTy{rvbI*pmI5dU}p(-43(FWdL_MtlzAqv&U3qzj3+D>79x-+h3Er#FwGJ zhmw0>#tMR~rUpJKG~{`f)plX?k;ClyEOmfDEXXLFDdKs_QqB6T$_>MgmlJVlSw?4O zgpQrhK3y&dGeSbXHUJ~}o&evHO2$b0obyAc%=kPmBiJRdna34J?ZDuCK>hJi{Mc0` zoCQV|&PJO8Lx5qWUX|AWGWJf5A9RL7c$UD$4N)c58kVGZD4D}n;V*HPFS zc>HeB*Ap2!bx$c78p@xZ`?5d%Mf3dfhwg=emNIFwBie%2_i7m}F_=o}j)NO{HbRQE z{U7@XK?o0lU0aJ={PcBI5(Y1r`})=G%KFzC;A6egJWYyN7IU?<8}iHi^NJDvLFgtC zH6N$2r3ffEVgN~+>)1?LfKa&1qQBvthdnM}B$*WUm&VU0B}>lnk%Arn5wX(2hlR=F z@6$60`@eEvN83^t5QTIugRs5r=IC3sM~{-7JMtB52sHx#Z zK(^P@(v!n0=jfbeggGb@G$p75Fh z8n89AnJ2rWow)9Zl5&4}=c>4@*z8)Y)1iFZpr4bz;(I|z+1$ygeLAjrz>Qpzm%e0V zPX-;=k^C=dqr1eVTm(E@|5`i-(5c{N;M*cJh0vkeEY2-3)^ci?8)C(r&!gM=CUJUHHF)iP__ZXUr5K?o@$iTeAwh|@W^ zQl^GdIQ&|NKeYy}GL%6#rM;xZXkRRRMig*J*MrD5e&3{%{Bt16oFAXcH$DYwEE6!- z^;$<_BM&Z>ih8zc;2jbq!$G$`Zyh-Vxw-;`)%C1y9fUaEA~*FD1SLdEMFUDvf77;u zhys+>wjVhvTRLDv=O03FGuAwF+%7zxkTvS`n%me+9jJUt%oExuLUUEK*7vY+oiqF+ z`5qD8wB6OC%!l5lKaLuwe0pkgwYN%ar+|Q;01@QJF~H#md3d6_5(^TGM>~d22LL~m zitrZp$_n3^^NYB~10tXvr~!j*y{$+Vq=AnNUQ;;5C9n{7nFIY=8@!**h35w{l*SX$ z`E}2{hD;ItUW*~)gyZNrpiYr`0s^7koS(NZ^nU1Q7D0K3KW6Gt*MbA1 zU6Z=Wigt2Hi5!#An=AU`%2?+RD`AjsW%?MmR?$idh=AL3mo-R9bH(}aeD2bIpzP5k ze77h%wRpc>E`Xa#wwxV)3Bo{M)zaoA-YW0lIT|+udl^}Zkui4F&k_o1RslUb?0n=? zjzsH)!n|v0nUapX?lh*s5YPqkvEbcjqi$ez%#*DZbhw$uQ;k1pm%fc`Kmf~DoDXAT z7~S)pLbM5XiTd{<^~Q(iCE_igp*)Kf>sfXvNKWaifQ%7{t8t)F{+qyO_)o~9czEYz z&^iqpYNED`3o6ED;H>NQw1Qe>N&R_E&%m4u0A2Kpb-p?Bgb7!g`AcKZ9V+v$l;g)st)#U-tJ_|GHY+nu78{RrCi`tI2_^$opmD% zeyUq6p|X|2Of@Dp^s=tO!!_@X=%fomp2c$r2LI5>dlxcKeUamGaZ1=3nZpGDvlcJaPuK6)b+zW++0Q^WM@Rms&l-iO!iC)hWO$36UTk8B*~DwG z?^8?R(RKJIx0G|Ae;!IfNo*$|E{9}`L#V6|>>B`rOEo`Ei`JH@o#YC_cASg?&lXpL zz~dCtU(hD50HtkW4I`h&`MexJvr)$2xsZ?TAc=ak7LuGiwj34XO3~gtkW!YvV@%JG z-bN&aLR_iB8Y=*)w6`72(6rG63dZ~$$6G=YzuT$rBN`1denR-AgL2i8VPj0he&or` zo$rO}Rnls~6WvR3@^fWqKMy+qgsW09)t!P4(*RQ{%wwALyw#KTAiAzh-em4G4_?u3 zd2?o$cFDU6enTmYDXO^v#z*lfuC9}KBDp*_k|gi;U{sO^tXhA@yjRJBQBw*Hf2 z!kp*uljdQ0MEZ_`-Hf`3G=Ivz3RD*VGGsoeY zS;iE`eyXwI!B4f0cP{qJd_PWh3|s$?#^@IpVp^-q0r41hAndFlpE{{3o=@2rlDqM6 zLs>rAcO7SpK#J@}T6;91&!RerY*Cb-Pk$qE$QvPqhDcQgch8ipIw$0%8!8W=)A!5G zt?nbA)03>NuVNCTK_k5zTwnK|cT7b-D>k>ByxF^t$2J9@E|}wD_TNsPFvyIbva{wr zfg%BQwAQDnVP*`l>?OI%rwi&bIuk@j>3Ayo;C-;P0FaxW3=|eoZzVD(KjR6HUoc{eD0Vf}Zkkv|=$6sE^p3m*fwnHi_?<9CE*+%Gfi2 zsa6r6q}d4(Z)o~MLL6H7M`;gZ2qseqzsv@*Q zdmZ~p%I(2AZ#~EHJW~;S$9uH-R#9m`sPn3M(gUdrCAoDbyqdL^9Xf zMpG6EoKxUvy5k&B2Lq0pFPpCcme6|@L=~b9hPK$GghdIJ{NieD$-_ZKzhY8ODucWT zJ3}c65yu$ia~)4TT35!seBqMLLIuZ4Av%cACCYB+#u(sw5+{bS*s{$^f}$VL?X!sRYSy z%vUo(_X1S?Lt?&a**H_4fPjpi^;L2q?M5UF#;iF?_M{Mt?j$rU{~CRCz%0w2g4O7q ztb}_AnV0fN5OEF~XRnLHG{(G;8s-oURMJr8$XEpb(TmD^wiWdhx{% z*4^R`q;c%)$3HCrPQm7vD^gm;;TGDR)bq=>e@b6hz1^#QlkXSFn*lsGZq?E`yP>hh z5poIdyfED4k4vc5nod#_=X>*n6WsAkL<1hpy$B@}Y+2?5?^mNBUwxhlKRO+iSWm6866`KfKU4#%#I z+uPy~8IbF~ZV6`iy1R7*d{vuyt<_dhNSf|~#@sIKz?6dp8YdHqD9*BQK*;cjNg(* zJKrV~O3%Gv>dH3T3{{iXl+=$J-PFuFiBvSl82sDam#=qRkd3u1Uu>|q-c=vMRL218 zpA;kcM!)xID7T9Ng9ar?cH3lA4(UYy()V_q6v3CPyGsc5^bAx}!GE@D>No8T&1I;Y%ILVrI+tO{1lh#FWs z@Bt*whG9%e#RT*P(n))H153`${RCp}+yd}_{8~sTvx_i=^|6Wb6+Lrmm9W?!0A>AQ zfOTYKEU{gE#yA3t7CpQqS0cSP4}!fD=uBkPrBMe?3@(wz)9Q4M*bTnr_Z=9T`nx^9 zDWsBs;0;@7HaDh$kZt2Sh4yT&Ev{%oD=_(hM0xu_{drzGhFz&C1l_z&H11NRDHLZB z5Npvs6!~IZ*x)@+@S$QupAsj^iD17v7 zxD#RHP2a`rWOmD2+qvSREzAEUqm7}t!|LS9zRh;4qhxcxtSNdIeYtrc^!BP<=PGl#A{^D@)`h0O})Kjos&O^s|hE+hom}>8^}L9FAKZoSk>64K1Tm#c!Wp zeAlcgb1a9&4fo|I5qztY3D#&hiqvPV>CX24en*$PD|OZcZvW$#Dbg1}w{s7CZxD9$ zP+AKSo@934)}Bd?_^rtSM1GF9CvyaH%0TGM(F}=&cSxvGv5A1#0~*Qz#M_tBA9?;R ze!vpiIPQR)aIP}QIHt1tZe7}$&BXNA_X~8d!BXuBtfY-b!BP55Ag5)N^t72?GmYrA zs#xix#x-`U1DHK8wW}E5scy;vRjlt3rw|XNDRzBq71)~Bk$zmDvbBG9L8u|kOLs_lUomV6n(z2R> z(6h2Wrro;kGTCQ(2y|O*XXl|Q#hkE&sQD?3r8R^&3AIfxx8(|ek&X>3Qq?cZ+rH>t zy@dbeiuM29_AKm-|9!>c_+Q-i9RD}By|&iBE7rf-;1A*#hqklDZoQ8avf3mdP%JGu z8K9vQ7-nt_>2MQ23SC2+bC$f}>x4R+Bn&eR?1B;0;Kb@ME z6&i>ZZ=l8_JmQb-sCFFoji`M`4CsO$t1~-lVzFT9(l5`qIAB`P!#@YrVPhP5Brxw> zvCONJjD#_|)h_yYn=X1^*(=Oj2T^@>1XRR98b7&g=!$Q#@D@3#y!eY2yO3dCbzcvt z8V9%rdp0^pt6ZcH4|@^L(1hv?WENI6^^D1j_=kN8{yX4Ri-8_*m2h!tR>U$$FH@4d zRYRvP?#f|vqNjLe1<;x_GiO`7mv`THP5ZWa7lz~(7=f$X8N7Bh$_7_9en)z#6B`6| zJewL^T0%DgY3uk!=|T2nw`)FYn@DOaZdAiBy=qybw&^g3D$}5woC28$CIdZB+Lxo~ z<6#M9VqxI?0f?t)dGN*HpQihJ($f_qm=LOr7SP8t14|NWHgPLmRK;L)!rB22DY&VP zuG$!EH5TNf`q7yKmDEyqI%CB<0i+o8sZX?0H5^e_ea?xj^)LKwSAQN8HM@dqs`k8e z@KBj2Mw3GIz($vtD2)6W3-u1@IZ5`rDqRnJ|7vsDE$a@s$%gG@^6?OY^Uy^_=M0OJ z3GN@r9QS7WYO=%2iOGFDY$a9pw=3snCxa!jHp9)7k7!bm*(d52v+CQ57NaO}C)ihI zU*rr%U9oP%P?fh)pJzB`+-IYFg`-C1(=<8mBPc5`g+T9{YDlZ z!%1iTgCS|v5Squ{D=%81yfQ-lVPYjvN^t`eR=1PZE_G5!o7hsf>O2SgiAm=jAGPRI zCV85F6YtJT)L_k~KsJFv9=EwSUK6=`yb*c4xu<|Hb8%M;!@o3KPW=_|U?*2YW}a!~ac}a*pcQnlT2jGj zQ^Va_Gcb`{N>nF2U>L$o%Tqgts_U>Dq+{hqBGI&>`SHko5*EcMvg*dxl(e!( zbLc1BK$JS);;OSo1j8CDyXno4FRT_L1?sh?0OO=!3YF$GCD@WD7U3n??nRuauP4;3 zyDvAPLetYmVQqn=b&QrYd2dOo6d`@Yhf$b@!Xs7{W353bbtK{)z$Q}n%!GH40KbK6 zmaZf>NAu?9P_K@@7?5|gQnzL`utqWrc=N#m{kyNTkQhEkb^j^&)qsSLeo!Rotr;Gc z@>Y$Ir+N?<@^&lf{TF%c=>YaIb*h4(mecHC%FKe?ao zFOn8{OpA`Z(n*FCB5EB^Ugvc+in8~urc*dGiuCVy`Rz;Z0uzhNRl*0iNtC8jo+)H- z1lO07X+|4m#Wq7`^3y%7{!{214=89+HbRU~DJLI+e1&t;9voj~_ zrntSZoinnfdh?@0VhNnCUKvKMv_)&N?a=C4hCr*TkeKHk35{?xd`Db75~QRO4G{jg zFKV7xa5J8yRNfFW3)*tTRer3r2yVPCo#=_GBivGNM^2GHT<7o{z9GYb>f1ahbulNh z;tV7pH1Xr3oa58;(nZ5jSJ*vw_OL*oq53OqAp2jin%aAn9OZf=zDToG}7K!qAD(6k+1CqD3j5xIuPODY_lpL+A;sML&-& ze^+;+XMMDAqnk^@!B_kl7Df;T*%kwisXS!ASMht1Q=k9~?B9}G7a%5R|E#(ns7oQF zAtSO0|NV1~&vC+FrjAen}mI*Jbg$9z<^w zc;4o(zD9V7p~H82f%hye%Kfsx->mesfO2l5TlArVU20>Fv6u_nwiN zjs5PHJ1vcN%(l4xy1T)S41nG<2aR>rykUax2XB@`xO$C2pZ^g$+(V>5pbjigmZxx{ z0z$pDcK`)rUoRm-AlpFMmxZ*;NaD5+%go&G-F0+RqXxRN8ENT0&rw3$qnX|KBVwtizsaAdW}u{4 zzHgVAdFUgL?9)^LW{Tlvl=p-=pG$vC++D<1&esRd*Fg9ciw0Ccq=^JQ-LyPI-M`*HU_GRpo_@D|DX)bP*>%7!962<|c> zJv_C;fu03#=|h6m0@-lY;ZJ1_faW@Wz#2)R*z=jbDX>Y2Fa^HV3Epi0EE8E2$`_*d z%y?j=w*3h|cW;=~^r3kXYx7`2^_VB@cOcAn%sa({j&XVGhh{Ht8C`LC3RRm!bMyGb zW%%*VZu$>J=e*S?wF8#MxQV;Q>-&c1sjkXu9H&2h;G5cgT%&{>LNf@wvVkbK0fPTmT%@vA8TC+Tk73BWBw_?e8r6Y=D;j@z|APM(9_ z=5VU*fvtx!LQa$1+jyBy-1FJr%=;;+NZ9^4&1)-RceMUFH@9%xeIJBBkkCguHtw^- z5XjSKf*A=B9)Df5mBx07^u)g7Kb`^{arK;&*F&sux$_E+KWbOtH}O#GN_^+x2$^6U z2iw4o5}@Fal|dh#g5L%3suBLYy`qmRMNZhEjR$pZTr)qVn4H17!*}RR`>OYyVrmAz z!4Zgu-cUX=v#9E4>zRd;X`jOM0IzZiv1{KlKM9A@{dvzF^bM9GfCBnFr+hTvA6$Qv zYzzC=hI<(TPC5?t(pZDf)`@bgt$MfOOeliD?Ox?e`TpvEi-1t~=&XR#;S! z>hRf$Gh*~f9d?Vc2ep+N%ntn)-Zr=dydqaTPWfrberxN_&hUipfw=-_msE1@1bro@ zZukMk)rwdJ0}D*EXN>;#VwlH+X$A+@0mTqs&`_dvU2ivIecQ>@E{tAc$^x1g!m)9~jlRjr5E@ZFX!iy_>6?KndV=k;>X###77HH%)wvq z9uTjOv*n4jFh6eOC^jlCKlj)?&2S9(xc&bU-NV?m9=X4g72Vz1dAQM|{#7c%_wjPC zZuB$U@2$cAzF%!&GznM0=Lt0-0rtM#=I-17>r~v_-}{g1zWn2>(`o}fYpI&=&M9DBn5CimRq4z+IEfJNC)fys(7HKnH$|Qwr`DM z(DzmAD~Dwk%&p$~6REF;Mc1jan02|kFeEJZ<4L<>#IkH@v6n>fpZHzf40RaIt=&Ya zn^#ePM&WIUiU<@>iXZD#Yni zmpnlO`Ku4-x4n|aR`OMmEY-}0Tit&mwm90j? z(DA(d^6viDRM#fQ=72RIM*Kc^^+MSuw+x47#NYviwZFacG4#R7qZ{vs@V4ZHxp(CM z+Ijf>jp^I~g%OvKb0o)Ur_2e+rRb_lzlOl7RUNeDDehtO9^bpk=F{WTyT(U<$3a7x z(f8=k9Hav$7mB;hzIl55;<1FIgOGv-j)!JII;R$v^4(hfnk-Xa>%`{`sJ?VpYspr9Aj8KVr4`c-LGa7 z7|_FSyqy11qV`;Al~{NBC{)NtF*a1E*@KIch6mbMbXd8cYpdN-gna=@#qw7*m5^_; z6xX+{0Za)*+rjC)k4Vvqp7eHxc3@><6Wlrrw&FD5jHqwXKmL2LtR&&-@vmX05?s-7FTZ zS{5^d5!M@>u`VElSl@>bQJJ%UEQa&6@(UGKteKM&gQ6KPVKXS1$Hd0F+^<)(zHLZs@-6{Q{9s40-4cj9$;O5VQK5g5P{lW<{Fl0aV8A^4rapQW2`?ViyUgEE3Zf2< z-&OfwGywGhFQ7VNV<8w#L%>H3%^QPo&|KD-j&^upd}jb3toO==<-ae4Rcw|4OEqfW zeW-l>Te7WpgpjvkLGYtNq0zA3Ye67S9{A$<0|DT-eH)D<=3}wGdNqG&rH#1^6%yeA zK=pahzzqRIIf8(I`7T%N;pO!K$|bP?S$M!f>ksUytq3Xnzfp*`EBo;BuFvVWqTt64 zfdy;`9AWw1U?{11Xf{?D%PyOo@|*l`HL@x3v;JeFIbfgp>Q72cqEnx`_OnD=;mqnZ zn_d9vFYj8+I9B@yhcK<~&vJuljtKIfodf&G1^Xz}A$g?L{QK!TeEEwH+l+veOvFCl zar^_eAxZ!lO2nTXu%oI2^YpEj1MA#!kq7%UETHxK$~b?^E;P+sYHcQTOaS+9!vLgk zvq#qi5>umX21ePsY1FR>p#8QJ^Ri$>-_ z%Q)GCfwzT9Ib76`XwWqc5z$*d+JJYp>Xi{|SOV`A{8Jd(i_naYI_W3-D98=-zogWS z?L(RH^YNsgie{)9uOc6@s>dP6dYoz_$a6hsVyifGOYQ}vv+xz0%J=(SrYL17pyTt^ za-AgMIqNW%JxKD~7{xCMMf`2)YGKy*5?vL1|2%eJ@!|RGFR77OG$3%hTrp1jpNX_D z>#vZ(p~LK**eA`wmHGmOBdC&rju@1yEVHC*Nc0AzMb~;Wr}KgG9@wOOZm`M2zICpn z2U3;_2dh{AySF|D0h|NGc}wa6{Kc(zv}o2U(#Bq1d3)Y?>#Dhjw>l)(Ivle)MAtej zYPr8``8Vy<{*er}&S|3G;5>Wm+mM)~z|AWda4G6%h2QLZeA<%(Kxwjn>D>aMi?9`VnN+)TLaf^uV1_pYW2mup}iu1@fg! zv&g|K&vK7hJnngr3y+NOmBW;DX)@BV%!4|MYVZX|G69_E%wF(urVdLQNtUW7LpSOt zh#V@Em>D6lpUqKEW&s3Kxl9lwF{s`)(TsrTE!m$xdBPDon*2l*oi%|(BMsV>Slgm~ zgIfZmw|~%C{qpB!x%iDwGP$af4jA8fGv7TWjoL6>MkbQ0@JHnp zDtllQ`py2+(IhZF78I{K&2R8_8WPJ4Jw6*FH;5Spu0+SYY*3>^6qKEmJ+wcY`W0LkR`1`{IA1)PtzH}vtI`0P8- zo0qG!5UT<}r$2)gZqP#FOvl`o*pg^i$8cO5ZN$DrbwMG4BOHj9R;#`y3m)$^Rb*3_S+x8+i#|V?!+iFz=u6m z)UD$!!T8v3z6hH%zA4_JB{UE?-JDlUMH4f^g)`&ls+viTu@kh%Kmy1EoXz7#W&WKH zkANsqG*CD5G(P|&|0Q)1;1EIHR(MtHCn)=!i~$3)CqVZ^fiEFs4eWHy#4I!XD=;eF z1$?+4xT|2$%#W~(Yn&yHLQTtdCTn%<(<<`-NDeqVyYjR!+Lo~*ik}8QGRq*E%WF}J zxr}8N-g+g?#|R!cDp*$6i1fTxQm=R|R=rUU?4;2XU^`gf6E??{A)}N9hIX$&N44BR zWxhfR=y2NK*8q!PW*w`#F3j=SPMozSM9Gg1Z&Sc8Jx3+cX5`n%I_r3i zgF(x8_{me`)UOk+JTPEzX{RKCX7s3y z!zL~aQH!+xQ=FmJik7+jIs>DC17byg3ccoB2p;d$RL6~M zy}}Fl3z5AJq5y6oh96VaD36VC95_1QF~?3)q_$4p6mo4~e|}^8uqu-V(HtAZ0WRaA zP^tO?0*ouj4cznfN#y35;;ma|4|sR?chFYIuZh#O36!x!&;Y{Um-(yjn`XdrQg1q% zL#$){pL~dGa`A9gRF6mqU=VedW9R+m`01_dWcJg&!PmFTM_DOdkT+FxPXxLXGlyLK zQ2Csv7w7wEYva92NA)Z%6qpP*)~$)HXA@&5d5Ex#0caZ{5gv*9(vrPx z-FqM23NTB`!DB+HGhQJjz7n4@n!4hs_CaBvUT*4Ar*9q|C8+8rjNnbA8?#;P#BO?2 zw?v;&Y0p>y~Wt5?@PdhgFah{%>iJQEdjCa3D| zorFaj{gO8k!kX^x&8LeL1@aX*v>sdq3RZI=VEUnv;|2l%`$caI?BFM+xEF0(aKg`o zEisQ~AM@&!I^iz|$MZn`VK9GI3I7EyY4EJj#7YMHNMKP_yq35@eAi!wti&x&KmSUD z`$q|LFkMMQoSR7+&2*tWqkP4e@(*r_kXeWYVJ9F~1PTb)88R}hT`185SqzP{PSJp1fT~tg2$)sB)t2PfJ11C7E9p)N)*7^3jCeiYd}M~G z2H>7fDnc3;M0Fv#3qC0OO;s0u>1St14(+T=aR2uWb1oUrq%TWK4~nv9Le$V$pDYwI z-@CE3)d^6so$m=YC@pcnGNw(<+-Pq4;YwOvMvnB0KQU&80~+Vy4O}H z!2HogO}-F=m3nS)P3ldH30N0gBIz~R=bT`YHUTvClxLQT%Qy1Bt?zp8|!b0fN8O= zst6wqnQxagxl}`?Lt!eWlNvj{oJ>cK0RM=;W8e<7QJRZ#Q_>vk2-gFlypimI_8Y=x zGCmF*$NA|o)Jok$nTUrjSS+`|$k{&5(XFP{hp&oR1ZJohv0f<^`QvKmGfY+nX&5JJ z!`+!wLd(=W>Nr?f`4NT0q8w_^TFJ46k4GY~QSBU^Mc1$oBs@uXr-40yM305B0srdT z{RbISh+Whia1*YIbp*A-Rz7ca zrPzT^y;do%Lq=hRptf7(%-zln%YJJJtB@M$&?h9HdG+!n8=F{DQ7Y9pQE{>?Y-rR- zs)@msXV_~0BTC{N8T#lnaaO5zNoub<#CpajKS)n4-_;o0&sGt3Q_pF!xlNI3=|nUa96;&CgFN!c@t=|CH1YKzjdXeTk;vrnuS7Uup=81;CUzmp}iWk&fheWtpuGpD}CZScI^ z_eU~xWsnS4?+?bn6yToL`t^H_t$w6yJ4EO#J4L}Ekfi_Wje;x{{QOQ3wVs%L9ZGRr zp{`DD){wU^dnv$yg@FgYSa^%K^R4z)$s|=>9W9jv6VU-n=|r4YBFm*H2(ig^vPGx0 zmtiKm&?38=Y_UY!*}RI=pb2+BkmAsyM+oE~>JF}hL`Akr1mq$n`YGx7tk**NVrFR= zrx=Q}+`U=s%>bAo&$UnoeUmq*dNI~!-N59V1S~?7>Q=bg~QbFz4 zO@eHim1HKieJy;<0p3V%^Ieg$5&EE@^(6_ULXIwNve~T+oB(pn82Yr5q?oR|{lDD% z#?mBX`HO@<;Rd!KMTx(~vIEc7o}s*VYA#thbLQNGqy)Z`kKnaJ*rS3$vCA9Dv8zteTJ^7CP7I6@xf+mcl)ex zinD^6?&1iOnZY?JFEcce>^N{S+pKY}+yovIlNy*ds(icSKqk2hsTYn_|#Z z>m})T=lEgf8mXvS)IB?CG7}6TAX4vY4JRoLFI3w5vC|dpfUc#_8&E+~^gwh~FGCWv zyh*Y!*G7iLt#m4P0vDX6MHhxIo#BH@jxjLQ-2D#kPC=gPi%o?LN%s&r?d3*+=emUo znXHVAmP=1&LLkIWiA8xK(VGWyvfV z9;t`L8!QE-6zOS0Cgy?>x#1P5tcK3XFj{27;GS>uH z+H{p|Oc2B;*IV~w0OTgyLLy#pt3Gj=OTR@xW7G>{ta+V)g9K*E&c?<_?>gE0`Guu} zC<7qAGA6+fg3U1DvcKfC4;rG^JSh&54swP?kO7+21{Q*LmYRR|pr|Xkf7D5rG+l|i ze2aOWIy6nx+T7$blQUK-C@cIOj&IX7n;yDcaTPR{W_mNJDFY0rUs~TNw|V+&-6cNw zuw%Yj)^?xN{7KU$6>m;p_BIMY`|-W6W-jSi$5osvne0>(zfQ)R0wLp%ufY7?oTrE^ z{7L2U4X=Q{IJsgj5Z^s*N7Oy#uF%lonj*jU(CrdbS%XZ^>(qU~^!%XBt6gRFxmZMP zDP+oOE{Ci9LpitKJaPNs4rIY>d#I824J0n~h@nWsev=U(hM`x^@k`)>Q>e@bhXWA# zjLXUmW+H^8gV$d84^9NY`v|!`QdsBw`>BLMscu^9fqpo44LQ(p{NGqWzlVw98 z?Ut|wP(`xiPcDVpG%#t82uRajaz~mih+!;5x6Ddew=H_NvZ#H67?4 zxUs6wQN-ISmWbr0&3Bt%iqbNISSqYpAHPO!TMh%|AZ~Q4bB@~a>uxJ2`rgx}DT@>i z;@c$}f2_Hpz9xT>yJUjMry~u$mW^Ix;72TlPjD|^sQR4ev2A04(zME+34h?>%IYk+ zv?EA#7C0Vb2g$5D8I9Oe7C)=%UJoZ*21WgE7_OHAmBDZ3sUh7o^UFoB*SmI)As2ti ztUgPFda5r#JYLzofr4&a=x?wDDG-wbEN2O;c~u!h_n4T1+0f797+|Sl`0E+8uMGPp ze#n8IdKUk@zP~P~S8zIl{Y*dCEiL54fu|iQ=DyCag2 z^%AxZ8LLj+GsLT?)y&8$Z=%YrbsiOu-PRp1b7nv6!1~+RTW99Wo}(s$q@6II^Sh=nNufgA|vu;TG3DLc{lA(aIT_4EK?eb zM6N&j3+X9{K_cEaCKo~n-E>U#`UuiN6C7hcVo5Cm76Zkcy1M}~`e4QdB zyp!!iH@s8`-^t*iTbFMj=6Ut@XS#m!bJe-Pd)&?ey{^7(8131Ud#<+?Xz$)5I4Xho z$piutV-)1o&+V8^Y~QIvdLFVO?>CGDv%t_x-3Pua51}wmjvX>o?mK^IROdmis;`J< z<`kQ>gQ#+bMo0>2&01|8Og}77KQouX{N& zQN6iw7vXe6wDW~nk%~Bn(s0WHyTGhNp+R+luFlTrepXXtqODt>Z%RjV-yC>+BbfAJ zr3FJB>$mV`aqf8Zg|QiI@4er=!~xvnGfB3}X^6svW)11pbLzMr39>^UnFJXp9s+Sc zhe=rK2j0G+&CNC1lR7phxHjmbn%nlzuf7X6*Y8OJ#%Z!YJM)@h&(!5;d-dw(#25!KgP}>NEBefvSr)0ZQIr>+qP|+uWZ}4 zZQHh8HLp9OdlvH-v(05j7eK)&*UJ(<;=M*DszCJlgt>7hULVc$ni^n%hDRtYI*E%>T}@yNzC| z!+a}Ljx3-&r${3p4PPLPUY$>Pr--(w9j?qg2ZBLj{gGWC~3C+2cGsn z$v-v@&i~8PIR8WPkMsX8`NyjfhsW-C8(80KP)DBw$kRQY$yloY3z1imV+15Bp;yPHa|!fHQWL3%db-v)uDc`_x{_sD*tn5(&p~) zYTW$>{q=ey_B6if+*jF;6qE!{hUP)Jylf zZ>bZ#JRUZAdp}=gC6&6{cW9Z!Ca3e$*6SM;Csp0A$Jg7Ti*6$m4DZ*|!8S6$a=y?A z&)?h8vO*`BK1sjdtV_&uf7>&7u4-0zQ5s}cYz;I0$<9qMyJp39)SLVBh+MhcKnCmO z;|cu943p>LHaj;QBI^g&oRT_+V=p2NoK5X7Sw5;=Un*t}zLKm*^D=^D; zW=zlD&*>~v514^)rFvL(piYY~2A$SnBD}MAVObBbXye4P3LwSMAD(xYGzE=Wc-5wW z`9Nle{4*f_D5-n0J=#$qJFmB6^2X!+BI^rNIh!o3^&5gv-V~X-YfG=khylf;3mWE5 zq&zr4@1?wGd0XS}zkKn1Y{s$F*O5{CiPay&RkPx%Fz^W??Y_wKc-^f(`=zBhPPfub z;nR41asp)`Mc#Op{ehv-q%R{Unxxn%He|?Ix%{Rczo)84K7-+vaKEp-hws}9Z$9hJ zEx@P4OJGKYd7*!actq%p_G2+}a?$06O8l>$hCRbljskw!a>(c&6Q!d~&B5fJd;efV zrY*|BR=G_9jwf42-t1XqJtIT!xfFL0>99!u87@~cmq-Uw1Yeu9;vFjol6*_XLFmo* zcR)Z_>r@nq8ek*T@(m~2%x}HtFz9vt2CBv7K<~c(6J~QJ^O3YYt~Q3cU<<1jdryzC z<>YOTfj*BcT1&N%{+F^>4z1*!PQFIjI(T_=z|@m*UYX5{gv%S?UGd%^c_>FF+<|Xx zW;(}Mo=133IHERmaJCV_8}3Pkt62tDP)2<|C7l6HboGx1ucdO-xM%=0$+b2=Ow0aS z_FfupJ^qN+7ge9Wa^=iE*i>|&Io-&t_c3?YU_g&KNG}0$PJ&oJ;B*dqV*5HG6u1?u z{=XOQ3#QAS%+_y$Wdo*Zjq;N|#*ax+4M(12(yS7`c!|b=Wq3elsHU~Az{MiNVHN@9 zYz62oZyh$kQ*E$n3u|y_rZ35s5gP>^vDcVyq=3!fTV)R*(W`q7p|w#j*zhv_@^>Y6 z604vO%i9l!Xk=cS%CA?jzMNr;)gdlQG~~MjdnRSa2o;dQ$dLio8|rVdnm80GE!}Wj z?VW;9fa&Mk3b8eW^~(C?*>sjX7$Brk5??>_ZOxf|pgjKc$sbn-1EOTN7?{uIkFAkC zgusVPxJH478m2$QY)l$OleN93%=UM;`_zWYMSqr^Pbl^z9mJj!t-R!B2^y z0N~`a%}caQ#Y%aT%zo;2jcx#1YJ1$%?@5wD1+`3;nm)~)$jEw8=8TmHc4QOwkD4*_ z_7DcnwBc_F1<`<7TI@HPX3y49^2vmaz|7p}Y{Is9awLxz(=GMwC*BDG3z_bOOr6uZ zuNOgOJ`bt~MmUTQm$z<1e|?~M1otwGm4bm`qV!}tW*c2EkpfukNI>}^!~Vr!iB;x&y?;0bIf5&Q1)=SUpN( z-zs@_FSN${dW$f#8~j_dGeFYmG=bmk7pAB#(bMb3^*3cKo}Xj8?SeUT%<>^YN}Dq@ z2;4w>Gq{Ocf#)xvYvGYHx~h+cKlBK}?A=^hMOO?z2)x6a-Bn zW|-YPZk8x3ZzqE7*^s+g>pq25Ty;>_{)HP10I)K{;6@2x*2C~qwnwUA*i`ut15(~l zwkU+`$cSK_x6<5-Gi9$Ew@o|o%^}gMv|9&%D#Q`gj|iW8z!Nd52;M5Zf3e$H^J_K( zBbF3C&4EGVjG60{e2pKUPsFx&IA1Y(w49+5Ej{XZffg}oGl+Q>Fa#F0R4Bjx%Q_SCMssgw|@hImf$Qfc*RR2M%1X*x92* zc6wDizz?{mBA^1taS%Gj?0um0t+vm4re|uT&%|ThAXO4YZwG+(cS6E^u*akzzRGUO$~Q|p;KsEw-lJpug-1-i zr`X<~opSR|zlFgqu3<5jG#sl!|Qtz7E(?+Ap~d2tQ5}vswPlUk-4O z>igOnh07|AQlnuuXmIUb=B<0&X!;*JGLeyGh>hyxI~Mr^GCuO#KDBz>c;X6x>@b=m z{nx?IBp#>1(1jXKJs}ju3l|6AK-9L@FF+EpQKS}|EHPLa%?LyER?NQ=2u~5~7`2hi z0Jj#r5SFCug6Uf5?ErbE0(S(%s6gdH=f z2(3o}uz4LUzNk}X2r{OHlj^Zv1L-Z5&gf2GDKIZKK^3+Q?F(k0~s4rrSwn~K4+hOsaT6qYez%H*jB@=Zg`lJ(UtY_B$n7}0$Z*{sB5O{ zCGmNy+b+Xc~GtdKQ<^@({AL23pd}41T(O^ptQh>L{o!iT00Qn1*)T%mhPfZ zztc>E@dNNmyfhf+4eAwfgFeZw| zCLnFcdiTKgI9$Z@ts^6-ikNW63(t`}Y$TBo{&(gH1!yorg%Pzsmrce+%o&=unlS3a z;o2{Rvh6w+5x%!1`=If8co;||0QhgP;NCiHcO1_Mz^JS^%5ntmR?gjif%srI_-u?B z8e8GOLjkry8fh--G>c8^ zWC}W&5RH6=>Zg$lmZ5i$otsW$d@q|gOoF_fooLV4ai3L0i1xEl>0`&NL)iA0?TcrP zLDf^(3T1_hXk(J1c8nBy=glmJ=Kb2AbOt=q{Q$0^o?Fc;k=0fS#fARp4+b8Y$_3WY zQlFW>1mK{yWA!g-srT??fYbmE1XKi^(n@$B^(|G6so$%0o%jmW)w(U1O={ACS#?2! z(lLZdQbBvtfr*}OX-8W7*wD(7t|TR`)%3rLEO@A-x2LAuUrxv(-sjI+&XhIus0gZ4|Q)V!#)`kc~&g*OguQNdvO*${})?1*>5|qEQXTzX) zd7~N(-kA-H^jhKdT^b`lAafo+7DpA1Z@a_0gddTryFUAFuY=9bQmWE-lp-%Z;1cc) zR3?xs46&EDqO~jh#Gv>X+G(4~nHB`;?6_JtlucVgngQJ|?g4;Bt7~l4hD;!g z2%dx^PILLhsh$q1n78C~96Ad@!eM~8;z};JVwgWKnfeF=YJ}5(M*srBI>qBkMMK4e z<7H$rd+ul}dy$}MT(jVW$9mC|aN#^uD#K*TxYn~kZ9PCk$BFIGLVrsEzd5;k9KgAW zc2p06u@jv^NWT4w>PBg|zBDcd!l2+=pTXIdXb;wFI@vHC%R%h^87e60eUjE+{yUXo z4C1LM?%2{b{is1&FO)g5D^bgFq5ARpm$XI4IYO73UfkdUh51o1;1<}hCUMQr7HzP5 zB}lZh)R$a<1tL{8?`qamjZONdS$P?0Kx9Gy8nEoa2T>XvGsX7j2is}fcWc;dG<~s+ zG&>?t^s`QN1Rz`u?RO8q;Q~)^zKbkQ0sfgh=8t4m0v)SXW^)*k85IXv|!(bp`2aDcC%FjWte%aO>Dt&_J*M5=aV`OIJhEEPG>i?CV}aU zZVPv2HA`TGIO4gXv%}0ps2Sy@H+yL-Bv4qeVOFFW>=>kL5qNQ{H60Wad>rk#fwsie zfw0r4i!Sv6V6)s7z*fq!{heS1LIAJf6V;6b^meX z%ZC?Nzpj2jxK_cm3A<82l8|Nae=~}^ZCP4tGn|fS+QbUYUCEv3@nXiutE2!nU#fUE zNp}M6hx0gG5!bn-$i!0(B_9SsFG@GX|XQmE7lpVBr(Noizq-Dyau<3tg zb@OYU5ZnGde&n=MoRK>9ukdh?KpM2?ys3Y5jcF}!TR5iaqNWv4z7#X6QUs%eoGS1s zyiPbnSLOGQUNIS~;K+EyZM-76IkR$bT@1CWd4jEzLJJE-MFnVWFYqGrr_S46`3J7{ zfmh*0Q05v|1N)7yd~iir&&CU$t25|w1!$50$*>Pf0kMKwbJ1(yFq16`E4cdz@{Iay zdkTjjw(#SS3L6N(JlcNDYadX?YMv&WDZIAeIHMg9IM#))oxN^6CG^A3ofmlq;qTNC zxceD?BqJsu5Z2&ts2WSGf;fNmIM6NA=@(ICH@w3`h*D0yKU@$gw^B=d^P^2ed$EM2 z1+(tY$A+rlyDN@aG1p-6;0|<@W{S(9?mxVt>H-FpYnS`DGq_L+*;hd3w&W>eNB-T| z+mM%J4ml~n{V`~nK#>T(+6n{7yzTzHu-8}Px6|J1@KdsC*$q!2hUuQ8=EOzvtgr1j zMz)UHO3BKTWCs1G3M-Vh&N>T{95Te0GyqPkGUxMQ6QU=Gg%^}NnNsGhGvf(IQb2Fi@QI!bnxuo<> zdc0h5V^Xu%-0JA)B>V5m1A`hW%>=#J;w{ zG=`%Gpm@Mu;H3aurf}nlaFRFZdIK2R-YVTx(;Pdqew_Py;Z%uBM&T@PuJxRzz{vD; z@=qkgw>dH4Vj+cxg-2qgr^O=d-*4EFHzOGW2b!BAl*OUC7o^F0K1CW`RTpU!g8Y7) z)^P}V)lOtk&|$2FWbbE@LA+W{-on!+_MM&U)sLig|C-A-W4A(iK@h8c^ZmBxFk}n zyzPS}d|8=pR=a9518g1M3M+UN+cO#`kw@k?z)gie`C`hI{nRt3At}+?&7*Ngu6nq7 zA3YvjKtpQ!pT+P=Uu5h#wpydjrCS4EkcbURpkvBJSDJy9mqsGCd;Nni$Psxp1b~wDR@0Hr<;jrJE`pfZxbcB-jcAQW?o{Rd3iJac{f$8R%hR z5j8u8wIst{wMB$-9qDc1yoSbnw1kdy;e#cP6F5|9WSRGUi%@b&&?aF8F<$jiTYi~S zyT{sdsUnk}6<(kQF&ZW+mF@Wl1#FA(rC`f(%~HV}8m6Dm@>)n8OPcP*!|phNL{Ise zd(NtTCDLK+w=5MzuS=>DHpXdZ%~|$#CL_wrR!Tbj$86ScRE;O3_Jk58V8I8$^;C5B zLaOvyBoCAhP(II3ybi#vPfUzqS~5BEy4&h!;RgP>Ihn>-Ows7=9qFevR$pK8xNhfz zh9pc#%i@(R-vt8sGQ3&j2fQ>y2sXHTV>&_{t%g~b13Qkhyjrck>-31Na&0roUE?-e znr9$bRRk|2efBHj!ZQ@g;b%en4kb_94d^XuYNuszhQW&Bf|XvyF6Ufolm1s-`v9`b z^MJRknl`Mr)V7h3{m-Z-t0}4R6tF}fL?TbzPHF(@{L67*&C3jB4!$XxgIBv=Y=xMP zmy^HWv#vB#azPNKVd16ry5Hb3@EO_i-?;~%v6W-~qp%e0fLGEPfsUK=oSZve)seM} z7K}~L2A@28nm2twC1u?+P|Rf&pLwc@N=inzZsL(oGE&i=CPkaJ5q&fPr(yR@^#0Al zkj$eHRb)y&MSJFz?S5(N7yd%|_9qjIP^KuRQaV~r2{6kp?1eXGLq&$(IfYH(ymjxB z{3#t&!oC$ri?4iiyDa1AI7Zb;A+ZcZR%3=q-#@ObAt>~FY@;7x3vTW7T`iB!_G9Rz8mY!HP$>)(b`<8yg^?4Wp>5N1udmTx3oPR}Hr(bYU$)Zie9&C;CxY zn_R8R9ac*|&oJ(YNk+#ojZ0m-n2XPG=3F=BUKc=##6Rvyg^q!vl5Kfep0>YCE!BMo z^P3tXXa1Dse$#EAhuVocvhLsw@AR_qLJ@^6W9pv*m`xd(X68N zY`JYZ`_F{$MDVmH$z5d*g9(a0==`+FCaTj@2u~EF!-cN8D?Z#KT)kq@45os?RiDp; z`KbwAPP~(CZ&apYfe<&@R=&7Le!PqELGGC^F^S&ebnp9pe#5)WO>^k$MJnCcW2=_( zyHHM!@um2a756tat=U91(*+cAW!Pj6;HrKa{*E3s0EFGR)tZC_5=X8s9e^$$Z%Mxo z>Mx_7ph%^YvfES!C(tufTFBsMW5c%fR3FWgWicTRJyIge8EV}zD=TF4H?*2ibitaM zPmXb-#2kYU_(&@CZi}#Xe6vSOxFRKRmg3|4VF z@ejFa0oa7O?ce_f4R8R|^~DIl^U^~xNA@ai=U-5ZCknOJy9V7A-PVm>N#je}1;}gn z2a*42P&+LkxGo98(BjimXL13*daU&(B=)=l_4eZ%Drewhhtz;UCumuJCZoBb9gdRn z4Aqs_irqx|{?bW(TQ7;SVFa<#uLVr;_|6;riCWB0Qn_BG>N4w?(eSe?`cNp)XEI5W zEES@#{~^qRELmi z0O84#hv~GjB2e!@@9u0?5@nI5`;8`E0Z2XuNH}(T@f|;QS0Q}P3CcEErqab@m5Pse4TxePt z87KyU-8|AZSg^Z>DF!|jo>G@ODOJ#;4^NTkiwjoT~o5rJ3$NWLs|2xu1LXODyG~9XI-6Y}uW)m+6f=T-2Dc z;-VgLe_Vs!7>bWVINu=ZyIb?ah<7G#mD$k30*~|h`GolcjznC*=Pi)y)tM^1y;~|( z;@Ou;&_nN~Dt8uHzREDd_rMZiY{!25RDBYn4tFy{*W80oX2(XkFhRFcj?YQa&1iFR z-zK9w99)0%dZl-a^L|!Q2zTxCc;2l0m~TEw{qc)PTPAR9~HE zIko9ip?-XPUrwUK06U*@ z$!p#8_yPs91~Z45XWim*vWIKmXBx9z934Dg&z{$BUw<8E(8`0^U4Mb_NsV@H>Gu*S z>5EQ2Ge17i@Hx#^uIOjstr3;D-tIadgOZ{8-nt3#e;(fjDVyEtUiAj8`f+&XZ*vGa zN>UDaIowaQIXAm{E5dmQYscgHc|K;DN#6##{G0hap)Qj^2z7HEjszJS?P*=XkI}&w zhw1TFENV94eSezkU?raotEZWHhgm&uvm%VN9zKV;Ph{}EmOh$M6U(=2gX*G8*z}cE9T98|a3o~WmiycRHiwrAvc}gqL9t(8$lUm@4&YA# zgf(lS#iVX}VU0k$*et@@_TWqd>a(N)^+4hNOu<@EOdGcMA|swx3@#0Lq^ib9M4tfP z*ejVp+$K1Y&WYaoA>wB{f9j!;yzE|GKE@qAzmw%e(u~c*x#Y#Pevz1x07AJvh#X@z533f$QYCrjI3cyn6j_Lj?kc@9PDvC zM^})otL-z%gB_@f3(QH>TuZq@HCF`UXC7?=EQd5+lp%6k^ywYm_nvQQR!p8igkhJv zWR)O#hbTFunn0Qb2Gj1ptR!R{L+hai=Hf+4UBT$E=C|jQ^8GkA#){mrWQ9rlLy}Zm zgh<_c z9C9mN%?5SFb>w26j}a3RycVHyAqAwxS-fmdxL%95Af!wD2F<`(k&TYyC?0r}g?{C{ zdeFO=TJuNJkk%*B&$fTr50+VSh6@L8Y$b~64X6%6KiP*1Th@oel3KA6^oDrA03ZxL zs#@7{g;F?ZlYkQV0An$hSk#I*E|LRB#vdkA`aj)W;IhwlV?i_$W5ZpAvSJ8eL_7W#62oYfnXR`790~ z5-D{eiOX4pY;D+Kk~Jct`h^!sOR6Xy0d2y9Ivbo;g!Ft7!dr2%J`9M3NZ2=7448_! z^Y30T3wF3bY}mWxWYzb4*10+zQvJ-ar?qClBMrq3_}^}fY@cR+K~g)p8WtCG6$s?3 zpH{(2>CzC3xA)O8U2QAzbG$MtbZ1No@mihe0`UU6xzGAVO&5y3EFob_)kS*iR+mzkq|EE<^Z&{L|)XG3JwbFq>Y@^$<$;&1+Tvs5~MT zFL9rV1uS_2Iah{|$8wQ*{1aIP*kOOr5$s0yB0RIyzbFT8v=Zgg-8AqlP%uSgl)irm zGC{ZKz8s%)XK7c4sq@0i1y~`PSu*wP70;`pgn&rkm|zy@3sLF*LHOm{3V7m(xJ?8` zZ(#<&A6CzG#N(whM*Qq zasWm~h3|94hh$^PTT)tzzU#m_)N8i~p!7y>azPTzwje-cJk^?X)IoI&Z!V1Iq8Cb3}!R@2`Pylg=Cz9K%r%hSdee^+p zTGNy;2u2Ea_ob=YWUct?qOB}^idH3%Kma@iy<-$ss4ohHxb%gOj43zl{(9J3q>J{xF{|YBvT()B_t2rWTT{Mg z227O~g*Z$llrNRbbD6K89ZKmjK67eh@O}dKgodd4Bt_s`eP)+vDg>H7a81(*gxnb1 zo4@6O-q30#Fg0%SQ9Fvg*1Dro0i}#>ADGqJ3P834>%?U~g*$*rP zP39`#ml>3+=T221uoiw$3v99yr>eEHvA(Q&C=S8oL{|h^zDjRA%D4jQrmg!GnuHKF z#s3iX8#1;l{oKKZcKwMX2*Q~3l*krLwqiHT5|rU$S?>!HgUBG%{j5n{XHOY-gS8W% zspK(zdLIB;ZL~}V`RyP3G&9PO=*QiE{IGrNoD+ZA@<9PHsPEHS90^re4;Th4%2|Z$&F>IsI#0E?Jm049aq@ivdyv-0y1cZUidMjl{-|? ziOdaVimRk-8bL2B{k!hyrbosOU1kj_uE_mfVX!jIFb`>8`xP<&$Q96^LFB&+XyN#E zNb`mxKnoZQ+RN-4$ZJM07F)Uiq#zf7T{vjs)h=J`^C((yE#=KLAJuGh%u)<-V!(+O#i&C-9I$YqB>H84$lOkwO?Kn zxflW)Bn$qD%uLp2J|N}IH>S`ZsR$!tHbpEz7`%&q`L)`PRjW6esAw*dlJr$`lYYD0gtQ+_t zT8!ij@ZYZnsyALn>mnnQtTer_<$w-;q=_xnUjL8YQ5&w9Pe}Ujd>s)Is<7=v&TP}U zi<4*Y=`(>K5$IGr`in#S%R^ZoZ#8`UF!8&jdELLQ^p}T8gmre8hbBJWdU)bKBD#T7 z%X|eI6MN(Zgh|Ae#c_CP5V(SsTsEmrESB>eikWi+H4l?Hph>G;CeQu1C$Z0fI<$!H zFih-`9?>BtS#1{&(Rd6&b$`N5-&C>^F9orR)Do@8Q!p~h{03>zlE1l7q1*?tPHxz1 zq*-%(2f_ntDsy-Yd@5khtuY~|Td9!NV5mO@NaFo66tz)xyv@fgU0i06WFT4}4%JqS z;`3ly?!ViC*+9UtSe6(n_k_H+$PCP~`xX;nZNkR3nJd%#nt|xcsP6ulT6V?^`a-uL zmXU`N_z03f*?IIOMG!Fo!2TqO~c4F#4FDA^c% z8p%Qo1xiiJK$t`CrN{Upgc#&ysP(hUK-4`pT)cz&uYnfbOb1ic-E}yn`IfX|59Q+!;M_6eMd zjKGFNh{v|cY9`e#s8fmw{&tOfE{CQ!0GXJNg$#yb=XAgqgXa(#k$V6}ZdG8ikVY9L zM;=kIUbp8GeHCob_4VHX!@=Ynof7cpAI6wfbwAEOwBDfSIYX z={|?C2-K0?ZU(YNDHh-%`*cBKx#GH~$-8|w85MNlUHdq$o`1|pFC|H36=_2y(cELO zo|=047J0w$ISunLip{nCdQu9h%4O{Yps(3)1%Ss|ZwJUy;x{ZjRhf@UWdiv`C&?}2 zyAW;~7;@u2LuCMf7qUVm34O9EZEZ%F;<**X)G5ardI;9@NZ6s9xTFGhR9*XtPZm63 zJj>oVC436oU>~{kv7hd<+E9`B`6%%FX*0G_Guhn$r`uDIf8S4o6FC0i{}lbM3dAR$ z;js5|qwC1AMn&u76UEN(!>mxQmyuKXbnO+V>k6Kex6o9`O3}wVns+Kx8F6J8a2sH) zB~Qi0sWvLoC`N;<<^mNur~8GP7|f9cl}ASh~Oh=(7yLSflZhpIutuuoT_;g>Kz)B4l>NYhz7As zqU$<56^}D>!(sbH`xZlDT76D9IyV4rn%iHA>K&^P06-fJtWbbdckjaL>86cK;EQc$ zPY-UnP=eS%|BH8=Huw9|JpW8A6-PO2ymIr~k&Djw-YRa^8+6{U@NFOJwnF1b4$HoW zbFC}96}#^8XQzwHi=!L6R7ar)8@#a^02_b?p>hb?kqexnVe|08k!)Q@iiUu${)GTV zR3otS3-Qe`Q27#V--3~=jD_yycWD8|T~I-ze+Q~sbC&vHuJhx~Jt-UH3lV6krAA_{ z{Lxc@g_T`r?Xk6jozDi06TnOF^&U?JB8Q6kr&c&bf~+3jlw8mr9XSPj556mPcT3bm z9i|HbXobP^`kv9uV)lIEza2bHYO-0?3bzVkrUM9cd4U!T8B&**G;?|D)4xTn>h zXBHR0B(nrxv&GU@W)41_s?o9+s>Lw3Me`iTBZvBnS^et8j$SVr0h3PLlBYSrxbzQO zqx80xiQI&Oke}A?-i-h?cJd-_s}MsXETn!P(XH8!mB1HZgtl^1>lJ2~w$W5~{(Tnn z1Pk-8-TH_cTPX^^C%)yc+VgNf&3p3?f0W-=0hxv*EkC`V--4O$s$t9Fu}}~27`Z{& zse_wK!6M~F;39{f;9rVA6mVZ?zlqzxRy=DB2sqVRy<6Xl;@8SZEC$oR_RYC}uj z3iy0qe`mLmRRfcbB0B$F|MoUATGe)GIBJYmS1|>3s9Tmd%mmbqzT>KF~OoY~z4Vvsn+R zjhvm*Tv3H5>?K^7Ls9m3qCX=E?|Ta1V+j+Y*o?-;Omj&>htlFd>B5Uz{S1WLfl~+H z=2;cKZB80pqc8_~1tslAl3-qlm{ysjl_ha45{l-4wm?@r-Icn;v&a1_2MW_|EU4X1fycM2DVv zxDMi{n{~??Bse>F%0jw(E#umxLj&K@t*^(JHBN?gQqv*A=yG^TiKKJOJ|}bz%DuGl zk=MePYbXZK)N7|Zt0ZO5f#hcJC+K}5%R$k59QhpF8RVb6y@)`4GU+x(g?)W=iF1j3 z>U2TsT5nB%Q|X}5XXI*~*$wn<9;rdSy~*+d!*0Fc1c?Pr=j-Xl9Uq8lQ-5_{1cCVt zP_e3PCy1EVbR5S1xj>EwR#)SyA?|rn zn7F3E!-p+0F0okANUaNI7BTRa2c6cs?;o{*(Akc|8~9a)^mie+GI}$}2$TOoi>y%> zt0Ig%^?dpoTgHyi9Dl1&Uq6Thv3_VS@zyU~k8>B|(B(^F@bPW@b}@>yfO0OXf}c=8W-Le|WWlk?wuOdWNZoUt>v*pVjnI^skE0wR zUdU$~<4!LhzPJeB`uE@BcK8gyhnjhLh#IQ^eqZZSYHxj>Hvn2@+#g} z?MYp5gGZ6!?7Sj6*9%eOCj{~MG+?(A_0X&oLv3L>r{<4KU3Y*l#(=Dd_x4xog#Xgi z#r)2ZQnj`o7&@JRm0Zg-Pm(vzgCJBu@%DyJ`i&fHx zXJOjTxBUs`ro*(LQQNi^M7Q$yZuOU(+p6jNID>uOo-~3&RmjMfoZoSYzT+u@9LvJ6 zoavn6%zk#}o>%|w0_kozBS!3AUC7+>x^r1l&;g{zq3|0eO_%By5HjxG@IRxBVjBXD z4ae0R+PcB?s0zCfTL;D&f5$DV{<%A@agFq#QcP$7JM!ONYgz zxu{-mwOuVl*X8CJxfB}IouaV$4JR(ve3E;`Hz?rB0Z1(&hgpY$ ztR&X~Tj1cX{pG6RK=xSa9?p0Lru*iqpgHRyjTk;eXbAP-ompuxaKn!EHFhty>4O{ZUo(ZmO>H|+MI0zxp6wNo0Qv~qa@%(Si zyUsp*4WlCn;UGTHP}Hpylku-91R^l^$s}Vbbfg&+XLJJah#ecKpJd6+URTh8yAq_HR>G`ISa}~|!#OYj6@{91SCyf+=+V8r& zQ44$IGq0{Zy$Jg-xiVT23J<+2xGl>`_bOTgaNqfb2uBz{vdc@SQ-Re$>KBS0Q11M& z40s$+E%>RBA}7OnP{jQx;LKmr#9)J+szpwN?x~4%89g$L_mig34dYd!O!76&Ix&F< zmYP+qH&xGW&UXLtMh3_L+D~-jAV?x@Vyv-2iGbnb?*@+yS+-6|1Ols1(sdfJ7E(QizsEXOrYk?sMDBmatWuk*fT?+hkoy~=;-3T9#?F&d^q>h_Il4IC?{9i?|82&O)ie6@&y0P~ zZ0?9##B}iHbKNsgg0QuI_?Yx(rbr3T_pLSQPcch8loK2U* zO%2+gqx;1^!L;5*`Edg(Vq#9+%RAT;hRAzMTsCRH#mjw?;M{aSjM_m&NDuUNN*&QZ zBOV>I#}#iv^anCJG|QpFz(h639Ku4)ed?=_Bxb6Smx^JbH38(O?7%m_SF!n(O}{q3 z|FPkVlMNf%Siz2MYw|eYi#*2E=$iQ&Iq|Sb1kcfVv`)-8jfvHot)jE~ z^&3^x6FhjgFgstwQl+!+kogBE_qpb;4ifq@<45Q>V zlph|1NC!WR&*(M>dYHOt58P=%Fyqu)3~(k;ak%cVm;c#9W1Je~ zR4@Pv$K%e6Zb*YT?$|7OA5`lCt0E}k!28%B1`Gwo=LlDxBgE$jqmA<953N@kepuw| zJsR&+`O_Xj$Q0ekX&z~a!-RiwxmR0X3%ELq>G5x?s53r+^I@RIEbI9+>|qm&Cjr%eI&217N_GZE4g#E93Q%v{UIE*9|) z;KcYDbW3C>5@fwhXQ8}P)LMv0#5OK+iWdkHVs92QE+WC2Mp1GhRdw4c);pH76o5dB zc70wQ=>u8=O1f-#vA41W33xOliB!cgs*y82E(n!i`A}o;k&DR`1+a?UEAJ-5j7*ZG z=Nrm$l-3DUS~sMp2hpG6hG}9eNYTirR5c1T6T(0N_F_cyxd(;mVr8T4iQgGkERYwe zkZ_^r?0`8OpcwVrm4;(9)N%z;)+3$s?|3qD5p{5CXsd+B8BJZoR^zSa5)QEu^y*xS z>nG_tt~og=(rY%sy+j0WY5xnvSh)JQGgv;lWQJ}ts_WkDJfQ#!Mx$>-om2}tec(b$ zFiYCn%ETOc%l(xcYR$#bW5DI$Na}9Mm3Q3w_)3$b)4e*}GQL$4j&*COGTP(%?Boor z#X`0<9v!mX0whEal=6TvKC!>0cYnzAcjZwtFXWrUi(HjJnA1q+BPc?hieNtd(zuFY zgi`B9TSumCxPIVx#2y5gHl#w?;4WQP^39TgwwZNG7y~U=KZP$|@5R&3k2X&Ndt>t3#m>GUD4OiEQ6^~F|RNMpQU3skb zWOPT2#z-%Oxc7p@NbT{p`$pr|$B?$^Cq`~+Fhe5bqjdH|JkKd;I$kj`RNf!mb&T*N z1tCQ!63P6D%a<%!vl!XqyV@CA~yj-hP`yfJYB&Ha~`>IcTbi=48i9M7K@>jfd~9 zhl`NCW%6sUnV|u}y9-TUm{g`ung%mtq8fBY#w6i<1PbWLvCw&!jL^HIR)QXzCb@|lPYCxLvG&qh8%EYEp>Ok?S z1OGDCYgw@P5_ZNElyM#RD_8YR1wFeS^dPPX)}!$}xdeTU+gePkI?&r!<{FtoR{ z4%xRai%~pWR#phj1jI%nvVfd~X(u+bsC3qBGM7x9u!0vF05=bH@@2l;a%Elklx=ZF z3vJbSx}dsw63}X+WvI&A1SnrgL28>8f_B*D*kE=@(2=0CHHWRg-pV=IWWjb}a}u8M zC;1$y#iM}vnz_y@L5a^h5l{fo>?(#Jy}* zc`&!5%{@Us&)ue9!dcqogFYfMYMs@`%I&L(XrBde_9h-mV`pIg6rOe?MnV<{zf>>O2NE75a%I>==oPVDr;!r z!4CI|l56t54qWK3(7Qyd+6Z!F;`?;w3qp$DTsL z0a>4OjbgT~pTD6B;IXAYanewR4ABkT$vSrjvH$&@oh%L>vj*OqifpieA%v8%Zac!O zWN6K<7SqHi569|~iB3s<5KEFZ1|;+2jNF(<%Li3LqfK3#lnW@Cz=caZpvWkQ0O*`r zy1Xo#tKX0wXViw{myb2Ioj<2i;Cz!y38Cs2d8{jeEH&>}+Ea_qfZ=GNJNZU6#ODzh z0oGDWjGN<~oX@mpWBc?sVkKsu(v!s!w~_9m#M<@S`5W@A#6e7!!CbV{V)2w&!obvw z)UR80z9fDB^%I$Yw?HT2Jo7sTlOG&h9d900-x)Phj1_e9p^?6RG z*E*Wkke{s3`nxSKSlD*TePe0oH=mrE2iEb62Bddi#^w|gE%;D&Do0|+b z|3rSwa0jWqg=3&1ZicnjN_pN9&1rW-GzwqW1Qpa5e>uO*jfDDIm9bm$#!@HdLW_rc zyUAi5O!~khO$M9!*|)(%Km;HJLErkkpoOh0(xFF_2%Mv3QP3Bm^>@kp;PVdWhFau8 zu!Y~6A%Qu^C`8Wk4rN=C^+EJ~bIfom1U2?#fqUv85qgUaq2ZpfUD{OTdL6pfd!bSk z#^$>}hP?}CYihe!)c*E_X@+}f8B^N)`Hs_2pZuDsAFJ{msV*qtRdTzuQm$Q&VR>k- zDC-mJ#O9TCUu01E44B>nNTKOgQ~C;r7yYekoMQI8-R4#1Xmwbf4cXTZdYaDCiH1$a z8cB#gFXO;qB_j7A7kz95$mX&~zRiuoDXaWv^SyKAl%qo`x{vLbDP)fi)KC#~R=;5Y zc+7AK`r8lIE_G^7rkc8e94-#25`ft9Hd;6&W*X5|kfH<)!e*{doE4`kv`^Kl7_Hx4e1qi6NkWw=0;ngxiO!EBFSMoF!7|w zS(Ht!27C~!f4;|Uqbtu)P}hyOXe$evaHFdQz?!~fx%zl!oIEQ4g(E7VK>P(ez!6 zDV7$nwm?%%klgv!t7(3B6O56j zFTebtpjto>>+ZY+5C#9jTP`#Tnn?| zrZ`yU_CTBpo~{h?`s)ESfl&-q4zmwRkl^H{Ren;K(xABf{qg`Dt=E5r44i(ajZ-(J z@(MxS0T=V-KEXWS5LCtb-1{slqJbSOTzO~4=Sv=p8oXtdoL&|B+)wt8#&}r*NF^7)v zJe_^hjV1>fkuY7_6|)AMrvqKK5m*ieRn~qAz_*-Z{_cL)RHu9AWcz~7MY6@)ch175 z-TgalM*;q!vZu6f@z2ft?<8AraAIEjE1pc`6;##@bth1%lFKWsjI6z{h5qZ#!FiL7 ztVUdkjV$<$oq_2?j<>=L+3VTZK%_ewz0aa>yy){>U=4sEQHlGu0@ zgOmR47xk}M`&|H<`f3VJCRy$DWu*IrCWki+W0WWZU)P-&4?n~U3pq>IM688I!ZTHO zrD_3nzgUHSXJNJQjrBjGB{PRDdFY*E#s1Z z9SYzYi<466H4`MOrOnL2-|yP+5eLSloAq8ZW#QLPGT@?!n-@N*7F{P{K7{v@r2WI$ zI8;})gmD;bIJ`4t{=kkkypUSJ#nq_w*6Ti0pY{%t$_iBaTHNs|xs@ly0GRP$w%hto z3$nfvo0X1F?j4Vke|%Ri}>lH|FnanZ!LqQfW zv16^*zGSxZq$OU}ytRKf+O@_$4^a@f9IQuv!K{R)X<6#{*|d`__HG;NRV|aS$1U1* zwP52iDP*UzVl@2bf&m{9S(@A-xEaC7hx{$a;z4O#_+)DOJxiqBFi+Y}+(2H7eXXCu zxGm;6+n6N*;zW(j#~hxTKjMH2S(TLYJ)zv@AO`pY!oh=nC4YlXoHIaPKo;-QRJ#9l%c&r4vRq$aF z4x@AElBiVj0vI_^xmN@jxO4$9t{+Z!w{1)7g%1S{h?iJ4%y&W}fTh$KKP_y6rnxJ#} z^~X_pou1fmrloi33^3ug;w^b+$k!#C;Tm)))NAwbgpa!J=Y%g0%}wy)3u=f^juQMQ z)^oBeYIk`rrhh6W$GfM}KUGDn2mpJLlPB>!%0NZ_2e(NN-xJ_hO#)GB@)xH>#twhl=tWbMLTHKEBbc8 zO7sqXvGTugGP{uPsQm zt+y_)(D740D4DcM*6oZ@V?R4UD?k_>(i~)qvlOS2;n_8Zc&?wOZ%s=N!|O9vZt>XX$wt_c#fX3RwA_G zp;dnOVe%WG^+x<&%KG?TTWN;Hgr#004mkxQriYZIKG;pVbYf=J&xnf8W|^-ldaU%SUl54^zeV zyNtC&!unraL~Qa9*7Hw%R2+@pC7GRlRksV*nXxtBs_9!x#jS-e!$+ADd;+Q}LIfXq zSlinN8O{Hc2Had~X?34;U~>%kR^72M|~)@KL=cY;Vw)l2JVZCD8I4Czuh#8^tR-n12|# zc1(jW4Q$kBVz-JV7()7}Qpb z3m3ZX8Kq^`ZkVeQuN#?mL|FFh5_wm{#DY@d7S^BbQ~cGJf=wYY!ou&*4_8d+5a% zml=P{zbO5QZ(vfs(;HxS^xavh!34sfHKF7zUPvW~9n}Pj#3s7TTcIRc1Irh9lb3VzN)&O+L7$Y+&P8c$a7fYc14V(w^lN$FGqO;OK{X?@G{Is((EbrQs&5C;n!# z{qS-Q-A+7X)|KR=*2yX8Fj^Qp{~o}B%ex`T|$`jKU~REl|le@87+%*B_1-b?~40 z9C&*N?*J_CieI*!NFWujYC9M>D8|;Mh@pC}*F`R7;bU?B7r2GGI^_S`asS`V^?$b6 z%&aU-|Gnd8`5$)NtpBSWH@BsucB}m^d-hMrC$-VYE6A-Vr}e0LPBzn`+C^$fjVO}2 zyrI03kVMMUWhZnNFqO{f!;U0rL&3cpOki7|LA@>2%a`#WX^;Nf?ANZTDp~K_h)vFJ zR^7Di{_ZK6FZ;fJpUKZ`W92k0{vg3jzUjl%_P4ONMp3KgM-K8+r`mr>95ZS z=|6Y<%M(&&0{yLQE??q*-1Vikj<3`#|J?OiI$751#6?bbgRG{St z3W=u=PuOQ@Q~Z%XH=bEB=ErW_xJ~S;Gicwn37ih8%tKyngOYT>62m2AV`fE7e}L`G$)N?6YYa( z5YSK@_!>;FOHAabckg=zA8JjDaxCSgy@v`S{)-RjYFCVm{T&B+XCM_x;sqp}dNPTk zJ3RpB<7(=W-!K4`KXyhC1_D7aJ8UvZ;s-rIS%p$+Dx$%jFrCp9ub2)t1y~pk*K7}6 zwq$2QpyA)XH`T@rA#$<)JEaF!`d@F3&9D zABxlew|_fw%PS|dw&QQ_^mJ?cd&#IGcYX~Z6iK2KZzTcEbTT!8!-2^@BrD}<4j1C2zQxdA4l7G6n~ zzS;W=pl_5US3c{yuUG%?^3gp``?XIu*?G<@5QUUc|J?rbk_bgb`{MatMc zJqh*Lr@MWpF&3v1FHmc2xZ+?Fky`j_!pRy-`DA0G>jVq5HLOB8`;+Gdk^uSZ=@&?# z&p;Ow4JroH>svZv#!Q}_$82VLADGXKcO|1K(0MSEXH0c-Fk|*ia1*6HFDULL2dnZ) zhh~K+ziByyQ%J#C!E%YRj8b#jt0bZ@2%i-ajOFIa9tP$@26Pi7>anOsGRwE+f+Kjd zx6IOGP_zbMnqI=o>-P0d0_Sh~XVAo~a=0ZJbf5r;GN4fql)U7eA;mLJ9>P2#8e2bc zbGt9@%>gbUASTFI(HA`d=bVC8GM#S%M^?kH%3EB7yoCYQyVdZRS9ttkP0(A+%08Yr zxJ=GE0u&(b4L^9GkEREl+`&#jQ!*QH-oQ>I60e5BmCAu{Go`>d4BJY?p4Na@A{WrH z+xM(rG)0oH496B{RM0pr$CqtJ=c91wZYA6*0Jt37{J!LDKL-wJTAB-d$spudBOEW# zk$NaP-EWgqTT5;f+$vlh0r!7S?Q>{xzHOqz^33gF9yWsU;_OF)(IWh?pWjx`rHMW8 zy>o*Z)in_Ij{4CpkkgYKzw*6mxWG#h7^MT)|E_a`4P_xpyTA)fy~(e0_uWRNlNJKH z4oi>Skk2PHc;;;?1)RE^^U$=Lp5H*Jfu?A%q&?`I!QCcM#KSjCDnv^7MaIM;2E$pZbx=G#aoq;&ot@r2 zIjMDglsDsm2H?Jtc`4&u|9v98oR3&cWRyzc$VISgHwPxpYuFcG`O&uV$&$b2LHhT{nPDb;1A`MPXoT1aP0~ zP{KLptpJ*vMFW`+HS$eOKm^06W5-eMM)#&i1R<3fEg$KQ$=)%qSgK4C#PK)JYc8pI zyk8i1Lns2mDYaw33(`vv+TAm&0Wm9D6cuyExx(1xR`ic4lJ3Q6^E>`iZWp6Ri*yaj z2{IpRJ_KA6-hm|z%Q$6_yaD*EZV<2lSr!ll2Ap*|hD7*=g&=CfP~wfXiKe zM@eJ0Lb0FS56lh(#69U3_}&fS9MZC|-!pZNZ||qPGb&gVwENVL5!d#y!aY!dsT@3>gSy_hWNzAk+;$(3YjGK}}EOkYe^N>SHT0@RI zs=@0dRcp}F0S-EgrGZ>HRmm@tmiVihx>E@#foks z@Yh0yCe^E`LZbs#FlUqv1lxFswZ*BtzbYFhMB4=9KvR28w=X_#3a0~x1B0pFHgBv+ z44lt?!*^M-mH!aGDOZS3B%%bBF}YIfJuuBtkAD~KWsD4Sk__?ja*G)8=aIc?_E<;% z+jQIAaK;m&w|A!7*71>rmA2!tr~DK)ari`g;C8fY@Y_;!KDZeJbn9>F@R8S8h<{-d z%`;94>|yZ$Ch1C7A@>N9p)^W-AiFUWpsoY_)O0KWz6r!FBl%md861a*-y09VD!dYh2Tl{6|RU+YuGD+Kt0-M zKeZ2_U%7SNeik~J%aZ}CYA7&za1R%B48aYKTyqi}-ouY4U57^sZ1rI77Bs)OF|Yy{ zzM)F^iQQi@jK~R%ii-0$jAo~&au0p?(Y*k09HkDgNlejW4T{HFdk&hUf>#k*@t}Hl zvUHjeqz3eu_+Ut8PYI%)FCE$TB;>CSun*>TmhwhZy z@s5-vmNWQYAu4jVF>xCd`1u06+;I$2ELv{xGLr{#)OU@`PSbweO(1n+9D?o6i6+OFd_A9#(r^})q-Y291 z{l_OHH~X1A6f%gZ;xOcpSIe)78T>G~Sl62fMO2YPH)7M{bfWg)r=)?(P++X~0BQ?T zDVj#fUdm7X&SC%ygP^nYku3XhJ;sP%O^--mD176B=u7?{nd#{lN#oU{W0pKQ(Ryw< zZu$3z)jyO>O3Zcwf2@14R-y#=G~D-?aEicU5dHnzkx5m}lA^G4MZK;4gIs3@6gZY} z+mT5$(>IC-^dhd+1PmSn7LYNNXLoJCrlPOTLvBI|xa^t|c17T`GnzAY{w}bblX*5> zLHjhzZZ;SD+~;O_sRpl;I8~qX^DOE88mR0dVZDLfXN5RqMpIp2))`)SA8IV3($;Ab z6T-nsY0`~X39gFPvahyv9_!E5cW*z4WDr~wyF@Ru-sgJcx&S8~vY)Ubw_WU9!w!s~ z@qk9_zs)-Yh=%5sEgOXgoc%t{wed&+{HLI7qV{hC`sdSzSWcTyc6d-p@o7l{hoB8A z#?+n*3SkkI1W-$$QCMc9oDrR6T*;D2A~aT~xz+&}(6F+0G*v)_2qtVGkW14ijd|}A zLraxi%iJF`lze(`)wnUJ{rydd3RlW<9sSS&)N<)<0{!$KY+qARlBJ3WEB(496ztV{ zReO1%W{xn(F*o-WX}3B(byOXJsEXYq6FZEHs=n3oN9!A}f0NqD40`#a`pp-O^G_Tn zt-@*O&e&@Eqx41Bng5fKw-N6l4?)3FB<_pw&G|lJu06)_O~5#ZdgD4ezouDFr71*s zcPsP3g**0Ch)JLZ5OCX3%)lH$>yEIi6)QXnm6Ex~MNHbhAu29Vn80leUChEBHXd|= zD+*SdqQ)YDW}(U=;o~%v7ho}&tur>Q6{Bwe4t0(BN+A-?6+qvtNB}ZjI)?m{UUuh_ zqnHq)Q*0`mVB7Pyd>2MF%v|?27dBi>*{t}j<>&N?g5{N(_}XPznoQf-C4WTycGl{4 znjo4`U3h!8$w2chaE$*KZTC?cjMdaP^4pkD`GrNx1Kjs+PS>AyO^pmnQ5&bh zY}urxX(LG_6MEHTmsH35Fg4E?lL{QU82BoyP6rC*(T(hKMuWcIUW&Ff5H-F2cC8O+Aqrg`jDbmv5 zG)UMD!Nz`1Go6|PNSS}lHn{x-;pZtz&dZZN)=$dUn+L8;OLo_33^O6_Xh&XWc)+Xs^nqK1oL( zV~POfM5A^#SCz}@WqUPSJMeIU=LG^7<w*p%DCQ#xIDihqmetybv&hLA42jwSBz{ z0I19!lu5|}rhx##a1q&uNmOc~L$m}Guc(IylFy4p(h&Wjq6=Htdzhfe%F}aGq)9zr&z2V&O=o~0tjmmWlOcurctk9!QYN4)XcGRhelKtk z6Y;FL0dQX2#{U>MSOO^a8+;{sJ_H$Ko=(WG z(F2F6V2H=JihCO}agvk)->wkkSH%b@~yc2ZI}dL36LR(7$z`XQwXoS ziTXaC)E)hu_XS5j5K;fGI4IM;)ChTQQ!SU>X4wr&9dNz@xVdCRD1!LI#u31?I2fVB zGx4=B+(#)1|bReq%>iG4{gG>%#P*jnFn} z|AdQ!`je=O89Se&0YUS+1+|VsDg~G=fMSahc{N=5)@D#7%|n1rHt%}YOmtaC(^Cf; zzk4ekjn9DdbJNU}4!{OQlB#>2z1INm-9s2Q`qWRK)fOsNS)0j~0To)C|l_WbMs|F~&XPMc$CZ&V9H zTSiGoCajvAF`bzsgYQM%whp`^AIH6@4DhH0Pf#;+$HG%>FV9t}r-WocC6GA+M-t;l7_5y$u{YZTKO z6CPKQJ?7b^?D+mRqrCfi1sA{2g-1ekIA%@vwBXo43Ksz~IE zN${8vr5OqBoF1LEF0G|WVW_ePY*YS>K$&H6TJ^oI0E1N-LZ1XI%-%-f**+BRT4a?! z;m)f(V&1u&UT;?gvdYl@JHyjB8Tsq1;apuQayly5J;>?+l+*{UZu+1CUw7W+GH~?N zTRBfegDQQV{l_U8Nd^D(JLzRdOIjxCg%6@j8b&j+I*N@e3(==1{U4cyzfd`(0CHLT zb>bJFWQh4wq0F&TP58*wj@}B&q-(;dCnB&7O8%8`)Bm2x!mud?Eq&Qf)o*@sb$~cO zPtEntCetL{z#%;}*-^-<+#(!We|@6Cb6TwqqjnyIHi^(sE!&?jkzhZoNzYLK-!s{) z@dZ0U6`TmH&o_ce8Xc)jR8V(Tn@&S%N}-XgP{zLVoI((i5&ZzvnV>U2VLslY*sgqc zgj5uK9&W9($Y12EOZba}{WO~$Ml?5h^{;11k+i$!R4*2VJ=KjZMAN`^IykQC-s$x% z`I_K;kzM-AHjgk`!v#+76@*)lPIsTpt@qk;M{ZOYxmri%u!+_%PHTfLG0!fPl5Z&A z+5?mYYLfhVG&@pCLdy<$$$?(9p~vdwh-;$)dpmL(o4(d-UvKnJLLDM=ndGvDe|V- z;=~>I1#N{_2~hJB*r^9M(TIFyk~A}irxc|O@E#thf_Cc@_QqhXcFv!8(6dQxDfwtk z!tUl(@y5*^co`h)Ref=jumT@{sP)S1rpuPm75vy! zu%VU%(Vg4}EOMS2H>`8sX_6Z*k1VOvap{H0R7quDht>Eze`>~Ro|hAb4^N=^Apg>V zl5wb|!N%=#9IjU=gJVX9cHl)-;d=dD^ z#}Cw_$R8=fk`Iel{!A7&tbs0chX%H5{iA^ufOi(-i&ed6%)c#YU97|t|ErKB9A_*R z`>jj{FdsfBPB3p%UVa@qbQ;4Y!0gf~ugcdm_&q=R1=O?1!1x~&r2ptb{{?7bVfcUD zAq))vLrQ|-f0dHx=3Y<0X}7<93hDK?y@_|32*!@P2A^#43K~dBb$a7Z_>+>Qt!q@Og(;GV;9aq+IvXYf*C+IK&>~r} zEyztwA5ujlI@IXNUCvInBh#{+@(1a4MLQ>4En zTmv{9k*;K?jcILQYiTA^X9H270C_&3!+j0&$&)>>=|-pBNJRr5^snS8mS|Vs=oXNu z5SeHD_mB3+Hs-S4nPWpv*9>Z&$_#CcyC(_vzku62c}(0yutUW{t;TGOAV#CxZgvQx zPHqlYdj@XcUF35I*PU~KfE?(6hWdKdg*P5xXH;XYN~rTQteZ~U{d>YS@^U*xFzXkg4n$!t4fsBk4ZYN(K!%ji6-RK>@T% zE=gjT+3~dFZt=u3(6OBCqtPHQ0Kip5b8TpDqmG?cwr&l9$hF=|3;d_q$R2`5}#<+MdY;02~Ex`IvXSO|M%J}jg(+=W5g0xJZKwZ-1j(;!f^ z-%c@j8MS=eVS4_P$D<619LtI4!^$ZnzpY=K*a^@@sxKP;IpE3?&62r}$R#*82sLA9 zci$qq9liy6Q6UKQ4MA_sJE0t6_0b8fPn zWXLF9bOV$V&^ychn2AFbo+~Z!PRG#U5{x*=$sbg%u4=@3-Tvpg$N}kgv0_$9ov<7c zS_q98+@T43lTQk#pxP^=9|VPwQA~9C2Ndvy8%NQZlAZg0_cuyX=4@(~P&zxp?4X^( zJbsC0#W-gs2Ax?EHFbVGP33r!+CE&2`h4GWa5FIO;bMV4j-VMuhzqkac(H~Z8b>KI zTY{tN=#jNG3#dhGe{Br(yw3IF9{qKUim_#A23|`rIhH+i5(U4Q8g8Vfg}nPwF)_;w z`sv5zql9z#nMd!(!-$@)fmvDXB%sjoUf~WNwp(~)SUpr!1z5LgC~TxZV}wgOQ~LL= zK{U$wcclT9RW;Np3yY4SJ=EW6g)utzig_@})ynJE_*o@9lx=_a`!S)LNXp+; zWslXn#py#Vm}VzY_Ma}GK!Q|Dl!JMU+pjdyIL@HYnUO)w<+32`w~JeWS1+AO+9(UZ z5on_=!m~I-(36{bDlc;q(YPDJal?q?)-s){uK`kG*X58-QwZM}+Kz+$x)t1o-SZO( zhy^z=zNj?3V-3Ze9%~~@itt=a>lo;0T8Dq?IvL@=kget!-ew_rpD!SF^Do_E#*PJ& zF3+8kvC>cq1eDTQ))4A>=t&qsZI4nw+8l@sKxIz5F61hwSOfXg_Pe~yX3?7cFJaN- zxkfV;&tb31_MmX~(+r0KkI5Uxwg7G z8jr!$MkuU2!zRW;#+wXa)Q2dJOFTgPFC2oX?E*ZLQ1dpQYSP|_+C@wdXp^nqAm_1i z5D9rt5l}EG3cXUDxYBA&h28{?YO`j%7@KJpAfAe()x#PiwYTX71{t9Y9987N?4i>R zQk{bX%O?rggww&)f33s`oKy;~wI`MfE^Nt0WLEYXGHf~k-(4yP?>eNn*}HRLJ-5?o zzv1{n!R9;M!+Eab?M2a*R^2jTP`vDEPfg)6V5>2Juho?i;0&qguUUR2)pZpJ{a}Ne z8G*{?;WFo-aGhdS$D4u5BnH!AqMdTzdJen?05SAg8o9Fkr`_HWQowH-lm)S?S+D13 zv~m!?eQa>S2w3|37SSP4D&r)_4U^zf^}Hfx*tLTG*a-U}{90`G$&N1|j=b$;`%?QQ`_lXP?^BIRpYm7xI0L_wK&~bPPZvm#iyiTE#)LwXK(vXZ4N%VaV`}_hNyP zcL65$zsc;+!jI;O*q6C2CSX0QN{J=5<$8XUXb{@L$3_jjTNyt=0T}ey`?cjL-}>5Q z*Vwn+CVwDxr9}wosgGnDK7iBkb0^^BV>nfA?j(n{W*=N#x#tBsHX`k8idVKdN?O;o zKGr*NNZ?7GqouskT4RsSE3iIQZDcP zoXy5eP%od7mm~YKFmFtfTXNP5LY6HO=T6km0s2b(1QYNFZ!^`mDq|%sH}j8)beBBI zwX6gqmCs9wpHM~^FI*05Iw$pnIcSakR>b5+5Ow;Q>$+HY1d{4ZRNY!Qe;D^DK}=fr z(Owi+r+VmWDurz^ZGd^8pY@v9FvVCn9ro=>PvBHs&Nxt9ORot4buS%Oy87>nxr)NnSs-=W2p$4Y{!*BWBT%6#L`Cx4iE^Quhor zDUf3^hk-em)s@Z)%MtpS7;v!AnMukkJ#Hv4r8=bzg%tE{Uy*pihr~%4%?s(XrP!xN zVGgGQ1~!AWNR{$F_(?(oexLi%V3z7|hCTUPsg+-9oj;ZtZxG?2-q}lRdbWJ@87+|e z6`MYt1>@@oirRr$QO^8<`|AWlBH9YzDAgKJ)|h=M{m}xSE?--%nVwkVRnW&$#7b5y z{99);Ev}**MJ^(P^E4;bv^u{N4R1q}(I;~4D@H{b;=}VIh7PI!a0Iv;(2O~SL`63Z zm(%zhuyw%qb|?7ED&O_ZV@OmtDVrJF1G;!3?(PRL!w$|yHCMxsAD9}Qi`eY{TbWvi z53Gf)-EDiZz3Jf|2uzjd&sq4OE4#ZfT0qGnOqHbADkv1R8k}3_f1e^d^9^k1Rb00z zuwBhc%u%rtvZ?S@jM8uaw;`z=H#nU+)ADAp$7JN=ex?9Ze)}(<4l>wphg7Kv-oX?i zvOypiGwbBcQPf-`nGuYNB9Gq(oarRt9Kbwr@9Mm;kAId4hql z^O{$INTlwr6`ip$aie%ghN5K+W^vigIAIK{-jr+M7O1#pzdH(9g2AFMtdWZDbazQhXq&F?H{` z6q&!FUgYvh)~TFRyxcDMC%c?YxN~(3h6W-gWm+rSApz{)a~}UJI~WR~<=VURe`$nW zcNj?HV|m^q-W+>xw2yFE#MKfx!({BvtBHOgG!^b~0$zl0msI5lmWk*1Y}CEs=n70SN8~;zuHVGz z`-|$`VE1W08%(tfmb?^(+?7ZKqXCTb%-%?bZrAKz8MY-n>dSE^$gFX``_=o!ESf4% z1fKPQKi|Ki%Gl79|7MiQC@C_7m{QLGL-#fJ7xt&f%Y~PX2_Vpi6->9(IJ=fd~2e6|K5$ z^!bM*aUbZ>-dW;aB~B?S+@w0a%v3T{1}o)F0CLPHJ=7=ttCjv3f#myS2w-bh(|d*m zy)8k+Hz4e)zygH2b@B;wKC~{xz^+^TJw%CVE+0oR<;HXh#mLZ6B*>A43Otl^F^Dyu z^cb{}_Rys$MPh`?jw)CY@@)O_S0St#i)l*mW=QJTety+V&+H)C7 za}NtWi-2&JId=PlbZ6}`Ve!FOoo3{8Gs6jDsolk;))cC4Y$HiW4b&J?Pmb3LS7#Y4 zUZ<}~*%z;3p45CnT%cE#uxX+?TE2OVa){%4&R@64cEF=RE9Ug|PjWR`E|A86fVJUl zFXZ6}Zs#uL&ARZ*IM-yBuRvlnda1$ZDvGCLCY|!)wUPNF;pE#kQF=Ud3>khd&S>Dk z^MmFVPP310UDoN5a5vB%tJ&+u6}2by$H`-noyNID)sREH&hX-uzj*^Fc@tM6B1{h@ zbxZo3VKGu0_gFCrcSi&UsiJ;)mt_<9-9}H?`+f&q)fR9c?HUZGZ!^r|@f0i;Wh(!h z(8k~Jn_`3;0di)&Om(f23>fhf^h};c9P$Nm8Aw~3ABw|?$N}NNjF(WMl zl(zQVLo-1{pok@Bz9e6XsPy$*gCjlC7Rj>Iy96DS_itSmf)t+^Udcg3j}-SY1EUX- z+76x;NUE623Krk+88_Q~3%o;F>bTPsN-y5{HK{xK+ACn9a`LUET7yl55wPNIob+IA ze6dSAvJqvKRPbmVOKgXc9!H~cNw({_(A$hejCv{z0F+?bYelx2gG&2tL+8hL2Ab4q z)-yc_-o6nOHmr##f7HKT@p-z_f!v59uaG=7coHPH5R*~sO&kMK+nS;mX2G3QB~krR zNUAA|Vf~jJ`epfTd2QW{NYuwW`^ASR&;Ss${nZjmz>! zIg2Q#3eWbgc?%{|G<7W%c?@)NZsdzD$vp))M9LWEerH0o6|TX3zkc{*#!1QUSdVB= zzLQOhNbKNw@v%U`YNG>e{K~JB0Jgp?oEKt1fuCA8&U1DlWRg8|<*_1XY+V|_T@KJM ztRb?hFIw%_xCDqbs=!@B1%Hl(i4ht{v(A$aO$6kpj2$w{{KZs&-Uf67@9^hFwOoeT zsbF>eEYSos9BCAk^O<@uNK4h`fpZ%}SmGE!KP}6jH5W|kGkdzVO3y3d!IvtsftD)v zR>B0crPC%L{aNB6v%-Eoo8~_hjS@uas?#!vetIOzvk5H63SfCGW%UPd==y8w{b9G@CuS=P ziU2QQN3)RZ%=?q54QE+iG8W0uc$(^m2j77=D5Wws%-vAtB`Y6GR8IZ?F*O=FzeCi| zTv%`d?)LbEBoHeO$tWx=sF9 zx{LjR7ydY`__&Cc*liF(cih8IKZ^)>3`46gINAO93zLleTE^I6ae4 z5F;iurEFkjNwqU!wu@?euAFZmAc=$VctJC5Z4p}=Zo>8Gy)dusA(;_(iLq)~U8x}! z+RM1FhjKNrHWEMF(!QKGr$7G|ylwyI&ZVPz{}v+k(?kC7Q6g^dl6VIp)j3g*Jle2% zhvguyqTu_$0&(2cJjNOK53`$;W#!8h!?|lkcQ}n$=oazXB|RYu|7E6CJxeIoEc%MF z%60M;8*nbln(L^v0WEMLs;3r9yTjk>4T{Nm_G}^``?kSY?+ZO-PB)*!bOGZJ7&F3tBF?G_}p)~GvzT6ow@7%C3VB%5w$8t>gN z^oXdDhMrbSVqq?Wn(I**MI&W}3;RmHr0xUkm^jGd9_4H#TRTTkG%O9-M}DwAk5qD2 znK2AV@{oD@%0Bl!4b;f#r*+YNrksB}Ym8T)T!P1}y$|cDZq}^xq}j3G9Sj~Ibl4h! zt=GeVv{GI8wRNusyKP|jY?=frQ@y&iT*Ji=#?MJpe;Izc2gW{F5?*U2{?I6OY|1%X zsY;}|q}~)OOU%CSjtOLsL^SwwRi5K5qynnhN^^-$hn{`Lz=siDlHlS84YS0DZpo{I z-#luEn5aWtf^Pz>iWrY=s$wS_iQu`;bMv9jEjdvtA8J>-FSbn4B|7U+@i%>!DRed} zCOes82}x3IR+5J~&O)ckFCSkI!@9&|;D(;N;1Ze}_}E)A6=8?0Ti}hJZEO)|-_(VmQOX+P&jp(NV z{)uyk46z~DZaHb+#J;b}S9f;#1=;=ZMankc&(Aj4#!`uVM=s)}IEK=;-3fayzPvk2>7a(IA7>@CNKMeF2fR(umQ=DZ;KmoHD-doi zD{oGUl-5QW~M6 zI}Ov6E|ShY1w!^D$Cg__?Jg+yKm^{B0aM(1(fh%-1*uX&ua+v|##&CXWsu7^^T)bEC8G%H&g0>8S6GAlG7~LQs^vACRtpvi8f!V9))O(YSOCnilKE408|+h zr2mv59uZY#Tzs%FkZGwi$KQ8oKJpUu{BU+^hC}7VU*Pxa~f4jLZdHkNiMwKt1>F+$#hMPd?$riU-$$0B(2Mf z=>jjp&rqd*K)qS`c;INW3#==ERb8G?pB)qQ>xXQ}ddz2(>NeVuswu7x;L-;aL+7T00Qeo@nN zk}5!>Reov#9FFA{*)7ooO`6?g1+FiSbm^BRdZ^R8_3wUxOJ8xr^8w;+saEDBdh4k{ z=tmpL?&-wH(JiW*(D%p&&N*0)pPBxWDf4}-V;SL8ip#<~{^JKZe*#r2tRP3MgV&ka z_q{Wq5aoQDY^pP}DE+wPL^_SAB=*Wjcmhvi;v=dt4}QYgKnuv+5#AA6InB)Lc?vx0_9{f5$&;t z+eXzyN3mN28TrQHC<>YX5UgxkP{1{_;_tXAskUNuG3`a`8zy!OFPMD-o;Zcxk?;Vc1nW&yMJ*A6RHpr4 z@*<!kHuEG6dBT43-mVgB{3I!ny6q~MD39{O<62f!#FjsdP87^Eq;H_k>8$ z|2|6{e@i<4Fd=xOBM8=<+0co>DuJGY z=ZAHXePP{KP=|I$Rv=LDie2ITQPMiC^(plh-J29;Bq9Hex+Yu-v)Im3L^qaZ0cI>o zF?-YT8uiT32k4JxGww%;aWrg@!=%;%VFJAT>Sf?KME0SV@ZGuL{A>M6?VdMPImBTsSSuy=sAZ#!}k*^I9QwCQ|$Y{BH$WTp6~zDP$yWFs=N-r{a^O!Gc?4PHnyE`3T8=s zTSBvQ3Md>5P5O4>*zVH9ej_v*b-XmPJLdVm-8kP6tarXIJ8&f}Mr<4IqA5!QdmkuL z=WuOc(!pG{H37Q(Mw`lQ&n&9Ry!Y*(kOllxr#F<|OZwT5B0x~L{fp4!p3C|rPW|%F z9p*r!bBy~Ck6z^mmJs<>z14Ccxn?7kjIS=OuJr8<<60O*f{%?n`IO2@ba79*-j|U7 zhP3$rp@{B_aMjfsL>xpGGfkbjNBN@Nyd-_?VJo4a~pX|LS1Yl>Vf=+?K!a>ZWnrziA#=&i)y-VBenkVnGX-UtqesOEfqNiBa4 z>z*6}VsBGhy6fB;K!8Z{^?Xekl?RoRO$gtiI;)=hx1od(7O>WA85tp9ISs1#PgidTJRK*xBh%09_OaZMR$6 zJ7Is~$jq6kP|g(j;vd}{o)6o%$KQwF;MV_N5B)Ed^FMkhDfn=mBntCzz}T6gvqQ`Oe;7N5AW?uW&6aK3wr$(CZQFLevhAu@wr$(C?W%r% zN6gG(deNKQXGAVC?)|=V&;s4r*GbkuI$MHx*0Ms26G;b&W2-SG@qRy4P{+*@WnVan z*9C(>f(R<%vuOUfzF!Rd{OHg;= zQp4L{9CF)8QFd|j^tPcyFL3om+tbrEvoXlgiw^r&2ucLwi(<1fcofV&lkZ zAe->xG?lRQv(M_Q3+2|2R!`>P|4wEoIw30dYvJqnf3Ogbt+2gxu?)~IR6a^0rvWUM zu;c0Xy>Of^?}MQc933=scl9dxL2i6dmh38RdZ5bcrO(UZ-Z;X%<+0XPEX63{+9m#> z$bRYYyaz3Md4A(q!|bZ!1@ksDatIe^D1(VsMN(Ugtr3D*TZd?dD1h_t=9?;lycQx; z^}1x4lBIT-=!e`3qbNb%Os-#vT)Z7fA9R0GvBbxP5d#LPdf;kG4U4VQrEu#T{8&bx zaCQr89(XFnX%s+PicWaBb8mh}Tc;Zlz^-SrNABc0_1L{#g|qBX^P+hISEF4_v0bht zY`42qHNrhSax0j@R(+YEHr;Dp!t^k4me8Wgke8%GA|Y+;c_3ry);HYbKB}Z?csl9a zAQ2LQ;9_aqEv?s82rp}9)>q@RHURTWO+zOUp&AnvclM)vCfW~e62zxd(QrX%z>IJ{ zS2fk6gN?6bfr;m(0W5upc9Kf1psQ&RQ04i;$}(ddSV({G`fX&Rw^laN2QMzEnUw#B zNuhEF$guYeM#B=&{@TB~r|$t;X2|@#6vjOtPC(l^6waguk>*kI(m5&+wBN~N19N-H zzJ13KUwuF6ztvO;6*mFrB<3hsXxF5T&J~?3sWpC!ckx+)^D8o8m9J{r<-qk;J{exFoDd*zGp&c;Mk9n^UQNWj5@6qr?P2k9~1~`~=tyMxOV!jkR9S{cSg=a#UK) z?6Fn!z!FUwclRe3&rj3;tDxt>?HcT0Wj(WJwZ0#_?mI)I3FfJpUc&+p#i0-Gp~?l5d+zD+~r+f zaKX|0PWbVl0&Ots8YloEpc=mu;OEU$w~xLmHO+!>7y_O2qy=|Y|XL@5RRm8Q+lJnTdiiz^6-WDYgN70#8soR{rP zK^4-gc5JPOM`%$4U+R?5;H2e*Z63AHWrsO?B!y3XVD)Ob%2lA$T^t$!hepr}TK02g zoDNSW(QIWLTYBYu7oytg4p_%nWDN`P0Z1yXKl^~Hco59(jiJHYXT5f@4Q$5ha7hu| z?p3VRr>T7@aQ}IVXpXEFewp_U`Pw!@Eeyz_+CdEtU>Yol`D!MHggiyq%SGM>fI-Q| zdyEf+M#mJb1n}R7jgvf&F|~p@={S*)Zee`p0i{>Kax^<1J6l_-CQ9}t1(Y3VMH|`A z;pmEi5zomig!wsiwP(|G3SvZg4Am1>Vb%ssgLQ2?<=5W>;y2ABLJ4_s{QT?=KEo(D zJY@8oMP0MjBFnH1bIWSm)5$Lw+siC8sY#6?CbysttPeIlA(y#Aw=x+4*|S;1*4X_0 zm-G1#T+0D=J|Pg^JcXU8ly;jWuFP{pWRaFVk85O)N8Lu#CM*=TgGNGdj=TkUD-qC2 zvoeKuE1rbt{MW16^AWLj1}WVuU_A_V(2XLx7e$N+)H{Jjg5^0@m0H%vFMa7Voqed0|Naboi%5KKMJeB zD1gi+CJ%1^DUb(0XAYZ3^TXk;z7AIttq{JSur%vPMj)va)T`-7f8 z*+=fB-`|!bUM3+{d%Y6X4kHL;MRrTETe0lOTT*_&`=q6umK%=j5OL^TiDy5XL=)R{ zVOCms%i;oe2 z>UhS+iNyJr8=6t%VBr}y=fv5Vu*}O4&|#STXKL=<3J@G;CV;w$;kO82odeCAa=1Lav$n7`Ob zJfpR9^ew+eQlR=4iMvHwahCtDOP!|bk!z|Xjc zHU(7wTWlCQeA7KgOgQQGbN3ohWXAiVKo?8FYXnAZ^&Y}7Gz1vCqsx21Ww>qY0*W)L zVh?@rh`DD)hfm&0quvu!ea_SKKw*Znp-!YJz_xlDD{(KjT@p_{3 zNg4Y_+Ss1T0V9NjQZZlhC`%)6dXPvE@CL|M@r}p@5n_W=v~f7*FiDHpv30ebRc-Z5 zY=U)Z^gEU5Z@jL6>RW;LshI+{2%>rcCL1RTPyc{%tHhdEyfb;N*K2$lnVmD)?dg?D z7P)PC8X56bgc<3K4L^iM`j|340B#>NZFE!xw1#AO_ej_ugde

Yj@QfQ9Sy}nqnQ1L&oKAs9SlYfy?iC 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�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 literal 0 HcmV?d00001 diff --git a/nettle.texinfo b/nettle.texinfo new file mode 100644 index 0000000..f994942 --- /dev/null +++ b/nettle.texinfo @@ -0,0 +1,2744 @@ +\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.1 +@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 2010. + +@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. +@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 General Public License (GPL) (see +the file COPYING for details). However, most of the individual files +are dual licensed under less restrictive licenses like the GNU Lesser +General Public License (LGPL), or are in the public domain. This means +that if you don't use the parts of nettle that are GPL-only, you have +the option to use the Nettle library just as if it were licensed under +the LGPL. 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 Ray +Dassen and @value{AUTHOR}. Released under the GPL. + +@item CAMELLIA +The C implementation is by Nippon Telegraph and Telephone Corporation +(NTT), heavily modified by @value{AUTHOR}. Assembler for x86 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 SERPENT +The implementation of the SERPENT cipher is written by Ross Anderson, +Eli Biham, and Lars Knudsen, adapted to LSH by Rafael Sevilla, and to +Nettle by @value{AUTHOR}. Released under the GPL. + +@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{}. + +@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{}. + +@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{}. 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{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{}. + +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{}. + +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{}. + +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{}. + +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{}. + +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{}, 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_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. +@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{}. + +@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}, const uint8_t *@var{dst}, 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}, const uint8_t *@var{dst}, 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{}. + +@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}, const uint8_t *@var{dst}, 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{}. + +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 AES 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}, const uint8_t *@var{dst}, 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}, const uint8_t *@var{dst}, 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{}. + +@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}, const uint8_t *@var{dst}, 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}, const uint8_t *@var{dst}, 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{}. + +@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}, const uint8_t *@var{dst}, 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{}. + +@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}, const uint8_t *@var{dst}, 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}, const uint8_t *@var{dst}, 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{}. + +@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}, const uint8_t *@var{dst}, 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}, const uint8_t *@var{dst}, 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{}. + +@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}, const uint8_t *@var{dst}, 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}, const uint8_t *@var{dst}, 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{}. + +@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}, const uint8_t *@var{dst}, 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}, const uint8_t *@var{dst}, 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{}. + +@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}, const uint8_t *@var{dst}, 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}, const uint8_t *@var{dst}, 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{}. + +@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 + +@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; + +Nettle includes such structs for all the @emph{regular} ciphers, i.e. +ones without weak keys or other oddities. +@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 two other modes of operation: Cipher Block Chaining +(@acronym{CBC}) and Counter mode (@acronym{CTR}). @acronym{CBC} is +widely used, but there are a few subtle issues of information leakage. +@acronym{CTR} was standardized more recently, and is believed to be more +secure. + +@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 into +@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. + +@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 into +@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 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{}. +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-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 into +@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-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} 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{}. + +@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{}. + +@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{}. 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{}. 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 + +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/packaging/nettle.spec b/packaging/nettle.spec new file mode 100644 index 0000000..b8acd68 --- /dev/null +++ b/packaging/nettle.spec @@ -0,0 +1,59 @@ +%define nettlemajor 4 +%define hogweedmajor 2 +%define develname nettle-devel + +Name: nettle +Summary: Nettle cryptographic library +Version: 2.1 +Release: 1 +License: LGPLv2+ +Group: System/Libraries +URL: http://www.lysator.liu.se/~nisse/nettle/ +Source: http://www.lysator.liu.se/~nisse/archive/%{name}-%{version}.tar.gz +BuildRequires: autoconf +BuildRequires: openssl-devel +BuildRequires: gmp-devel + +%description +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. + +%package -n %develname +Group: Development/C++ +Summary: Header files for compiling against Nettle library +Provides: %name-devel = %{version}-%{release} + +%description -n %develname +This is the development package of nettle. + +%prep +%setup -q + +%build +%configure --disable-openssl --enable-shared +make + +%install +make install DESTDIR=$RPM_BUILD_ROOT INSTALL="install -p" +make install-shared DESTDIR=$RPM_BUILD_ROOT INSTALL="install -p" +rm -f $RPM_BUILD_ROOT%{_libdir}/*.a + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%manifest nettle.manifest +%{_bindir}/* +%{_infodir}/* +%{_libdir}/libnettle.so.%{nettlemajor}* +%{_libdir}/libhogweed.so.%{hogweedmajor}* + +%files -n %develname +%{_libdir}/libnettle.so +%{_libdir}/libhogweed.so +%{_includedir}/nettle + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig diff --git a/pgp-encode.c b/pgp-encode.c new file mode 100644 index 0000000..0ac46d2 --- /dev/null +++ b/pgp-encode.c @@ -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 +#include +#include + +#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= 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 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 + +#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 index 0000000..eff25fa --- /dev/null +++ b/pkcs1-rsa-md5.c @@ -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 +#include +#include + +#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 index 0000000..85395bd --- /dev/null +++ b/pkcs1-rsa-sha1.c @@ -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 +#include +#include + +#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 index 0000000..363f784 --- /dev/null +++ b/pkcs1-rsa-sha256.c @@ -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 +#include +#include + +#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 index 0000000..8eb4377 --- /dev/null +++ b/pkcs1-rsa-sha512.c @@ -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 +#include +#include + +#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 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 +#include + +#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 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 +#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 index 0000000..3645926 --- /dev/null +++ b/prime-list.h @@ -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 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 +#include + +#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 index 0000000..c8c6aa4 --- /dev/null +++ b/realloc.h @@ -0,0 +1,43 @@ +/* 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 + +typedef void *nettle_realloc_func(void *ctx, void *p, unsigned length); + +nettle_realloc_func nettle_realloc; +nettle_realloc_func nettle_xrealloc; + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_REALLOC_H_INCLUDED */ diff --git a/rotors.h b/rotors.h new file mode 100644 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 index 0000000..8eef185 --- /dev/null +++ b/rsa-compat.c @@ -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 index 0000000..9622503 --- /dev/null +++ b/rsa-compat.h @@ -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 index 0000000..973fa65 --- /dev/null +++ b/rsa-decrypt.c @@ -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 +#include +#include + +#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 index 0000000..a901e71 --- /dev/null +++ b/rsa-encrypt.c @@ -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 +#include +#include + +#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; isize - 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 index 0000000..8c56bb4 --- /dev/null +++ b/rsa-keygen.c @@ -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 +#include + +#include "rsa.h" +#include "bignum.h" + +#ifndef DEBUG +# define DEBUG 0 +#endif + +#if DEBUG +# include +#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 index 0000000..166cba7 --- /dev/null +++ b/rsa-md5-sign.c @@ -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 + +#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 index 0000000..f8931c7 --- /dev/null +++ b/rsa-md5-verify.c @@ -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 + +#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 index 0000000..f120c7b --- /dev/null +++ b/rsa-sha1-sign.c @@ -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 + +#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 index 0000000..71ed848 --- /dev/null +++ b/rsa-sha1-verify.c @@ -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 + +#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 index 0000000..5f3cf7c --- /dev/null +++ b/rsa-sha256-sign.c @@ -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 + +#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 index 0000000..ef3f1e3 --- /dev/null +++ b/rsa-sha256-verify.c @@ -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 + +#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 index 0000000..fa14487 --- /dev/null +++ b/rsa-sha512-sign.c @@ -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 + +#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 index 0000000..869a8f5 --- /dev/null +++ b/rsa-sha512-verify.c @@ -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 + +#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 index 0000000..aa407ca --- /dev/null +++ b/rsa-sign.c @@ -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 index 0000000..2e3b52f --- /dev/null +++ b/rsa-verify.c @@ -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 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 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 +#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) \ +) + + +/* 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 index 0000000..f129ff7 --- /dev/null +++ b/rsa2openpgp.c @@ -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 +#include + +#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 index 0000000..8578ec3 --- /dev/null +++ b/rsa2sexp.c @@ -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-meta.c b/serpent-meta.c new file mode 100644 index 0000000..204d2a1 --- /dev/null +++ b/serpent-meta.c @@ -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.c b/serpent.c new file mode 100644 index 0000000..65344b0 --- /dev/null +++ b/serpent.c @@ -0,0 +1,374 @@ +/* serpent.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) 1998, 2000, 2001, Ross Anderson, Eli Biham, Lars + * Knudsen, Rafael R. Sevilla, Niels Möller + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* I've modified this code a bit so that it interoperates with lsh + * properly. 2000-9-5, Rafael R. Sevilla + */ + +/* NOTE: The copyright notice for the original version of this code + * said "All rights reserved. This code is freely distributed for AES + * selection process. No other use is allowed." However, the authors + * later decided to GPL the code. /nisse */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "serpent.h" +#include "serpent_sboxes.h" + +#include "macros.h" + +void +serpent_set_key(struct serpent_ctx *ctx, + unsigned key_size, const uint8_t *key) +{ + unsigned i, j; + uint32_t w[132], k[132]; + + assert(key_size >= SERPENT_MIN_KEY_SIZE); + assert(key_size <= SERPENT_MAX_KEY_SIZE); + + for (i = key_size, j = 0; + (i >= 4); + i-=4, j++) + { + assert(j<8); + /* Read the key in the reverse direction. Why? */ + w[j] = READ_UINT32(key + i - 4); + } + + if (j < 8) + { + /* Pad key, "aabbccddeeff" -> 0xccddeeff, 0x01aabb" */ + uint32_t partial = 0x01; + while (i) + partial = (partial << 8 ) | *key++; + w[j++] = partial; + + while (j < 8) + w[j++] = 0; + } + + for(i=8; i<16; i++) + w[i]=ROL(w[i-8]^w[i-5]^w[i-3]^w[i-1]^PHI^(i-8),11); + for(i=0; i<8; i++) + w[i]=w[i+8]; + for(i=8; i<132; i++) + w[i]=ROL(w[i-8]^w[i-5]^w[i-3]^w[i-1]^PHI^i,11); + + RND03(w[ 0], w[ 1], w[ 2], w[ 3], k[ 0], k[ 1], k[ 2], k[ 3]); + RND02(w[ 4], w[ 5], w[ 6], w[ 7], k[ 4], k[ 5], k[ 6], k[ 7]); + RND01(w[ 8], w[ 9], w[ 10], w[ 11], k[ 8], k[ 9], k[ 10], k[ 11]); + RND00(w[ 12], w[ 13], w[ 14], w[ 15], k[ 12], k[ 13], k[ 14], k[ 15]); + RND31(w[ 16], w[ 17], w[ 18], w[ 19], k[ 16], k[ 17], k[ 18], k[ 19]); + RND30(w[ 20], w[ 21], w[ 22], w[ 23], k[ 20], k[ 21], k[ 22], k[ 23]); + RND29(w[ 24], w[ 25], w[ 26], w[ 27], k[ 24], k[ 25], k[ 26], k[ 27]); + RND28(w[ 28], w[ 29], w[ 30], w[ 31], k[ 28], k[ 29], k[ 30], k[ 31]); + RND27(w[ 32], w[ 33], w[ 34], w[ 35], k[ 32], k[ 33], k[ 34], k[ 35]); + RND26(w[ 36], w[ 37], w[ 38], w[ 39], k[ 36], k[ 37], k[ 38], k[ 39]); + RND25(w[ 40], w[ 41], w[ 42], w[ 43], k[ 40], k[ 41], k[ 42], k[ 43]); + RND24(w[ 44], w[ 45], w[ 46], w[ 47], k[ 44], k[ 45], k[ 46], k[ 47]); + RND23(w[ 48], w[ 49], w[ 50], w[ 51], k[ 48], k[ 49], k[ 50], k[ 51]); + RND22(w[ 52], w[ 53], w[ 54], w[ 55], k[ 52], k[ 53], k[ 54], k[ 55]); + RND21(w[ 56], w[ 57], w[ 58], w[ 59], k[ 56], k[ 57], k[ 58], k[ 59]); + RND20(w[ 60], w[ 61], w[ 62], w[ 63], k[ 60], k[ 61], k[ 62], k[ 63]); + RND19(w[ 64], w[ 65], w[ 66], w[ 67], k[ 64], k[ 65], k[ 66], k[ 67]); + RND18(w[ 68], w[ 69], w[ 70], w[ 71], k[ 68], k[ 69], k[ 70], k[ 71]); + RND17(w[ 72], w[ 73], w[ 74], w[ 75], k[ 72], k[ 73], k[ 74], k[ 75]); + RND16(w[ 76], w[ 77], w[ 78], w[ 79], k[ 76], k[ 77], k[ 78], k[ 79]); + RND15(w[ 80], w[ 81], w[ 82], w[ 83], k[ 80], k[ 81], k[ 82], k[ 83]); + RND14(w[ 84], w[ 85], w[ 86], w[ 87], k[ 84], k[ 85], k[ 86], k[ 87]); + RND13(w[ 88], w[ 89], w[ 90], w[ 91], k[ 88], k[ 89], k[ 90], k[ 91]); + RND12(w[ 92], w[ 93], w[ 94], w[ 95], k[ 92], k[ 93], k[ 94], k[ 95]); + RND11(w[ 96], w[ 97], w[ 98], w[ 99], k[ 96], k[ 97], k[ 98], k[ 99]); + RND10(w[100], w[101], w[102], w[103], k[100], k[101], k[102], k[103]); + RND09(w[104], w[105], w[106], w[107], k[104], k[105], k[106], k[107]); + RND08(w[108], w[109], w[110], w[111], k[108], k[109], k[110], k[111]); + RND07(w[112], w[113], w[114], w[115], k[112], k[113], k[114], k[115]); + RND06(w[116], w[117], w[118], w[119], k[116], k[117], k[118], k[119]); + RND05(w[120], w[121], w[122], w[123], k[120], k[121], k[122], k[123]); + RND04(w[124], w[125], w[126], w[127], k[124], k[125], k[126], k[127]); + RND03(w[128], w[129], w[130], w[131], k[128], k[129], k[130], k[131]); + + for(i=0; i<=32; i++) + for(j=0; j<4; j++) + ctx->keys[i][j] = k[4*i+j]; +} + +void +serpent_encrypt(const struct serpent_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *plain) +{ + register uint32_t x0, x1, x2, x3; + register uint32_t y0, y1, y2, y3; + + FOR_BLOCKS(length, dst, plain, SERPENT_BLOCK_SIZE) + { + /* Why the reverse order? */ + x0=READ_UINT32(plain + 12); + x1=READ_UINT32(plain + 8); + x2=READ_UINT32(plain + 4); + x3=READ_UINT32(plain); + + /* Start to encrypt the plaintext x */ + keying(x0, x1, x2, x3, ctx->keys[ 0]); + RND00(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[ 1]); + RND01(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[ 2]); + RND02(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[ 3]); + RND03(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[ 4]); + RND04(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[ 5]); + RND05(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[ 6]); + RND06(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[ 7]); + RND07(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[ 8]); + RND08(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[ 9]); + RND09(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[10]); + RND10(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[11]); + RND11(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[12]); + RND12(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[13]); + RND13(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[14]); + RND14(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[15]); + RND15(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[16]); + RND16(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[17]); + RND17(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[18]); + RND18(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[19]); + RND19(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[20]); + RND20(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[21]); + RND21(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[22]); + RND22(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[23]); + RND23(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[24]); + RND24(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[25]); + RND25(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[26]); + RND26(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[27]); + RND27(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[28]); + RND28(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[29]); + RND29(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[30]); + RND30(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[31]); + RND31(x0, x1, x2, x3, y0, y1, y2, y3); + x0 = y0; x1 = y1; x2 = y2; x3 = y3; + keying(x0, x1, x2, x3, ctx->keys[32]); + + /* The ciphertext is now in x */ + + /* Why the reverse order? */ + WRITE_UINT32(dst, x3); + WRITE_UINT32(dst+4, x2); + WRITE_UINT32(dst+8, x1); + WRITE_UINT32(dst+12, x0); + } +} + +void +serpent_decrypt(const struct serpent_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *cipher) +{ + register uint32_t x0, x1, x2, x3; + register uint32_t y0, y1, y2, y3; + + FOR_BLOCKS(length, dst, cipher, SERPENT_BLOCK_SIZE) + { + /* Why the reverse order? */ + x0 = READ_UINT32(cipher + 12); + x1 = READ_UINT32(cipher + 8); + x2 = READ_UINT32(cipher + 4); + x3 = READ_UINT32(cipher); + + /* Start to decrypt the ciphertext x */ + keying(x0, x1, x2, x3, ctx->keys[32]); + InvRND31(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[31]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND30(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[30]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND29(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[29]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND28(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[28]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND27(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[27]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND26(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[26]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND25(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[25]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND24(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[24]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND23(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[23]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND22(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[22]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND21(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[21]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND20(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[20]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND19(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[19]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND18(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[18]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND17(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[17]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND16(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[16]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND15(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[15]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND14(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[14]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND13(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[13]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND12(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[12]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND11(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[11]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND10(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[10]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND09(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[ 9]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND08(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[ 8]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND07(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[ 7]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND06(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[ 6]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND05(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[ 5]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND04(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[ 4]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND03(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[ 3]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND02(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[ 2]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND01(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[ 1]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND00(x0, x1, x2, x3, y0, y1, y2, y3); + x0 = y0; x1 = y1; x2 = y2; x3 = y3; + keying(x0, x1, x2, x3, ctx->keys[ 0]); + + /* The plaintext is now in x */ + + /* Why the reverse order? */ + WRITE_UINT32(dst, x3); + WRITE_UINT32(dst+4, x2); + WRITE_UINT32(dst+8, x1); + WRITE_UINT32(dst+12, x0); + } +} diff --git a/serpent.h b/serpent.h new file mode 100644 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/serpent_sboxes.h b/serpent_sboxes.h new file mode 100644 index 0000000..5f94025 --- /dev/null +++ b/serpent_sboxes.h @@ -0,0 +1,511 @@ +/* serpentsboxes.h + * + * $Id: serpent_sboxes.h,v 1.1 2007/04/05 14:20:35 nisse Exp $ + * + * For more details on this algorithm, see the Serpent website at + * http://www.cl.cam.ac.uk/~rja14/serpent.html + */ + +/* Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* I've modified this code a bit so that it interoperates with lsh + * properly. 2000-9-5, Rafael R. Sevilla + */ + +/* NOTE: The copyright notice for the original version of this code + * said "All rights reserved. This code is freely distributed for AES + * selection process. No other use is allowed." However, the authors + * later decided to GPL the code. /nisse */ + +#ifndef SERPENT_SBOXES_H_INCLUDED +#define SERPENT_SBOXES_H_INCLUDED + +#include "serpent.h" + +/* S0: 3 8 15 1 10 6 5 11 14 13 4 2 7 0 9 12 */ + +/* depth = 5,7,4,2, Total gates=18 */ +#define RND00(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t05, t06, t07, t08, t09, 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; } + +/* InvS0: 13 3 11 0 10 6 5 12 1 14 4 7 15 9 8 2 */ + +/* depth = 8,4,3,6, Total gates=19 */ +#define InvRND00(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t06, t08, t09, t10, t12, t13, t14, t15, t17, t18, t01;\ + t01 = c ^ d ; \ + t02 = a | b ; \ + t03 = b | c ; \ + t04 = c & t01; \ + t05 = t02 ^ t01; \ + t06 = a | t04; \ + y = ~ t05; \ + t08 = b ^ d ; \ + t09 = t03 & t08; \ + t10 = d | y ; \ + x = t09 ^ t06; \ + t12 = a | t05; \ + t13 = x ^ t12; \ + t14 = t03 ^ t10; \ + t15 = a ^ c ; \ + z = t14 ^ t13; \ + t17 = t05 & t13; \ + t18 = t14 | t17; \ + w = t15 ^ t18; } + +/* S1: 15 12 2 7 9 0 5 10 1 11 14 8 6 13 3 4 */ + +/* depth = 10,7,3,5, Total gates=18 */ +#define RND01(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t06, t07, t08, 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; } + +/* InvS1: 5 8 2 14 15 6 12 3 11 4 7 9 1 13 10 0 */ + +/* depth = 7,4,5,3, Total gates=18 */ +#define InvRND01(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t14, t15, t17, t01;\ + t01 = a ^ b ; \ + t02 = b | d ; \ + t03 = a & c ; \ + t04 = c ^ t02; \ + t05 = a | t04; \ + t06 = t01 & t05; \ + t07 = d | t03; \ + t08 = b ^ t06; \ + t09 = t07 ^ t06; \ + t10 = t04 | t03; \ + t11 = d & t08; \ + y = ~ t09; \ + x = t10 ^ t11; \ + t14 = a | y ; \ + t15 = t06 ^ x ; \ + z = t01 ^ t04; \ + t17 = c ^ t15; \ + w = t14 ^ t17; } + +/* S2: 8 6 7 9 3 12 10 15 13 1 14 4 0 11 5 2 */ + +/* depth = 3,8,11,7, Total gates=16 */ +#define RND02(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t05, t06, t07, t08, 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; } + +/* InvS2: 12 9 15 4 11 14 1 2 0 3 6 13 5 8 10 7 */ + +/* depth = 3,6,8,3, Total gates=18 */ +#define InvRND02(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t06, t07, t08, t09, t10, t11, t12, t15, t16, t17, t01;\ + t01 = a ^ d ; \ + t02 = c ^ d ; \ + t03 = a & c ; \ + t04 = b | t02; \ + w = t01 ^ t04; \ + t06 = a | c ; \ + t07 = d | w ; \ + t08 = ~ d ; \ + t09 = b & t06; \ + t10 = t08 | t03; \ + t11 = b & t07; \ + t12 = t06 & t02; \ + z = t09 ^ t10; \ + x = t12 ^ t11; \ + t15 = c & z ; \ + t16 = w ^ x ; \ + t17 = t10 ^ t15; \ + y = t16 ^ t17; } + +/* S3: 0 15 11 8 12 9 6 3 13 1 2 4 10 7 5 14 */ + +/* depth = 8,3,5,5, Total gates=18 */ +#define RND03(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t06, t07, t08, 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; } + +/* InvS3: 0 9 10 7 11 14 6 13 3 5 12 2 4 8 15 1 */ + +/* depth = 3,6,4,4, Total gates=17 */ +#define InvRND03(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t06, t07, t09, t11, t12, t13, t14, t16, t01;\ + t01 = c | d ; \ + t02 = a | d ; \ + t03 = c ^ t02; \ + t04 = b ^ t02; \ + t05 = a ^ d ; \ + t06 = t04 & t03; \ + t07 = b & t01; \ + y = t05 ^ t06; \ + t09 = a ^ t03; \ + w = t07 ^ t03; \ + t11 = w | t05; \ + t12 = t09 & t11; \ + t13 = a & y ; \ + t14 = t01 ^ t05; \ + x = b ^ t12; \ + t16 = b | t13; \ + z = t14 ^ t16; } + +/* S4: 1 15 8 3 12 0 11 6 2 5 4 10 9 14 7 13 */ + +/* depth = 6,7,5,3, Total gates=19 */ +#define RND04(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t06, t08, t09, 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; } + +/* InvS4: 5 0 8 3 10 9 7 14 2 12 11 6 4 15 13 1 */ + +/* depth = 6,4,7,3, Total gates=17 */ +#define InvRND04(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t06, t07, t09, t10, t11, t12, t13, t15, t01;\ + t01 = b | d ; \ + t02 = c | d ; \ + t03 = a & t01; \ + t04 = b ^ t02; \ + t05 = c ^ d ; \ + t06 = ~ t03; \ + t07 = a & t04; \ + x = t05 ^ t07; \ + t09 = x | t06; \ + t10 = a ^ t07; \ + t11 = t01 ^ t09; \ + t12 = d ^ t04; \ + t13 = c | t10; \ + z = t03 ^ t12; \ + t15 = a ^ t04; \ + y = t11 ^ t13; \ + w = t15 ^ t09; } + +/* S5: 15 5 2 11 4 10 9 12 0 3 14 8 13 6 7 1 */ + +/* depth = 4,6,8,6, Total gates=17 */ +#define RND05(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t07, t08, t09, 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; } + +/* InvS5: 8 15 2 9 4 1 13 14 11 6 5 3 7 12 10 0 */ + +/* depth = 4,6,9,7, Total gates=17 */ +#define InvRND05(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t07, t08, t09, t10, t12, t13, t15, t16, t01;\ + t01 = a & d ; \ + t02 = c ^ t01; \ + t03 = a ^ d ; \ + t04 = b & t02; \ + t05 = a & c ; \ + w = t03 ^ t04; \ + t07 = a & w ; \ + t08 = t01 ^ w ; \ + t09 = b | t05; \ + t10 = ~ b ; \ + x = t08 ^ t09; \ + t12 = t10 | t07; \ + t13 = w | x ; \ + z = t02 ^ t12; \ + t15 = t02 ^ t13; \ + t16 = b ^ d ; \ + y = t16 ^ t15; } + +/* S6: 7 2 12 5 8 4 6 11 14 9 1 15 13 3 10 0 */ + +/* depth = 8,3,6,3, Total gates=19 */ +#define RND06(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t07, t08, t09, t10, 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; } + +/* InvS6: 15 10 1 13 5 3 6 0 4 9 14 7 2 12 8 11 */ + +/* depth = 5,3,8,6, Total gates=19 */ +#define InvRND06(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t06, t07, t08, t09, t12, t13, t14, t15, t16, t17, t01;\ + t01 = a ^ c ; \ + t02 = ~ c ; \ + t03 = b & t01; \ + t04 = b | t02; \ + t05 = d | t03; \ + t06 = b ^ d ; \ + t07 = a & t04; \ + t08 = a | t02; \ + t09 = t07 ^ t05; \ + x = t06 ^ t08; \ + w = ~ t09; \ + t12 = b & w ; \ + t13 = t01 & t05; \ + t14 = t01 ^ t12; \ + t15 = t07 ^ t13; \ + t16 = d | t02; \ + t17 = a ^ x ; \ + z = t17 ^ t15; \ + y = t16 ^ t14; } + +/* S7: 1 13 15 0 14 8 2 11 7 4 12 10 9 3 5 6 */ + +/* depth = 10,7,10,4, Total gates=19 */ +#define RND07(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t06, t08, t09, t10, 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; } + +/* InvS7: 3 0 6 13 9 14 15 8 5 12 11 7 10 1 4 2 */ + +/* depth = 9,7,3,3, Total gates=18 */ +#define InvRND07(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t06, t07, t08, t09, t10, t11, t13, t14, t15, t16, t01;\ + t01 = a & b ; \ + t02 = a | b ; \ + t03 = c | t01; \ + t04 = d & t02; \ + z = t03 ^ t04; \ + t06 = b ^ t04; \ + t07 = d ^ z ; \ + t08 = ~ t07; \ + t09 = t06 | t08; \ + t10 = b ^ d ; \ + t11 = a | d ; \ + x = a ^ t09; \ + t13 = c ^ t06; \ + t14 = c & t11; \ + t15 = d | x ; \ + t16 = t01 | t10; \ + w = t13 ^ t15; \ + y = t14 ^ t16; } + +#define RND08(a,b,c,d,e,f,g,h) RND00(a,b,c,d,e,f,g,h) +#define RND09(a,b,c,d,e,f,g,h) RND01(a,b,c,d,e,f,g,h) +#define RND10(a,b,c,d,e,f,g,h) RND02(a,b,c,d,e,f,g,h) +#define RND11(a,b,c,d,e,f,g,h) RND03(a,b,c,d,e,f,g,h) +#define RND12(a,b,c,d,e,f,g,h) RND04(a,b,c,d,e,f,g,h) +#define RND13(a,b,c,d,e,f,g,h) RND05(a,b,c,d,e,f,g,h) +#define RND14(a,b,c,d,e,f,g,h) RND06(a,b,c,d,e,f,g,h) +#define RND15(a,b,c,d,e,f,g,h) RND07(a,b,c,d,e,f,g,h) +#define RND16(a,b,c,d,e,f,g,h) RND00(a,b,c,d,e,f,g,h) +#define RND17(a,b,c,d,e,f,g,h) RND01(a,b,c,d,e,f,g,h) +#define RND18(a,b,c,d,e,f,g,h) RND02(a,b,c,d,e,f,g,h) +#define RND19(a,b,c,d,e,f,g,h) RND03(a,b,c,d,e,f,g,h) +#define RND20(a,b,c,d,e,f,g,h) RND04(a,b,c,d,e,f,g,h) +#define RND21(a,b,c,d,e,f,g,h) RND05(a,b,c,d,e,f,g,h) +#define RND22(a,b,c,d,e,f,g,h) RND06(a,b,c,d,e,f,g,h) +#define RND23(a,b,c,d,e,f,g,h) RND07(a,b,c,d,e,f,g,h) +#define RND24(a,b,c,d,e,f,g,h) RND00(a,b,c,d,e,f,g,h) +#define RND25(a,b,c,d,e,f,g,h) RND01(a,b,c,d,e,f,g,h) +#define RND26(a,b,c,d,e,f,g,h) RND02(a,b,c,d,e,f,g,h) +#define RND27(a,b,c,d,e,f,g,h) RND03(a,b,c,d,e,f,g,h) +#define RND28(a,b,c,d,e,f,g,h) RND04(a,b,c,d,e,f,g,h) +#define RND29(a,b,c,d,e,f,g,h) RND05(a,b,c,d,e,f,g,h) +#define RND30(a,b,c,d,e,f,g,h) RND06(a,b,c,d,e,f,g,h) +#define RND31(a,b,c,d,e,f,g,h) RND07(a,b,c,d,e,f,g,h) + +#define InvRND08(a,b,c,d,e,f,g,h) InvRND00(a,b,c,d,e,f,g,h) +#define InvRND09(a,b,c,d,e,f,g,h) InvRND01(a,b,c,d,e,f,g,h) +#define InvRND10(a,b,c,d,e,f,g,h) InvRND02(a,b,c,d,e,f,g,h) +#define InvRND11(a,b,c,d,e,f,g,h) InvRND03(a,b,c,d,e,f,g,h) +#define InvRND12(a,b,c,d,e,f,g,h) InvRND04(a,b,c,d,e,f,g,h) +#define InvRND13(a,b,c,d,e,f,g,h) InvRND05(a,b,c,d,e,f,g,h) +#define InvRND14(a,b,c,d,e,f,g,h) InvRND06(a,b,c,d,e,f,g,h) +#define InvRND15(a,b,c,d,e,f,g,h) InvRND07(a,b,c,d,e,f,g,h) +#define InvRND16(a,b,c,d,e,f,g,h) InvRND00(a,b,c,d,e,f,g,h) +#define InvRND17(a,b,c,d,e,f,g,h) InvRND01(a,b,c,d,e,f,g,h) +#define InvRND18(a,b,c,d,e,f,g,h) InvRND02(a,b,c,d,e,f,g,h) +#define InvRND19(a,b,c,d,e,f,g,h) InvRND03(a,b,c,d,e,f,g,h) +#define InvRND20(a,b,c,d,e,f,g,h) InvRND04(a,b,c,d,e,f,g,h) +#define InvRND21(a,b,c,d,e,f,g,h) InvRND05(a,b,c,d,e,f,g,h) +#define InvRND22(a,b,c,d,e,f,g,h) InvRND06(a,b,c,d,e,f,g,h) +#define InvRND23(a,b,c,d,e,f,g,h) InvRND07(a,b,c,d,e,f,g,h) +#define InvRND24(a,b,c,d,e,f,g,h) InvRND00(a,b,c,d,e,f,g,h) +#define InvRND25(a,b,c,d,e,f,g,h) InvRND01(a,b,c,d,e,f,g,h) +#define InvRND26(a,b,c,d,e,f,g,h) InvRND02(a,b,c,d,e,f,g,h) +#define InvRND27(a,b,c,d,e,f,g,h) InvRND03(a,b,c,d,e,f,g,h) +#define InvRND28(a,b,c,d,e,f,g,h) InvRND04(a,b,c,d,e,f,g,h) +#define InvRND29(a,b,c,d,e,f,g,h) InvRND05(a,b,c,d,e,f,g,h) +#define InvRND30(a,b,c,d,e,f,g,h) InvRND06(a,b,c,d,e,f,g,h) +#define InvRND31(a,b,c,d,e,f,g,h) InvRND07(a,b,c,d,e,f,g,h) + +/* Linear transformations and key mixing: */ + +#define ROL(x,n) ((((uint32_t)(x))<<(n))| \ + (((uint32_t)(x))>>(32-(n)))) +#define ROR(x,n) ((((uint32_t)(x))<<(32-(n)))| \ + (((uint32_t)(x))>>(n))) + +#define transform(x0, x1, x2, x3, y0, y1, y2, y3) \ + y0 = ROL(x0, 13); \ + y2 = ROL(x2, 3); \ + y1 = x1 ^ y0 ^ y2; \ + y3 = x3 ^ y2 ^ ((uint32_t)y0)<<3; \ + y1 = ROL(y1, 1); \ + y3 = ROL(y3, 7); \ + y0 = y0 ^ y1 ^ y3; \ + y2 = y2 ^ y3 ^ ((uint32_t)y1<<7); \ + y0 = ROL(y0, 5); \ + y2 = ROL(y2, 22) + +#define inv_transform(x0, x1, x2, x3, y0, y1, y2, y3) \ + y2 = ROR(x2, 22);\ + y0 = ROR(x0, 5); \ + y2 = y2 ^ x3 ^ ((uint32_t)x1<<7); \ + y0 = y0 ^ x1 ^ x3; \ + y3 = ROR(x3, 7); \ + y1 = ROR(x1, 1); \ + y3 = y3 ^ y2 ^ ((uint32_t)y0)<<3; \ + y1 = y1 ^ y0 ^ y2; \ + y2 = ROR(y2, 3); \ + y0 = ROR(y0, 13) + +#define keying(x0, x1, x2, x3, subkey) \ + x0^=subkey[0];x1^=subkey[1]; \ + x2^=subkey[2];x3^=subkey[3] + +/* PHI: Constant used in the key schedule */ +#define PHI 0x9e3779b9L + +#endif /* SERPENT_SBOXES_H_INCLUDED */ diff --git a/sexp-format.c b/sexp-format.c new file mode 100644 index 0000000..a3e6d92 --- /dev/null +++ b/sexp-format.c @@ -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 +#include +#include +#include +#include + +#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 index 0000000..db4b193 --- /dev/null +++ b/sexp-transport-format.c @@ -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 index 0000000..37865e7 --- /dev/null +++ b/sexp-transport.c @@ -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 +#include + +#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 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 +#include + +#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; iatom_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; itype) + { + 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; iatom_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 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 +#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); + + +/* Checks the type of the current expression, which should be a list + * + * ( ...) + */ +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); + + +/* 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 index 0000000..eca790e --- /dev/null +++ b/sexp2bignum.c @@ -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 index 0000000..a3bc5e3 --- /dev/null +++ b/sexp2dsa.c @@ -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 + +#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 index 0000000..e3faf68 --- /dev/null +++ b/sexp2rsa.c @@ -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 + +#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 index 0000000..8b3d505 --- /dev/null +++ b/sha-example.c @@ -0,0 +1,41 @@ +#include +#include + +#include + +#define BUF_SIZE 1000 + +static void +display_hex(unsigned length, uint8_t *data) +{ + unsigned i; + + for (i = 0; i: + * + * 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 +# define DEBUG(i) \ + fprintf(stderr, "%2d: %8x %8x %8x %8x %8x\n", i, A, B, C, D ,E) +#else +# define DEBUG(i) +#endif + +#include +#include +#include + +#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 index 0000000..d201da8 --- /dev/null +++ b/sha1-meta.c @@ -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 index 0000000..c04ab77 --- /dev/null +++ b/sha1.c @@ -0,0 +1,173 @@ +/* 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 +#include +#include + +#include "sha.h" + +#include "macros.h" +#include "nettle-write.h" + +/* A block, treated as a sequence of 32-bit words. */ +#define SHA1_DATA_LENGTH 16 + +/* SHA initial values */ + +#define h0init 0x67452301L +#define h1init 0xEFCDAB89L +#define h2init 0x98BADCFEL +#define h3init 0x10325476L +#define h4init 0xC3D2E1F0L + +/* Initialize the SHA values */ + +void +sha1_init(struct sha1_ctx *ctx) +{ + /* Set the h-vars to their initial values */ + ctx->digest[ 0 ] = h0init; + ctx->digest[ 1 ] = h1init; + ctx->digest[ 2 ] = h2init; + ctx->digest[ 3 ] = h3init; + ctx->digest[ 4 ] = h4init; + + /* Initialize bit count */ + ctx->count_low = ctx->count_high = 0; + + /* Initialize buffer */ + ctx->index = 0; +} + +#define SHA1_INCR(ctx) ((ctx)->count_high += !++(ctx)->count_low) + +void +sha1_update(struct sha1_ctx *ctx, + unsigned length, const uint8_t *buffer) +{ + if (ctx->index) + { /* Try to fill partial block */ + unsigned left = SHA1_DATA_SIZE - ctx->index; + if (length < left) + { + memcpy(ctx->block + ctx->index, buffer, length); + ctx->index += length; + return; /* Finished */ + } + else + { + memcpy(ctx->block + ctx->index, buffer, left); + + _nettle_sha1_compress(ctx->digest, ctx->block); + SHA1_INCR(ctx); + + buffer += left; + length -= left; + } + } + while (length >= SHA1_DATA_SIZE) + { + _nettle_sha1_compress(ctx->digest, buffer); + SHA1_INCR(ctx); + + buffer += SHA1_DATA_SIZE; + length -= SHA1_DATA_SIZE; + } + if ((ctx->index = length)) /* This assignment is intended */ + /* Buffer leftovers */ + memcpy(ctx->block, buffer, length); +} + +/* Final wrapup - pad to SHA1_DATA_SIZE-byte boundary with the bit pattern + 1 0* (64-bit count of bits processed, MSB-first) */ + +static void +sha1_final(struct sha1_ctx *ctx) +{ + uint32_t bitcount_high; + uint32_t bitcount_low; + unsigned i; + + i = ctx->index; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + + assert(i < SHA1_DATA_SIZE); + ctx->block[i++] = 0x80; + + if (i > (SHA1_DATA_SIZE - 8)) + { /* No room for length in this block. Process it and + pad with another one */ + memset(ctx->block + i, 0, SHA1_DATA_SIZE - i); + + _nettle_sha1_compress(ctx->digest, ctx->block); + i = 0; + } + if (i < (SHA1_DATA_SIZE - 8)) + memset(ctx->block + i, 0, (SHA1_DATA_SIZE - 8) - i); + + /* There are 512 = 2^9 bits in one block */ + bitcount_high = (ctx->count_high << 9) | (ctx->count_low >> 23); + bitcount_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 + (SHA1_DATA_SIZE - 8), bitcount_high); + WRITE_UINT32(ctx->block + (SHA1_DATA_SIZE - 4), bitcount_low); + + _nettle_sha1_compress(ctx->digest, ctx->block); +} + +void +sha1_digest(struct sha1_ctx *ctx, + unsigned length, + uint8_t *digest) +{ + assert(length <= SHA1_DIGEST_SIZE); + + sha1_final(ctx); + _nettle_write_be32(length, digest, ctx->digest); + sha1_init(ctx); +} diff --git a/sha224-meta.c b/sha224-meta.c new file mode 100644 index 0000000..a8bbafc --- /dev/null +++ b/sha224-meta.c @@ -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 index 0000000..ad03039 --- /dev/null +++ b/sha256-compress.c @@ -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 +#include +#include + +#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 index 0000000..c21c792 --- /dev/null +++ b/sha256-meta.c @@ -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 index 0000000..fa4f735 --- /dev/null +++ b/sha256.c @@ -0,0 +1,214 @@ +/* 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 +#include +#include + +#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, +}; + +/* 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; +} + +#define SHA256_INCR(ctx) ((ctx)->count_high += !++(ctx)->count_low) + +void +sha256_update(struct sha256_ctx *ctx, + unsigned length, const uint8_t *buffer) +{ + if (ctx->index) + { /* Try to fill partial block */ + unsigned left = SHA256_DATA_SIZE - ctx->index; + if (length < left) + { + memcpy(ctx->block + ctx->index, buffer, length); + ctx->index += length; + return; /* Finished */ + } + else + { + memcpy(ctx->block + ctx->index, buffer, left); + + _nettle_sha256_compress(ctx->state, ctx->block, K); + SHA256_INCR(ctx); + + buffer += left; + length -= left; + } + } + while (length >= SHA256_DATA_SIZE) + { + _nettle_sha256_compress(ctx->state, buffer, K); + SHA256_INCR(ctx); + + buffer += SHA256_DATA_SIZE; + length -= SHA256_DATA_SIZE; + } + /* Buffer leftovers */ + /* NOTE: The corresponding sha1 code checks for the special case length == 0. + * That seems supoptimal, as I suspect it increases the number of branches. */ + + memcpy(ctx->block, buffer, length); + ctx->index = length; +} + +/* Final wrapup - pad to SHA1_DATA_SIZE-byte boundary with the bit pattern + 1 0* (64-bit count of bits processed, MSB-first) */ + +static void +sha256_final(struct sha256_ctx *ctx) +{ + uint32_t bitcount_high; + uint32_t bitcount_low; + int i; + + i = ctx->index; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + + assert(i < SHA256_DATA_SIZE); + ctx->block[i++] = 0x80; + + if (i > (SHA1_DATA_SIZE - 8)) + { /* No room for length in this block. Process it and + * pad with another one */ + memset(ctx->block + i, 0, SHA256_DATA_SIZE - i); + _nettle_sha256_compress(ctx->state, ctx->block, K); + + i = 0; + } + + if (i < (SHA256_DATA_SIZE - 8)) + memset(ctx->block + i, 0, (SHA256_DATA_SIZE - 8) - i); + + /* There are 512 = 2^9 bits in one block */ + bitcount_high = (ctx->count_high << 9) | (ctx->count_low >> 23); + bitcount_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), bitcount_high); + WRITE_UINT32(ctx->block + (SHA256_DATA_SIZE - 4), bitcount_low); + + _nettle_sha256_compress(ctx->state, ctx->block, K); +} + +void +sha256_digest(struct sha256_ctx *ctx, + unsigned length, + uint8_t *digest) +{ + assert(length <= SHA256_DIGEST_SIZE); + + sha256_final(ctx); + _nettle_write_be32(length, digest, ctx->state); + 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) +{ + assert(length <= SHA224_DIGEST_SIZE); + + sha256_final(ctx); + _nettle_write_be32(length, digest, ctx->state); + sha224_init(ctx); +} diff --git a/sha384-meta.c b/sha384-meta.c new file mode 100644 index 0000000..0c02239 --- /dev/null +++ b/sha384-meta.c @@ -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 index 0000000..f11226e --- /dev/null +++ b/sha512-compress.c @@ -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 +#include +#include + +#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 index 0000000..d9ba03e --- /dev/null +++ b/sha512-meta.c @@ -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 index 0000000..244ac80 --- /dev/null +++ b/sha512.c @@ -0,0 +1,298 @@ +/* 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 +#include +#include + +#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, +}; + +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; +} + +#define SHA512_INCR(ctx) ((ctx)->count_high += !++(ctx)->count_low) + +void +sha512_update(struct sha512_ctx *ctx, + unsigned length, const uint8_t *buffer) +{ + if (ctx->index) + { /* Try to fill partial block */ + unsigned left = SHA512_DATA_SIZE - ctx->index; + if (length < left) + { + memcpy(ctx->block + ctx->index, buffer, length); + ctx->index += length; + return; /* Finished */ + } + else + { + memcpy(ctx->block + ctx->index, buffer, left); + + _nettle_sha512_compress(ctx->state, ctx->block, K); + SHA512_INCR(ctx); + + buffer += left; + length -= left; + } + } + while (length >= SHA512_DATA_SIZE) + { + _nettle_sha512_compress(ctx->state, buffer, K); + SHA512_INCR(ctx); + + buffer += SHA512_DATA_SIZE; + length -= SHA512_DATA_SIZE; + } + + /* Buffer leftovers */ + memcpy(ctx->block, buffer, length); + ctx->index = length; +} + +/* Final wrapup - pad to SHA1_DATA_SIZE-byte boundary with the bit pattern + 1 0* (64-bit count of bits processed, MSB-first) */ + +static void +sha512_final(struct sha512_ctx *ctx) +{ + uint64_t bitcount_high; + uint64_t bitcount_low; + int i; + + i = ctx->index; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + + assert(i < SHA512_DATA_SIZE); + ctx->block[i++] = 0x80; + + if (i > (SHA512_DATA_SIZE-16)) + { /* No room for length in this block. Process it and + * pad with another one */ + memset(ctx->block + i, 0, SHA512_DATA_SIZE - i); + _nettle_sha512_compress(ctx->state, ctx->block, K); + + i = 0; + } + + if (i < (SHA512_DATA_SIZE - 16)) + memset(ctx->block + i, 0, (SHA512_DATA_SIZE - 16) - i); + + /* There are 1024 = 2^10 bits in one block */ + bitcount_high = (ctx->count_high << 10) | (ctx->count_low >> 54); + bitcount_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), bitcount_high); + WRITE_UINT64(ctx->block + (SHA512_DATA_SIZE - 8), bitcount_low); + + _nettle_sha512_compress(ctx->state, ctx->block, K); +} + +static void +sha512_write_digest(struct sha512_ctx *ctx, + unsigned length, + uint8_t *digest) +{ + unsigned i; + unsigned words; + unsigned leftover; + + sha512_final(ctx); + + 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 index 0000000..3275f0c --- /dev/null +++ b/shadata.c @@ -0,0 +1,50 @@ +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +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 index 0000000..0d432e0 --- /dev/null +++ b/sparc32/aes-decrypt-internal.asm @@ -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() + +C Arguments +define(, <%i0>) +define(, <%i1>) +define(,<%i2>) +define(, <%i3>) +define(, <%i4>) + +C AES state, two copies for unrolling + +define(, <%l0>) +define(, <%l1>) +define(, <%l2>) +define(, <%l3>) + +define(, <%l4>) +define(, <%l5>) +define(, <%l6>) +define(, <%l7>) + +C %o0-%03 are used for loop invariants T0-T3 +define(, <%o4>) +define(, <%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(, 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 index 0000000..e013822 --- /dev/null +++ b/sparc32/aes-encrypt-internal.asm @@ -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() + +C Arguments +define(, <%i0>) +define(, <%i1>) +define(,<%i2>) +define(, <%i3>) +define(, <%i4>) + +C AES state, two copies for unrolling + +define(, <%l0>) +define(, <%l1>) +define(, <%l2>) +define(, <%l3>) + +define(, <%l4>) +define(, <%l5>) +define(, <%l6>) +define(, <%l7>) + +C %o0-%03 are used for loop invariants T0-T3 +define(, <%o4>) +define(, <%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(, 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 index 0000000..05f465e --- /dev/null +++ b/sparc32/aes.m4 @@ -0,0 +1,83 @@ +C Used as temporaries by the AES macros +define(, <%g1>) +define(, <%g2>) +define(, <%g3>) + +C Loop invariants used by AES_ROUND +define(, <%o0>) +define(, <%o1>) +define(, <%o2>) +define(, <%o3>) + +C AES_LOAD(i, src, key, res) +define(, < + 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(, < + 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(, < + 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 index 0000000..4d8dac9 --- /dev/null +++ b/sparc32/arcfour-crypt.asm @@ -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(, ) + +C Registers + +define(, <%i0>) +define(,<%i1>) +define(, <%i2>) +define(, <%i3>) + +define(, <%i4>) +define(, <%i5>) +define(, <%g1>) +define(, <%g2>) +define(, <%g3>) +define(, <%o0>) +define(, <%o1>) +define(, <%o2>) +define(, <%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(, < + 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(, 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 index 0000000..e69de29 diff --git a/sparc64/aes-decrypt-internal.asm b/sparc64/aes-decrypt-internal.asm new file mode 100644 index 0000000..408dd72 --- /dev/null +++ b/sparc64/aes-decrypt-internal.asm @@ -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(, <%i0>) +define(, <%i1>) +define(,<%i2>) +define(, <%i3>) +define(, <%i4>) + +C AES state, two copies for unrolling + +define(, <%l0>) +define(, <%l1>) +define(, <%l2>) +define(, <%l3>) + +define(, <%l4>) +define(, <%l5>) +define(, <%l6>) +define(, <%l7>) + +C %o0-%03 are used for loop invariants T0-T3 +define(, <%o4>) +define(, <%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(, 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 index 0000000..5462056 --- /dev/null +++ b/sparc64/aes-encrypt-internal.asm @@ -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(, <%i0>) +define(, <%i1>) +define(,<%i2>) +define(, <%i3>) +define(, <%i4>) + +C AES state, two copies for unrolling + +define(, <%l0>) +define(, <%l1>) +define(, <%l2>) +define(, <%l3>) + +define(, <%l4>) +define(, <%l5>) +define(, <%l6>) +define(, <%l7>) + +C %o0-%03 are used for loop invariants T0-T3 +define(, <%o4>) +define(, <%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(, 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 index 0000000..0e407d1 --- /dev/null +++ b/sparc64/arcfour-crypt.asm @@ -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(, ) + +C Registers + +define(, <%i0>) +define(,<%i1>) +define(, <%i2>) +define(, <%i3>) + +define(, <%i4>) +define(, <%i5>) +define(, <%g1>) +define(, <%g2>) +define(, <%g3>) +define(, <%o0>) +define(, <%o1>) +define(, <%o2>) +define(, <%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(, < + 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(, 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 index 0000000..4c1c0e5 --- /dev/null +++ b/sparc64/machine.m4 @@ -0,0 +1,4 @@ +define(, 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 index 0000000..9788f70 --- /dev/null +++ b/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/testsuite/.test-rules.make b/testsuite/.test-rules.make new file mode 100644 index 0000000..fe6489d --- /dev/null +++ b/testsuite/.test-rules.make @@ -0,0 +1,126 @@ +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) + +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) + +hmac-test$(EXEEXT): hmac-test.$(OBJEXT) + $(LINK) hmac-test.$(OBJEXT) $(TEST_OBJS) -o hmac-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 index 0000000..1549362 --- /dev/null +++ b/testsuite/Makefile.in @@ -0,0 +1,109 @@ +@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 \ + 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 hmac-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 + +check: $(TS_ALL) $(srcdir)/run-tests + LD_LIBRARY_PATH=../.lib 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 index 0000000..87be806 --- /dev/null +++ b/testsuite/aes-test.c @@ -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 index 0000000..6027c54 --- /dev/null +++ b/testsuite/arcfour-test.c @@ -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 index 0000000..17c3503 --- /dev/null +++ b/testsuite/arctwo-test.c @@ -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 index 0000000..fe8fe92 --- /dev/null +++ b/testsuite/base16-test.c @@ -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 index 0000000..b4d0917 --- /dev/null +++ b/testsuite/base64-test.c @@ -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 index 0000000..84e0483 --- /dev/null +++ b/testsuite/bignum-test.c @@ -0,0 +1,97 @@ +#include "testutils.h" + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#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 index 0000000..c4311bb --- /dev/null +++ b/testsuite/blowfish-test.c @@ -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 index 0000000..3ac4b20 --- /dev/null +++ b/testsuite/buffer-test.c @@ -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 index 0000000..4f1d118 --- /dev/null +++ b/testsuite/camellia-test.c @@ -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 index 0000000..e4b7830 --- /dev/null +++ b/testsuite/cast128-test.c @@ -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 index 0000000..b7bd2dd --- /dev/null +++ b/testsuite/cbc-test.c @@ -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 index 0000000..15c74d5 --- /dev/null +++ b/testsuite/ctr-test.c @@ -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 index 0000000..b5635fb --- /dev/null +++ b/testsuite/cxx-test.cxx @@ -0,0 +1,108 @@ +/* For FILE, used by gmp.h */ +#include + +#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 ("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 + ("The magic words are squeamish ossifrage")); + ASSERT (rsa_md5_sign (&key, &md5, signature)); + + /* Verify it */ + md5_update (&md5, 39, reinterpret_cast + ("The magic words are squeamish ossifrage")); + if (!rsa_md5_verify (&pub, &md5, signature)) + FAIL(); + + /* Try bad data */ + md5_update (&md5, 39, reinterpret_cast + ("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 index 0000000..c820c4e --- /dev/null +++ b/testsuite/des-compat-test.c @@ -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 +#include +#include + +#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>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 index 0000000..244e5aa --- /dev/null +++ b/testsuite/des-test.c @@ -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 index 0000000..678a235 --- /dev/null +++ b/testsuite/des3-test.c @@ -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 index 0000000..12dc309 --- /dev/null +++ b/testsuite/dsa-keygen-test.c @@ -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 index 0000000..3698d1b --- /dev/null +++ b/testsuite/dsa-test.c @@ -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/gold-bug.txt b/testsuite/gold-bug.txt new file mode 100644 index 0000000..be3a2a0 --- /dev/null +++ b/testsuite/gold-bug.txt @@ -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 index 0000000..d3068d9 --- /dev/null +++ b/testsuite/hmac-test.c @@ -0,0 +1,831 @@ +#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_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 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 index 0000000..218894f --- /dev/null +++ b/testsuite/knuth-lfib-test.c @@ -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 index 0000000..8ab45c1 --- /dev/null +++ b/testsuite/md2-test.c @@ -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 index 0000000..208456d --- /dev/null +++ b/testsuite/md4-test.c @@ -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 index 0000000..bffb623 --- /dev/null +++ b/testsuite/md5-compat-test.c @@ -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 index 0000000..995f304 --- /dev/null +++ b/testsuite/md5-test.c @@ -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/pkcs1-conv-test b/testsuite/pkcs1-conv-test new file mode 100755 index 0000000..e1ce3db --- /dev/null +++ b/testsuite/pkcs1-conv-test @@ -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 <testkey.pub <testsignature < testsignature2 <&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 index 0000000..b1101ea --- /dev/null +++ b/testsuite/serpent-test.c @@ -0,0 +1,57 @@ +#include "testutils.h" +#include "serpent.h" + +int +test_main(void) +{ + /* The first test for each key size from the ecb_vk.txt and ecb_vt.txt + * files in the serpent package. */ + + /* 128 bit key */ + + /* vk, 1 */ + test_cipher(&nettle_serpent128, + HL("8000000000000000 0000000000000000"), + HL("0000000000000000 0000000000000000"), + H("49AFBFAD9D5A3405 2CD8FFA5986BD2DD")); + + /* vt, 1 */ + test_cipher(&nettle_serpent128, + HL("0000000000000000 0000000000000000"), + HL("8000000000000000 0000000000000000"), + H("10B5FFB720B8CB90 02A1142B0BA2E94A")); + + /* 192 bit key */ + + /* vk, 1 */ + test_cipher(&nettle_serpent192, + HL("8000000000000000 0000000000000000" + "0000000000000000"), + HL("0000000000000000 0000000000000000"), + H("E78E5402C7195568 AC3678F7A3F60C66")); + + /* vt, 1 */ + test_cipher(&nettle_serpent192, + HL("0000000000000000 0000000000000000" + "0000000000000000"), + HL("8000000000000000 0000000000000000"), + H("B10B271BA25257E1 294F2B51F076D0D9")); + + /* 256 bit key */ + + /* vk, 1 */ + test_cipher(&nettle_serpent256, + HL("8000000000000000 0000000000000000" + "0000000000000000 0000000000000000"), + HL("0000000000000000 0000000000000000"), + H("ABED96E766BF28CB C0EBD21A82EF0819")); + + /* vt, 1 */ + test_cipher(&nettle_serpent256, + HL("0000000000000000 0000000000000000" + "0000000000000000 0000000000000000"), + HL("8000000000000000 0000000000000000"), + H("DA5A7992B1B4AE6F 8C004BC8A7DE5520")); + + SUCCESS(); +} diff --git a/testsuite/sexp-conv-test b/testsuite/sexp-conv-test new file mode 100755 index 0000000..a3470ab --- /dev/null +++ b/testsuite/sexp-conv-test @@ -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 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 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 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 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 index 0000000..33c585f --- /dev/null +++ b/testsuite/sexp-format-test.c @@ -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 index 0000000..4e68f56 --- /dev/null +++ b/testsuite/sexp-test.c @@ -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 index 0000000..2e7cd91 --- /dev/null +++ b/testsuite/sexp2rsa-test.c @@ -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 index 0000000..4f1b4dc --- /dev/null +++ b/testsuite/sha1-huge-test.c @@ -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 index 0000000..8319086 --- /dev/null +++ b/testsuite/sha1-test.c @@ -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 index 0000000..cef82af --- /dev/null +++ b/testsuite/sha224-test.c @@ -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 index 0000000..7499521 --- /dev/null +++ b/testsuite/sha256-test.c @@ -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 index 0000000..086e115 --- /dev/null +++ b/testsuite/sha384-test.c @@ -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 index 0000000..97bde53 --- /dev/null +++ b/testsuite/sha512-test.c @@ -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 index 0000000..b487126 --- /dev/null +++ b/testsuite/symbols-test @@ -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 index 0000000..2c547ad --- /dev/null +++ b/testsuite/teardown-env @@ -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 index 0000000..eea8037 --- /dev/null +++ b/testsuite/testutils.c @@ -0,0 +1,961 @@ +/* testutils.c */ + +#include "testutils.h" + +#include "cbc.h" +#include "ctr.h" +#include "knuth-lfib.h" + +#include +#include +#include +#include + +/* -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)) + 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)) + 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)) + FAIL(); + + memcpy(ctr, ictr, cipher->block_size); + + ctr_crypt(ctx, cipher->encrypt, + cipher->block_size, ctr, + length, data, data); + + if (!MEMEQ(length, data, cleartext)) + 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)) + 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)) + FAIL(); + + free(ctx); + free(data); +} + +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 index 0000000..91ec496 --- /dev/null +++ b/testsuite/testutils.h @@ -0,0 +1,210 @@ +#ifndef NETTLE_TESTUTILS_H_INCLUDED +#define NETTLE_TESTUTILS_H_INCLUDED + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-types.h" + +#include +#include +#include + +#if HAVE_LIBGMP +# include "bignum.h" +#endif + +#if WITH_HOGWEED +# include "rsa.h" +# include "dsa.h" +#endif + +#include "nettle-meta.h" + +#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_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 index 0000000..65558d3 --- /dev/null +++ b/testsuite/twofish-test.c @@ -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 index 0000000..5f01e76 --- /dev/null +++ b/testsuite/yarrow-test.c @@ -0,0 +1,221 @@ +#include "testutils.h" +#include "yarrow.h" +#include "knuth-lfib.h" + +#include "macros.h" + +#include +#include +#include +#include +#include + +/* 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 index 0000000..7f876b4 --- /dev/null +++ b/texinfo.tex @@ -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 . +% +% 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 `\^^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 . + % + \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 to achieve this: TeX expands \the only once, + % simply yielding the contents of . (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 + \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{...} +% If we want to allow any 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'{'#1'}'{#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\ }} + +\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 +% 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 index 0000000..4115b4e --- /dev/null +++ b/tools/Makefile.in @@ -0,0 +1,80 @@ +@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-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 + +SOURCES = $(sexp_conv_SOURCES) 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 $@ + +.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 index 0000000..ed32692 --- /dev/null +++ b/tools/getopt.c @@ -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. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +# ifndef const +# define const +# endif +#endif + +#include + +/* 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 +# 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 +# include +#endif /* GNU C library. */ + +#ifdef VMS +# include +# if HAVE_STRING_H - 0 +# include +# endif +#endif + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. */ +# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC +# include +# 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; + +#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 +# define my_index strchr +#else + +# if HAVE_STRING_H +# include +# else +# include +# 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__ */ + +/* 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; +} + +/* 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. */ + +#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 index 0000000..76cf5ee --- /dev/null +++ b/tools/getopt.h @@ -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 , but + that does not exist if we are standalone. So: if __GNU_LIBRARY__ is + not defined, include , which will pull in 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 +#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 index 0000000..62c55cf --- /dev/null +++ b/tools/getopt1.c @@ -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. */ + +#ifdef HAVE_CONFIG_H +#include +#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 + +/* 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 +#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 +#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. */ + +#ifdef TEST + +#include + +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 index 0000000..8dd7d0c --- /dev/null +++ b/tools/input.c @@ -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 +#include +#include +#include + +#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 index 0000000..5c59add --- /dev/null +++ b/tools/input.h @@ -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 + +/* 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 index 0000000..c49f81b --- /dev/null +++ b/tools/misc.c @@ -0,0 +1,73 @@ +/* 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 +#include +#include + +#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); + + exit(EXIT_FAILURE); +} + +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 index 0000000..ee5afcd --- /dev/null +++ b/tools/misc.h @@ -0,0 +1,75 @@ +/* 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))) + __attribute__((__noreturn__)) +#endif + ; + +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-lfib-stream.c b/tools/nettle-lfib-stream.c new file mode 100644 index 0000000..f666900 --- /dev/null +++ b/tools/nettle-lfib-stream.c @@ -0,0 +1,81 @@ +/* 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. + */ + +#include "knuth-lfib.h" + +#include +#include +#include + +#include + +#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 index 0000000..d491d9a --- /dev/null +++ b/tools/output.c @@ -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 +#include +#include +#include +#include + +#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; iline_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) + 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; isize; 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; isize; 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 index 0000000..8ac5256 --- /dev/null +++ b/tools/output.h @@ -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 + +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 index 0000000..292c6ce --- /dev/null +++ b/tools/parse.c @@ -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 +#include + +#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 index 0000000..df6f8b4 --- /dev/null +++ b/tools/parse.h @@ -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 index 0000000..158df5d --- /dev/null +++ b/tools/pkcs1-conv.c @@ -0,0 +1,649 @@ +/* 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 +#include +#include +#include + +#include "asn1.h" +#include "base64.h" +#include "buffer.h" +#include "rsa.h" +#include "dsa.h" + +#include "getopt.h" +#include "misc.h" + +enum object_type + { + 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; + + static const struct option options[] = + { + /* Name, args, flag, val */ + { "help", no_argument, NULL, '?' }, + { "version", no_argument, NULL, 'V' }, + { "private-rsa-key", no_argument, NULL, RSA_PRIVATE_KEY }, + { "public-rsa-key", no_argument, NULL, RSA_PUBLIC_KEY }, + { "private-dsa-key", no_argument, NULL, DSA_PRIVATE_KEY }, + { "public-key-info", no_argument, NULL, GENERAL_PUBLIC_KEY }, + { "base-64", no_argument, NULL, 'b' }, + { NULL, 0, NULL, 0 } + }; + + while ( (c = getopt_long(argc, argv, "V?b", options, NULL)) != -1) + { + switch (c) + { + default: + abort(); + + case 'b': + base64 = 1; + break; + + case RSA_PRIVATE_KEY: + case RSA_PUBLIC_KEY: + case DSA_PRIVATE_KEY: + case GENERAL_PUBLIC_KEY: + type = c; + break; + + case '?': + printf("FIXME: Usage information.\n"); + return EXIT_SUCCESS; + + case 'V': + printf("pkcs1-conv (" PACKAGE_STRING ")\n"); + exit (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 index 0000000..4b08a9c --- /dev/null +++ b/tools/sexp-conv.c @@ -0,0 +1,442 @@ +/* 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 +#include +#include +#include +#include + +#if HAVE_FCNTL_LOCKING +# if HAVE_SYS_TYPES_H +# include +# endif +# if HAVE_UNISTD_H +# include +# endif +# include +#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" + +static void * +xalloc(size_t size) +{ + void *p = malloc(size); + if (!p) + { + fprintf(stderr, "Virtual memory exhausted.\n"); + abort(); + } + + return p; +} + + +/* 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(); + } +} + + +/* Argument parsing and main program */ + +/* The old lsh sexp-conv program took the following options: + * + * Usage: sexp-conv [OPTION...] + * Conversion: sexp-conv [options] OUTPUT + * or: sexp-conv [OPTION...] + * Fingerprinting: sexp-conv --raw-hash [ --hash=ALGORITHM ] + * 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, '?' }, + { "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, "V?s: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 '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 '?': + printf("Usage: sexp-conv [OPTION...]\n" + " Conversion: sexp-conv [OPTION...] 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 index 0000000..7e46325 --- /dev/null +++ b/twofish-meta.c @@ -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 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 + * + * Modifications for lsh, integrated testing + * Copyright (C) 1999 J.H.M. Dassen (Ray) + * + * 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 +#include + +#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 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 index 0000000..e52e565 --- /dev/null +++ b/write-be32.c @@ -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 + +#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/x86/aes-decrypt-internal.asm b/x86/aes-decrypt-internal.asm new file mode 100644 index 0000000..0dc6f7b --- /dev/null +++ b/x86/aes-decrypt-internal.asm @@ -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() + +C Register usage: + +C AES state +define(,<%eax>) +define(,<%ebx>) +define(,<%ecx>) +define(,<%edx>) + +C Primary use of these registers. They're also used temporarily for other things. +define(,<%ebp>) +define(,<%edi>) +define(,<%esi>) + +define(, <40(%esp)>) +define(, <44(%esp)>) +define(, <48(%esp)>) +define(, <52(%esp)>) +define(, <56(%esp)>) + +define(, <16(%esp)>) +define(, <12(%esp)>) +define(, <8(%esp)>) +define(, <4(%esp)>) +define(, <(%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 index 0000000..99620d4 --- /dev/null +++ b/x86/aes-encrypt-internal.asm @@ -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() + +C Register usage: + +C AES state +define(,<%eax>) +define(,<%ebx>) +define(,<%ecx>) +define(,<%edx>) + +C Primary use of these registers. They're also used temporarily for other things. +define(,<%ebp>) +define(,<%edi>) +define(,<%esi>) + +define(, <40(%esp)>) +define(, <44(%esp)>) +define(, <48(%esp)>) +define(, <52(%esp)>) +define(, <56(%esp)>) + +define(, <16(%esp)>) +define(, <12(%esp)>) +define(, <8(%esp)>) +define(, <4(%esp)>) +define(, <(%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 index 0000000..3507e85 --- /dev/null +++ b/x86/aes.m4 @@ -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(, < + 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(, < + 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(, < + 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(, < + 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(, < + 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 index 0000000..bdeb98f --- /dev/null +++ b/x86/arcfour-crypt.asm @@ -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 index 0000000..b5c491c --- /dev/null +++ b/x86/camellia-crypt-internal.asm @@ -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(,<%eax>) +define(,<%ebx>) +define(,<%ecx>) +define(

,<%edx>) + +define(,<%ebp>) +define(,<%esi>) +define(,<%edi>) + +C Locals on the stack + +define(, <(%esp)>) +define(, <4(%esp)>) +define(, <8(%esp)>) +define(, <12(%esp)>) +define(, <16(%esp)>) + +C Arguments on stack. +define(, <40(%esp)>) +define(, <44(%esp)>) +define(, <48(%esp)>) +define(, <52(%esp)>) +define(, <56(%esp)>) + +define(, <(T,$1,4)>) +define(, <1024(T,$1,4)>) +define(, <2048(T,$1,4)>) +define(, <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(, < + 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(, < + movl L0, FRAME_L0 + movl H0, FRAME_H0 + movl L1, FRAME_L1 + movl H1, FRAME_H1 + + ROUND(L0,H0,,

,0) + movl L1, FRAME_L1 + movl H1, FRAME_H1 + ROUND(L1,H1,,,8) + movl L0, FRAME_L0 + movl H0, FRAME_H0 + ROUND(L0,H0,,

,16) + movl L1, FRAME_L1 + movl H1, FRAME_H1 + ROUND(L1,H1,,,24) + movl L0, FRAME_L0 + movl H0, FRAME_H0 + ROUND(L0,H0,,

,32) + ROUND(L1,H1,,,40) + roll <$>16, L1 + roll <$>16, H1 +>) + +C FL(x0, x1, key-offset) +define(, < + 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(, < + 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 index 0000000..38bee36 --- /dev/null +++ b/x86/machine.m4 @@ -0,0 +1,16 @@ +C OFFSET(i) +C Expands to 4*i, or to the empty string if i is zero +define(, ) + +dnl LREG(reg) gives the 8-bit register corresponding to the given 32-bit register. +define(,)dnl + +define(,)dnl diff --git a/x86/md5-compress.asm b/x86/md5-compress.asm new file mode 100644 index 0000000..44894e3 --- /dev/null +++ b/x86/md5-compress.asm @@ -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(,<%eax>) +define(,<%ebx>) +define(,<%ecx>) +define(,<%edx>) +define(,<%ebp>) +define(,<%esi>) + +C %edi is unused + +C F1(x,y,z) = (z ^ (x & (y ^ z))) +define(, < + movl $3, TMP + xorl $2, TMP + andl $1, TMP + xorl $3, TMP>) + +define(,) + +C F3(x,y,z) = x ^ y ^ z +define(,< + movl $1, TMP + xorl $2, TMP + xorl $3, TMP>) + +C F4(x,y,z) = y ^ (x | ~z) +define(,< + movl $3, TMP + notl TMP + orl $1, TMP + xorl $2, TMP>) + +define(,) + +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(,< + 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(, SA, SB, SC, SD, REF( 0), $0xd76aa478, 7) + ROUND(, SD, SA, SB, SC, REF( 1), $0xe8c7b756, 12) + ROUND(, SC, SD, SA, SB, REF( 2), $0x242070db, 17) + ROUND(, SB, SC, SD, SA, REF( 3), $0xc1bdceee, 22) + ROUND(, SA, SB, SC, SD, REF( 4), $0xf57c0faf, 7) + ROUND(, SD, SA, SB, SC, REF( 5), $0x4787c62a, 12) + ROUND(, SC, SD, SA, SB, REF( 6), $0xa8304613, 17) + ROUND(, SB, SC, SD, SA, REF( 7), $0xfd469501, 22) + ROUND(, SA, SB, SC, SD, REF( 8), $0x698098d8, 7) + ROUND(, SD, SA, SB, SC, REF( 9), $0x8b44f7af, 12) + ROUND(, SC, SD, SA, SB, REF(10), $0xffff5bb1, 17) + ROUND(, SB, SC, SD, SA, REF(11), $0x895cd7be, 22) + ROUND(, SA, SB, SC, SD, REF(12), $0x6b901122, 7) + ROUND(, SD, SA, SB, SC, REF(13), $0xfd987193, 12) + ROUND(, SC, SD, SA, SB, REF(14), $0xa679438e, 17) + ROUND(, SB, SC, SD, SA, REF(15), $0x49b40821, 22) + + ROUND(, SA, SB, SC, SD, REF( 1), $0xf61e2562, 5) + ROUND(, SD, SA, SB, SC, REF( 6), $0xc040b340, 9) + ROUND(, SC, SD, SA, SB, REF(11), $0x265e5a51, 14) + ROUND(, SB, SC, SD, SA, REF( 0), $0xe9b6c7aa, 20) + ROUND(, SA, SB, SC, SD, REF( 5), $0xd62f105d, 5) + ROUND(, SD, SA, SB, SC, REF(10), $0x02441453, 9) + ROUND(, SC, SD, SA, SB, REF(15), $0xd8a1e681, 14) + ROUND(, SB, SC, SD, SA, REF( 4), $0xe7d3fbc8, 20) + ROUND(, SA, SB, SC, SD, REF( 9), $0x21e1cde6, 5) + ROUND(, SD, SA, SB, SC, REF(14), $0xc33707d6, 9) + ROUND(, SC, SD, SA, SB, REF( 3), $0xf4d50d87, 14) + ROUND(, SB, SC, SD, SA, REF( 8), $0x455a14ed, 20) + ROUND(, SA, SB, SC, SD, REF(13), $0xa9e3e905, 5) + ROUND(, SD, SA, SB, SC, REF( 2), $0xfcefa3f8, 9) + ROUND(, SC, SD, SA, SB, REF( 7), $0x676f02d9, 14) + ROUND(, SB, SC, SD, SA, REF(12), $0x8d2a4c8a, 20) + + ROUND(, SA, SB, SC, SD, REF( 5), $0xfffa3942, 4) + ROUND(, SD, SA, SB, SC, REF( 8), $0x8771f681, 11) + ROUND(, SC, SD, SA, SB, REF(11), $0x6d9d6122, 16) + ROUND(, SB, SC, SD, SA, REF(14), $0xfde5380c, 23) + ROUND(, SA, SB, SC, SD, REF( 1), $0xa4beea44, 4) + ROUND(, SD, SA, SB, SC, REF( 4), $0x4bdecfa9, 11) + ROUND(, SC, SD, SA, SB, REF( 7), $0xf6bb4b60, 16) + ROUND(, SB, SC, SD, SA, REF(10), $0xbebfbc70, 23) + ROUND(, SA, SB, SC, SD, REF(13), $0x289b7ec6, 4) + ROUND(, SD, SA, SB, SC, REF( 0), $0xeaa127fa, 11) + ROUND(, SC, SD, SA, SB, REF( 3), $0xd4ef3085, 16) + ROUND(, SB, SC, SD, SA, REF( 6), $0x04881d05, 23) + ROUND(, SA, SB, SC, SD, REF( 9), $0xd9d4d039, 4) + ROUND(, SD, SA, SB, SC, REF(12), $0xe6db99e5, 11) + ROUND(, SC, SD, SA, SB, REF(15), $0x1fa27cf8, 16) + ROUND(, SB, SC, SD, SA, REF( 2), $0xc4ac5665, 23) + + ROUND(, SA, SB, SC, SD, REF( 0), $0xf4292244, 6) + ROUND(, SD, SA, SB, SC, REF( 7), $0x432aff97, 10) + ROUND(, SC, SD, SA, SB, REF(14), $0xab9423a7, 15) + ROUND(, SB, SC, SD, SA, REF( 5), $0xfc93a039, 21) + ROUND(, SA, SB, SC, SD, REF(12), $0x655b59c3, 6) + ROUND(, SD, SA, SB, SC, REF( 3), $0x8f0ccc92, 10) + ROUND(, SC, SD, SA, SB, REF(10), $0xffeff47d, 15) + ROUND(, SB, SC, SD, SA, REF( 1), $0x85845dd1, 21) + ROUND(, SA, SB, SC, SD, REF( 8), $0x6fa87e4f, 6) + ROUND(, SD, SA, SB, SC, REF(15), $0xfe2ce6e0, 10) + ROUND(, SC, SD, SA, SB, REF( 6), $0xa3014314, 15) + ROUND(, SB, SC, SD, SA, REF(13), $0x4e0811a1, 21) + ROUND(, SA, SB, SC, SD, REF( 4), $0xf7537e82, 6) + ROUND(, SD, SA, SB, SC, REF(11), $0xbd3af235, 10) + ROUND(, SC, SD, SA, SB, REF( 2), $0x2ad7d2bb, 15) + ROUND(, 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 index 0000000..f6fa347 --- /dev/null +++ b/x86/sha1-compress.asm @@ -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(,<%eax>) +define(,<%ebx>) +define(,<%ecx>) +define(,<%edx>) +define(,<%ebp>) +define(,<%esp>) +define(,<%edi>) +define(,<%esi>) + +C Constants +define(, <0x5A827999>) C Rounds 0-19 +define(, <0x6ED9EBA1>) C Rounds 20-39 +define(, <0x8F1BBCDC>) C Rounds 40-59 +define(, <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(, < + 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(, < + 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(, < + 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(, < + 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(, < + 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 index 0000000..8f0df73 --- /dev/null +++ b/x86_64/aes-decrypt-internal.asm @@ -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() + +C Register usage: + +C AES state, use two of them +define(,<%eax>) +define(,<%ebx>) +define(,<%ecx>) +define(,<%edx>) + +define(,<%r10d>) +define(,<%r11d>) +define(,<%r12d>) + +define(, <%rdi>) +define(, <%rsi>) +define(,<%edx>) C Length is only 32 bits +define(, <%rcx>) +define(, <%r8>) + +define(, <%r9>) +define(,<%r14>) +define(, <%r15d>) +define(, <%r13d>) + +C Must correspond to an old-style register, for movzb from %ah--%dh to +C work. +define(,<%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 index 0000000..c23feb6 --- /dev/null +++ b/x86_64/aes-encrypt-internal.asm @@ -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() + +C Register usage: + +C AES state, use two of them +define(,<%eax>) +define(,<%ebx>) +define(,<%ecx>) +define(,<%edx>) + +define(,<%r10d>) +define(,<%r11d>) +define(,<%r12d>) + +define(, <%rdi>) +define(
, <%rsi>) +define(,<%edx>) C Length is only 32 bits +define(, <%rcx>) +define(, <%r8>) + +define(, <%r9>) +define(,<%r14>) +define(, <%r15d>) +define(, <%r13d>) + +C Must correspond to an old-style register, for movzb from %ah--%dh to +C work. +define(,<%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 index 0000000..8034f77 --- /dev/null +++ b/x86_64/aes.m4 @@ -0,0 +1,130 @@ +dnl LREG(reg) gives the 8-bit register corresponding to the given 32-bit register. +define(,)dnl + +define(,) + +define(,)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(, < + 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(, < + 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(, < + 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(, < + 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(, < + 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/machine.m4 b/x86_64/machine.m4 new file mode 100644 index 0000000..887bf3b --- /dev/null +++ b/x86_64/machine.m4 @@ -0,0 +1,3 @@ +C OFFSET(i) +C Expands to 4*i, or to the empty string if i is zero +define(, ) diff --git a/x86_64/sha1-compress.asm b/x86_64/sha1-compress.asm new file mode 100644 index 0000000..a912ce0 --- /dev/null +++ b/x86_64/sha1-compress.asm @@ -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(,<%eax>)dnl +define(,<%r8d>)dnl +define(,<%ecx>)dnl +define(,<%edx>)dnl +define(,<%r9d>)dnl +define(,<%rsp>)dnl +define(,<%r10d>)dnl +define(,<%r11d>)dnl C Used by F3 +define(, <%esi>)dnl + +C Arguments +define(,<%rdi>)dnl +define(,<%rsi>)dnl + +C Constants +define(, <<$>0x5A827999>)dnl C Rounds 0-19 +define(, <<$>0x6ED9EBA1>)dnl C Rounds 20-39 +define(, <<$>0x8F1BBCDC>)dnl C Rounds 40-59 +define(, <<$>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(, < + 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(, < + 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(, )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(, < + movl $3, TMP + xorl $2, TMP + andl $1, TMP + xorl $3, TMP>)dnl +define(, < + movl $1, TMP + xorl $2, TMP + xorl $3, TMP>)dnl +C Uses TMP2 +define(, < + 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(, < + 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, , NOEXPAND( 0)) + ROUND(SE, SA, SB, SC, SD, , NOEXPAND( 1)) + ROUND(SD, SE, SA, SB, SC, , NOEXPAND( 2)) + ROUND(SC, SD, SE, SA, SB, , NOEXPAND( 3)) + ROUND(SB, SC, SD, SE, SA, , NOEXPAND( 4)) + + ROUND(SA, SB, SC, SD, SE, , NOEXPAND( 5)) + ROUND(SE, SA, SB, SC, SD, , NOEXPAND( 6)) + ROUND(SD, SE, SA, SB, SC, , NOEXPAND( 7)) + ROUND(SC, SD, SE, SA, SB, , NOEXPAND( 8)) + ROUND(SB, SC, SD, SE, SA, , NOEXPAND( 9)) + + ROUND(SA, SB, SC, SD, SE, , NOEXPAND(10)) + ROUND(SE, SA, SB, SC, SD, , NOEXPAND(11)) + ROUND(SD, SE, SA, SB, SC, , NOEXPAND(12)) + ROUND(SC, SD, SE, SA, SB, , NOEXPAND(13)) + ROUND(SB, SC, SD, SE, SA, , NOEXPAND(14)) + + ROUND(SA, SB, SC, SD, SE, , NOEXPAND(15)) + EXPAND(16) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(17) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(18) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(19) ROUND(SB, SC, SD, SE, SA, ) + + movl K2VALUE, KVALUE + EXPAND(20) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(21) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(22) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(23) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(24) ROUND(SB, SC, SD, SE, SA, ) + + EXPAND(25) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(26) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(27) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(28) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(29) ROUND(SB, SC, SD, SE, SA, ) + + EXPAND(30) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(31) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(32) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(33) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(34) ROUND(SB, SC, SD, SE, SA, ) + + EXPAND(35) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(36) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(37) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(38) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(39) ROUND(SB, SC, SD, SE, SA, ) + + movl K3VALUE, KVALUE + EXPAND(40) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(41) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(42) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(43) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(44) ROUND(SB, SC, SD, SE, SA, ) + + EXPAND(45) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(46) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(47) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(48) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(49) ROUND(SB, SC, SD, SE, SA, ) + + EXPAND(50) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(51) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(52) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(53) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(54) ROUND(SB, SC, SD, SE, SA, ) + + EXPAND(55) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(56) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(57) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(58) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(59) ROUND(SB, SC, SD, SE, SA, ) + + movl K4VALUE, KVALUE + EXPAND(60) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(61) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(62) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(63) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(64) ROUND(SB, SC, SD, SE, SA, ) + + EXPAND(65) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(66) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(67) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(68) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(69) ROUND(SB, SC, SD, SE, SA, ) + + EXPAND(70) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(71) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(72) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(73) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(74) ROUND(SB, SC, SD, SE, SA, ) + + EXPAND(75) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(76) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(77) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(78) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(79) ROUND(SB, SC, SD, SE, SA, ) + + 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 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 index 0000000..7645a72 --- /dev/null +++ b/yarrow256.c @@ -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 +#include +#include + +#include "yarrow.h" + +#include "macros.h" + +#ifndef YARROW_DEBUG +#define YARROW_DEBUG 0 +#endif + +#if YARROW_DEBUG +#include +#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; isources[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; insources; 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; insources; 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 index 0000000..92360d9 --- /dev/null +++ b/yarrow_key_event.c @@ -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; +} + -- 2.7.4