The unified diff between revisions [8a2b79c6..] and [44833339..] is displayed below. It can also be downloaded as a raw diff.

#
#
# rename "doc/log.txt"
#     to "doc/logs/log-16.txt"
#
# rename "doc/misc"
#     to "doc/logs"
#
# rename "doc/misc/indent.el"
#     to "doc/indent.el"
#
# add_file "doc/examples/passhash.cpp"
#  content [61f8d76d55bc063f9cec55251585e08e293d74cc]
#
# add_file "doc/logs/log-17.txt"
#  content [854c83de9c38f66705cb95fe1bf8db1aff8cddaf]
#
# add_file "modules/alg_amd64/sha160.cpp"
#  content [17fd07d4bb4956f04f0c6c61407afc3ed80e3e6d]
#
# add_file "modules/alg_amd64/sha1core.S"
#  content [37428d9baed3b84369f894a181ebfe1cf44c5dcc]
#
# add_file "src/dsa_gen.cpp"
#  content [71213b478a52c337f6aad69d3942bdcb51193e3e]
#
# add_file "src/version.cpp"
#  content [3947412507c78b8097be19bc56bffdfe731114f6]
#
# patch "checks/bigint.cpp"
#  from [350f7171b34e0063900a80401d6382a8de8c5010]
#    to [51aea731b8d78f775d76dfa8eefa899ab31db372]
#
# patch "checks/check.cpp"
#  from [73acdead18be7ece2112d96d83ea125593322960]
#    to [13bc69c7aeadb063aee9c8bbb8db2aa68c767379]
#
# patch "checks/pk.cpp"
#  from [93e0079f5e99691acd65ce9689d47da57c81b0ea]
#    to [a35abb667d6a1455f720ca7d084150f1fe76a907]
#
# patch "checks/pk_bench.cpp"
#  from [35b3cb0885e93f496427f3e742a3627daf7d202a]
#    to [d25753ec590b0aa3c2042686f59e72f470b558d6]
#
# patch "checks/validate.cpp"
#  from [421f757824d705c52557bad0b4e4300c522bc9b7]
#    to [c8f8cd4ed6867ae6fd8bbe7c8af0f5c04f847664]
#
# patch "configure.pl"
#  from [47c34d1c5e924c819aaf04bd3f0965f2d5c13121]
#    to [ddf8c9903adfd6d0b20a436b0bdeda99aba45cee]
#
# patch "doc/api.tex"
#  from [8298bf084d4d113e2df22fdbe53366fd753e7deb]
#    to [f33b77380be868c39a2edb508c77051e5b94d88f]
#
# patch "doc/building.tex"
#  from [766f68650552872ddafc3091e70990ecf7e3892b]
#    to [5ffcd552ad48605b03a6dbe526ac39d85451c6e4]
#
# patch "doc/credits.txt"
#  from [82ddba5af31bf8190ccb98d7a322c4bcea5878df]
#    to [e54ece85d28b6137440b9313c4735334e2e6f6f4]
#
# patch "doc/examples/Makefile"
#  from [afe3c8a9246d9f6b1b44af04fc4fcd972699637b]
#    to [76067eb1e3aa94d93bb5c2deca4ce8c0de0adb62]
#
# patch "doc/examples/asn1.cpp"
#  from [bf6c750f7152f7c792172cfd9ce07ff051c0130e]
#    to [4f15025ab441a641f3d07b113a1fd13b5688e17f]
#
# patch "doc/todo.txt"
#  from [e48c9d897f2bc8ebebb57b71180ba0816b3ae66d]
#    to [25dd79beaaee197c26cb5b8e74167a0d2a390bc2]
#
# patch "include/bigint.h"
#  from [689ece18a80002a375af09f33d855f33469aa0f6]
#    to [f81e5621041cfc85cafbe2a72f9ce5fb7145ec58]
#
# patch "include/dl_group.h"
#  from [63df1ce81409a4e8f89feef8fa0c314281f71dd2]
#    to [5c9bb309357d9ef7c1a2140496bbcdb535216919]
#
# patch "include/numthry.h"
#  from [1f9a9f66446b88105642da7214dae8a17cd065fc]
#    to [4d094d0b3a98dbd84783beb080f861d076d1a0f5]
#
# patch "include/rc2.h"
#  from [fcac6cb2073c0446a32ba779892b1acb5dc2c326]
#    to [eaecc46fb58c529ab699898f3f7a881da9b09296]
#
# patch "include/tiger.h"
#  from [67c4f8f3b5e4ffd5b22fb2d41ee8d10a40244651]
#    to [137052ea451bedfce4f867fb1f9d1c9ff1da0cd6]
#
# patch "misc/config/cc/gcc"
#  from [517279cb2443099568b02482c05aa51e3ba2efe7]
#    to [8f5871a7933c06c3db66c6ae748acedc28de85a9]
#
# patch "misc/config/makefile/unix.in"
#  from [32b7a4408a90d77b8f2110fcfdebd3b0123e0fa7]
#    to [ee7062ad81b0ecd648a13a863a0876bbccdaee45]
#
# patch "misc/config/makefile/unix_shr.in"
#  from [ca59084e9e1eef77c70f0aea8b1ff8bdbc02cc68]
#    to [ae60f52d0264845e124e1686b9d0ee0cd94e6d4d]
#
# patch "modules/alg_amd64/asm_macr.h"
#  from [c8fe2875602bdeeb27250cf791110e664b82cf0e]
#    to [b9d8a0bb0350c0f45355b78469fc63bb48c1b590]
#
# patch "modules/alg_amd64/modinfo.txt"
#  from [6086d394850522537238f61f5ffaed5aefa8b4e5]
#    to [0a765bd257f37a2959ec10d20a9299beffb737ae]
#
# patch "modules/alg_amd64/mp_mulop.S"
#  from [01c79c5e9462181cecdd0bff4c4f3b1a2f55ad8c]
#    to [1722e595dcf83cfa57bd5c5e9537dad1376993a7]
#
# patch "modules/alg_ia32/asm_macr.h"
#  from [540af413c630f50e7f0859b972be4d6618c788eb]
#    to [6fbce3454c0456405e2fa41cc9ce7de74cad9fe3]
#
# patch "modules/alg_ia32/modinfo.txt"
#  from [06da382f85623de9067fec5d905bd3356cfe095a]
#    to [99d0df3d5eb6c0b2cfbc26f79da54a6c6f0ca9ab]
#
# patch "modules/alloc_mmap/modinfo.txt"
#  from [f579441d02037bdb1d2ce44737497f1c0badd77a]
#    to [d36d112666314144a5aa817fc24738e9aea91a8a]
#
# patch "modules/comp_bzip2/modinfo.txt"
#  from [c78696d699e0c89529c5fbd0c8a67643ecd3025f]
#    to [85bf9ca722bf07022effa03bfb357136e4c56cfa]
#
# patch "modules/comp_zlib/modinfo.txt"
#  from [7c23c79fa9ffa62f368eed0d61735b81421bad5d]
#    to [5f5620f37503b158951092000b1b72dc1b3b7d82]
#
# patch "modules/eng_aep/modinfo.txt"
#  from [579ec293b81755160084c68cf57d17978f851745]
#    to [c6c85c43e35cb4f019eeeeb055ddb5eb9dc83748]
#
# patch "modules/eng_gmp/modinfo.txt"
#  from [434ba42eea5fae5871d30a6193fcba08dadc6285]
#    to [11311582ba7dfe4746dff64496b75b369eec97bf]
#
# patch "modules/eng_ossl/modinfo.txt"
#  from [864fb3451852a3b3e4cb57e3cb6cbe14950a574b]
#    to [8f79388a72fdf29e9395edcc8e997efda201d79d]
#
# patch "modules/es_beos/modinfo.txt"
#  from [11745ca183c7e6cdd29a5dfd268ad704eec5850e]
#    to [d0a5ef440b6013c1f82e6a39031c78f30e3fadd6]
#
# patch "modules/es_capi/modinfo.txt"
#  from [5dc7e848f8e2e918c07324ad8153a0f1f102ed38]
#    to [a467873f02e52e8e4ba8a88e67fb2c388fc4bfad]
#
# patch "modules/es_egd/modinfo.txt"
#  from [2837cd119013a29ec4446d6ac39434dec6ea833e]
#    to [849799afc6c979db47632b1e12674feea8433633]
#
# patch "modules/es_ftw/modinfo.txt"
#  from [b2d47b89e7a954459b665d7e49243b775f296bbd]
#    to [e768aa15a419357a4b137e2ef3ee65b4b376efdc]
#
# patch "modules/es_unix/modinfo.txt"
#  from [3bdd49d9388e1868229c1932d76407e5e4250535]
#    to [fa9c67a4f4768aa0c066a9cab02c01ef02695b66]
#
# patch "modules/es_win32/modinfo.txt"
#  from [fce9af2f4743da175596dc30864975bfbb600da0]
#    to [ab32f74ac8c68e0eba7b05565cf76ccfae391301]
#
# patch "modules/fd_unix/modinfo.txt"
#  from [d73b45bb1da513ee25176841082d325ac06ab7ce]
#    to [cbc5342abbb086f96ee060c793b2aa2c26c8db88]
#
# patch "modules/ml_unix/modinfo.txt"
#  from [d32034b1b981ea3e88fc2345f0bc124a55a48a6e]
#    to [bf6269c374008bd70e0e70b38e141d608a7348b1]
#
# patch "modules/ml_win32/modinfo.txt"
#  from [6ced9fef6e66978979c5c9100af974de4235ede3]
#    to [a587dfdb9f3e79f0a74b69278520b7c680bacf16]
#
# patch "modules/mp_amd64/modinfo.txt"
#  from [e90ca111f72335f935ef7c0878fd63a67751a4d5]
#    to [707b42d89ee327711973f147e8583142ff52e873]
#
# patch "modules/mp_asm64/modinfo.txt"
#  from [0cc20d0cb895e8bac4c24123c214dc0dd44f67b2]
#    to [b986042b6363c26bff5f6deafdb72136771c2ad5]
#
# patch "modules/mp_ia32/modinfo.txt"
#  from [e6c05e22914ecb6842d2ed9952a95d8285012694]
#    to [d40d210e8f58f97f7f5ededc3ec2d2087d2a326a]
#
# patch "modules/mux_pthr/modinfo.txt"
#  from [9a1693732e2fa3fbbdb68a28ad3523572123c4da]
#    to [0306778b14500cd26b308c4ece786d4c090046f1]
#
# patch "modules/mux_qt/modinfo.txt"
#  from [ee1f0b4f8eb27a801ece47bae80b602139e3164d]
#    to [7a2d33867e046517ab5abbac000f20112a8b9079]
#
# patch "modules/mux_win32/modinfo.txt"
#  from [143f56bb6b4951c992cbfe94f5bbfab217d9f347]
#    to [0f8259741903003ddee76b57fa3eb910ad7cd337]
#
# patch "modules/tm_hard/modinfo.txt"
#  from [e69c63bacd0a135f3e3570a7b6ec571946cf49bc]
#    to [34ed0938a058deec122cda1dcb6011362b896f89]
#
# patch "modules/tm_posix/modinfo.txt"
#  from [f119b7da441d36a3c129fd839378c64849623295]
#    to [31f8fdc8ad4d300118857e941ba9e10a54847456]
#
# patch "modules/tm_unix/modinfo.txt"
#  from [a1b98fb4bcba8d5867029010076eb9fb60f8fcb3]
#    to [b5b5e69895fd4a5f9f7a7ccdc1b8dc12e93c2e49]
#
# patch "modules/tm_win32/modinfo.txt"
#  from [1b79d2d4900442943d871e5585fdb953a23354e6]
#    to [1767c2035911b3d660e62b9d5d46f6a6021f7582]
#
# patch "readme.txt"
#  from [431af18d2e230b901fd7346d5678c4c19c253fe4]
#    to [f87f44e5c245905285cc47ca63517e786915c85e]
#
# patch "src/base.cpp"
#  from [43a02e5c0ec42872bd76b43a73355c3a06828c5b]
#    to [cdaa5f9d688ffedf8e69403aca0bc12efdc9e951]
#
# patch "src/big_base.cpp"
#  from [0e889535d578b076a1658120398b1b12125eb59d]
#    to [e1e47bd2adbead119ac975631c010ca173acfcad]
#
# patch "src/divide.cpp"
#  from [ea20f916193dc209d67e75548d20acf49610bd31]
#    to [e422958f75e485021705cced9c02be03d49f4312]
#
# patch "src/dl_group.cpp"
#  from [4c7a91a8a1ce902edc4483f6bdc74df1fc97a561]
#    to [0067221961c89565b6106d27f4a40d34166808a7]
#
# patch "src/fips140.cpp"
#  from [1093f48a9ddc32be2495fcdfb42e6a71f725d6ae]
#    to [df549a1ac6d511cb6f5a9d9a801bfed4529569cb]
#
# patch "src/libstate.cpp"
#  from [43c2dd9b9bf8e289f1d23e6f55cb7830a40779b4]
#    to [ff89a1505fed854b0dce45db7b7ae802706785f4]
#
# patch "src/make_prm.cpp"
#  from [e805370b0cfe8ee6f71f5988483db948ace4c9ee]
#    to [d665482d002305b15dd878616f4c78fdb76cf76a]
#
# patch "src/oids.cpp"
#  from [f812bbaa6bdbdf76ea1266217946dee1c0dd068b]
#    to [469aad470e7ec8f275bee3ad392a675828b40aeb]
#
# patch "src/pkcs8.cpp"
#  from [319c27dbe18f5ee7237c166108c6a2cabcad3f6a]
#    to [733a303d5cbf22ad09fcb583943de7120358add9]
#
# patch "src/policy.cpp"
#  from [6bcd1fdac7e93a5b9aa60a569dc8c6311110063f]
#    to [1e86b8cdeb93b76a1ef9b35ac4dfc2ba83485f34]
#
# patch "src/rc2.cpp"
#  from [a5a76788d13cbe24f835175d13cbc6d4ee6b877c]
#    to [4cb138bc8daa390e45a613b23fb68c8716b4e6e2]
#
# patch "src/tiger.cpp"
#  from [167f2eff8bb45951178d0390b6ef275f11e882a8]
#    to [fdf03cd77f1d481baf50387da64179d2688aff38]
#
# patch "src/x509_crl.cpp"
#  from [a43c647009f9cac3e2014380479629440e25b0cc]
#    to [8d56ad20f352039dcccff53846813e8cd2600538]
#
# patch "src/x509cert.cpp"
#  from [48c2f3abc19a48f9b12b1e070b8d4ccef3f4de99]
#    to [b4b56e1db59f5870a94444004fa1f6f05edebda6]
#
============================================================
--- doc/examples/passhash.cpp	61f8d76d55bc063f9cec55251585e08e293d74cc
+++ doc/examples/passhash.cpp	61f8d76d55bc063f9cec55251585e08e293d74cc
@@ -0,0 +1,76 @@
+#include <botan/botan.h>
+#include <botan/pkcs5.h>
+#include <iostream>
+
+using namespace Botan;
+
+std::string password_hash(const std::string& pass);
+bool password_hash_ok(const std::string& pass, const std::string& hash);
+
+int main(int argc, char* argv[])
+   {
+   if(argc != 2 && argc != 3)
+      {
+      std::cerr << "Usage: " << argv[0] << " password\n";
+      std::cerr << "Usage: " << argv[0] << " password hash\n";
+      return 1;
+      }
+
+   try
+      {
+      LibraryInitializer init;
+
+      if(argc == 2)
+         std::cout << "H('" << argv[1] << "') = " << password_hash(argv[1]) << '\n';
+      else
+         {
+         bool ok = password_hash_ok(argv[1], argv[2]);
+         if(ok)
+            std::cout << "Password and hash match\n";
+         else
+            std::cout << "Password and hash do not match\n";
+         }
+      }
+   catch(std::exception& e)
+      {
+      std::cerr << e.what() << '\n';
+      return 1;
+      }
+   return 0;
+   }
+
+std::string password_hash(const std::string& pass)
+   {
+   PKCS5_PBKDF2 kdf("SHA-1");
+
+   kdf.set_iterations(10000);
+   kdf.new_random_salt(6); // 48 bits
+
+   Pipe pipe(new Base64_Encoder);
+   pipe.start_msg();
+   pipe.write(kdf.current_salt());
+   pipe.write(kdf.derive_key(12, pass).bits_of());
+   pipe.end_msg();
+
+   return pipe.read_all_as_string();
+   }
+
+bool password_hash_ok(const std::string& pass, const std::string& hash)
+   {
+   Pipe pipe(new Base64_Decoder);
+   pipe.start_msg();
+   pipe.write(hash);
+   pipe.end_msg();
+
+   SecureVector<byte> hash_bin = pipe.read_all();
+
+   PKCS5_PBKDF2 kdf("SHA-1");
+
+   kdf.set_iterations(10000);
+   kdf.change_salt(hash_bin, 6);
+
+   SecureVector<byte> cmp = kdf.derive_key(12, pass).bits_of();
+
+   return same_mem(cmp.begin(), hash_bin.begin() + 6, 12);
+   }
+
============================================================
--- doc/logs/log-17.txt	854c83de9c38f66705cb95fe1bf8db1aff8cddaf
+++ doc/logs/log-17.txt	854c83de9c38f66705cb95fe1bf8db1aff8cddaf
@@ -0,0 +1,8 @@
+
+* 1.7.0, May 19, 2007
+ - DSA parameter generation now follows FIPS 186-3
+ - Added OIDs for Rabin-Williams and Nyberg-Rueppel
+ - Somewhat better support for out of tree builds
+ - Minor optimizations for RC2 and Tiger
+ - Documentation updates
+ - Update the todo list
============================================================
--- modules/alg_amd64/sha160.cpp	17fd07d4bb4956f04f0c6c61407afc3ed80e3e6d
+++ modules/alg_amd64/sha160.cpp	17fd07d4bb4956f04f0c6c61407afc3ed80e3e6d
@@ -0,0 +1,52 @@
+/*************************************************
+* SHA-160 Source File                            *
+* (C) 1999-2006 The Botan Project                *
+*************************************************/
+
+#include <botan/sha160.h>
+#include <botan/bit_ops.h>
+
+namespace Botan {
+
+extern "C" void sha160_core(u32bit[5], const byte[64], u32bit[80]);
+
+/*************************************************
+* SHA-160 Compression Function                   *
+*************************************************/
+void SHA_160::hash(const byte input[])
+   {
+   sha160_core(digest, input, W);
+   }
+
+/*************************************************
+* Copy out the digest                            *
+*************************************************/
+void SHA_160::copy_out(byte output[])
+   {
+   for(u32bit j = 0; j != OUTPUT_LENGTH; ++j)
+      output[j] = get_byte(j % 4, digest[j/4]);
+   }
+
+/*************************************************
+* Clear memory of sensitive data                 *
+*************************************************/
+void SHA_160::clear() throw()
+   {
+   MDx_HashFunction::clear();
+   W.clear();
+   digest[0] = 0x67452301;
+   digest[1] = 0xEFCDAB89;
+   digest[2] = 0x98BADCFE;
+   digest[3] = 0x10325476;
+   digest[4] = 0xC3D2E1F0;
+   }
+
+/*************************************************
+* SHA_160 Constructor                            *
+*************************************************/
+SHA_160::SHA_160() : MDx_HashFunction(20, 64, true, true), W(80)
+   {
+   clear();
+   }
+
+}
============================================================
--- modules/alg_amd64/sha1core.S	37428d9baed3b84369f894a181ebfe1cf44c5dcc
+++ modules/alg_amd64/sha1core.S	37428d9baed3b84369f894a181ebfe1cf44c5dcc
@@ -0,0 +1,252 @@
+/*************************************************
+* SHA-160 Source File                            *
+* (C) 1999-2006 The Botan Project                *
+*************************************************/
+
+#include <botan/asm_macr.h>
+
+START_LISTING(sha1core.S)
+
+START_FUNCTION(sha160_core)
+
+#define DIGEST_ARR %rdi
+#define INPUT %rsi
+#define W %rdx
+#define LOOP_CTR %eax
+
+#define A %r8d
+#define B %r9d
+#define C %r10d
+#define D %r11d
+#define E %ecx
+
+   ZEROIZE(LOOP_CTR)
+
+START_LOOP(.LOAD_INPUT)
+   addl $8, %eax
+
+   movq ARRAY8(INPUT, 0), %r8
+   movq ARRAY8(INPUT, 1), %r9
+   movq ARRAY8(INPUT, 2), %r10
+   movq ARRAY8(INPUT, 3), %r11
+
+   bswap %r8
+   bswap %r9
+   bswap %r10
+   bswap %r11
+
+   rolq $32, %r8
+   rolq $32, %r9
+   rolq $32, %r10
+   rolq $32, %r11
+
+   movq %r8, ARRAY8(W, 0)
+   movq %r9, ARRAY8(W, 1)
+   movq %r10, ARRAY8(W, 2)
+   movq %r11, ARRAY8(W, 3)
+
+   addq $32, W
+   addq $32, INPUT
+LOOP_UNTIL_EQ(LOOP_CTR, 16, .LOAD_INPUT)
+
+/*
+   #define A %r8d
+#define B %r9d
+#define C %r10d
+#define D %r11d
+#define E %ecx
+*/
+START_LOOP(.EXPANSION)
+   addl $4, LOOP_CTR
+
+   ZEROIZE(A)
+   ASSIGN(B, ARRAY4(W, -1))
+   ASSIGN(C, ARRAY4(W, -2))
+   ASSIGN(D, ARRAY4(W, -3))
+
+   XOR(A, ARRAY4(W, -5))
+   XOR(B, ARRAY4(W, -6))
+   XOR(C, ARRAY4(W, -7))
+   XOR(D, ARRAY4(W, -8))
+
+   XOR(A, ARRAY4(W, -11))
+   XOR(B, ARRAY4(W, -12))
+   XOR(C, ARRAY4(W, -13))
+   XOR(D, ARRAY4(W, -14))
+
+   XOR(A, ARRAY4(W, -13))
+   XOR(B, ARRAY4(W, -14))
+   XOR(C, ARRAY4(W, -15))
+   XOR(D, ARRAY4(W, -16))
+
+   ROTL_IMM(D, 1)
+   ROTL_IMM(C, 1)
+   ROTL_IMM(B, 1)
+   XOR(A, D)
+   ROTL_IMM(A, 1)
+
+   ASSIGN(ARRAY4(W, 0), D)
+   ASSIGN(ARRAY4(W, 1), C)
+   ASSIGN(ARRAY4(W, 2), B)
+   ASSIGN(ARRAY4(W, 3), A)
+
+   addq $16, W
+LOOP_UNTIL_EQ(LOOP_CTR, 80, .EXPANSION)
+
+   subq $320, W
+
+#define MAGIC1 0x5A827999
+#define MAGIC2 0x6ED9EBA1
+#define MAGIC3 0x8F1BBCDC
+#define MAGIC4 0xCA62C1D6
+
+#define T %esi
+#define T2 %eax
+
+#define F1(A, B, C, D, E, F, N)       \
+   ASSIGN(T2, ARRAY4(W, N))         ; \
+   ASSIGN(A, F)                     ; \
+   ROTL_IMM(F, 5)                   ; \
+   ADD(F, E)                        ; \
+   ASSIGN(E, C)                     ; \
+   XOR(E, D)                        ; \
+   ADD3_IMM(F, T2, MAGIC1)          ; \
+   AND(E, B)                        ; \
+   XOR(E, D)                        ; \
+   ROTR_IMM(B, 2)                   ; \
+   ADD(E, F)                        ;
+
+#define F2_4(A, B, C, D, E, F, N, MAGIC) \
+   ASSIGN(T2, ARRAY4(W, N))         ; \
+   ASSIGN(A, F)                     ; \
+   ROTL_IMM(F, 5)                   ; \
+   ADD(F, E)                        ; \
+   ASSIGN(E, B)                     ; \
+   XOR(E, C)                        ; \
+   ADD3_IMM(F, T2, MAGIC)           ; \
+   XOR(E, D)                        ; \
+   ROTR_IMM(B, 2)                   ; \
+   ADD(E, F)                        ;
+
+#define F3(A, B, C, D, E, F, N)       \
+   ASSIGN(T2, ARRAY4(W, N))         ; \
+   ASSIGN(A, F)                     ; \
+   ROTL_IMM(F, 5)                   ; \
+   ADD(F, E)                        ; \
+   ASSIGN(E, B)                     ; \
+   OR(E, C)                         ; \
+   AND(E, D)                        ; \
+   ADD3_IMM(F, T2, MAGIC3)          ; \
+   ASSIGN(T2, B)                    ; \
+   AND(T2, C)                       ; \
+   OR(E, T2)                        ; \
+   ROTR_IMM(B, 2)                   ; \
+   ADD(E, F)                        ;
+
+#define F2(A, B, C, D, E, F, W) \
+   F2_4(A, B, C, D, E, F, W, MAGIC2)
+
+#define F4(A, B, C, D, E, F, W) \
+   F2_4(A, B, C, D, E, F, W, MAGIC4)
+
+   ASSIGN(T, ARRAY4(DIGEST_ARR, 0))
+   ASSIGN(B, ARRAY4(DIGEST_ARR, 1))
+   ASSIGN(C, ARRAY4(DIGEST_ARR, 2))
+   ASSIGN(D, ARRAY4(DIGEST_ARR, 3))
+   ASSIGN(E, ARRAY4(DIGEST_ARR, 4))
+
+   /* First Round */
+   F1(A, B, C, D, E, T, 0)
+   F1(T, A, B, C, D, E, 1)
+   F1(E, T, A, B, C, D, 2)
+   F1(D, E, T, A, B, C, 3)
+   F1(C, D, E, T, A, B, 4)
+   F1(B, C, D, E, T, A, 5)
+   F1(A, B, C, D, E, T, 6)
+   F1(T, A, B, C, D, E, 7)
+   F1(E, T, A, B, C, D, 8)
+   F1(D, E, T, A, B, C, 9)
+   F1(C, D, E, T, A, B, 10)
+   F1(B, C, D, E, T, A, 11)
+   F1(A, B, C, D, E, T, 12)
+   F1(T, A, B, C, D, E, 13)
+   F1(E, T, A, B, C, D, 14)
+   F1(D, E, T, A, B, C, 15)
+   F1(C, D, E, T, A, B, 16)
+   F1(B, C, D, E, T, A, 17)
+   F1(A, B, C, D, E, T, 18)
+   F1(T, A, B, C, D, E, 19)
+
+   /* Second Round */
+   F2(E, T, A, B, C, D, 20)
+   F2(D, E, T, A, B, C, 21)
+   F2(C, D, E, T, A, B, 22)
+   F2(B, C, D, E, T, A, 23)
+   F2(A, B, C, D, E, T, 24)
+   F2(T, A, B, C, D, E, 25)
+   F2(E, T, A, B, C, D, 26)
+   F2(D, E, T, A, B, C, 27)
+   F2(C, D, E, T, A, B, 28)
+   F2(B, C, D, E, T, A, 29)
+   F2(A, B, C, D, E, T, 30)
+   F2(T, A, B, C, D, E, 31)
+   F2(E, T, A, B, C, D, 32)
+   F2(D, E, T, A, B, C, 33)
+   F2(C, D, E, T, A, B, 34)
+   F2(B, C, D, E, T, A, 35)
+   F2(A, B, C, D, E, T, 36)
+   F2(T, A, B, C, D, E, 37)
+   F2(E, T, A, B, C, D, 38)
+   F2(D, E, T, A, B, C, 39)
+
+   /* Third Round */
+   F3(C, D, E, T, A, B, 40)
+   F3(B, C, D, E, T, A, 41)
+   F3(A, B, C, D, E, T, 42)
+   F3(T, A, B, C, D, E, 43)
+   F3(E, T, A, B, C, D, 44)
+   F3(D, E, T, A, B, C, 45)
+   F3(C, D, E, T, A, B, 46)
+   F3(B, C, D, E, T, A, 47)
+   F3(A, B, C, D, E, T, 48)
+   F3(T, A, B, C, D, E, 49)
+   F3(E, T, A, B, C, D, 50)
+   F3(D, E, T, A, B, C, 51)
+   F3(C, D, E, T, A, B, 52)
+   F3(B, C, D, E, T, A, 53)
+   F3(A, B, C, D, E, T, 54)
+   F3(T, A, B, C, D, E, 55)
+   F3(E, T, A, B, C, D, 56)
+   F3(D, E, T, A, B, C, 57)
+   F3(C, D, E, T, A, B, 58)
+   F3(B, C, D, E, T, A, 59)
+
+   /* Fourth Round */
+   F4(A, B, C, D, E, T, 60)
+   F4(T, A, B, C, D, E, 61)
+   F4(E, T, A, B, C, D, 62)
+   F4(D, E, T, A, B, C, 63)
+   F4(C, D, E, T, A, B, 64)
+   F4(B, C, D, E, T, A, 65)
+   F4(A, B, C, D, E, T, 66)
+   F4(T, A, B, C, D, E, 67)
+   F4(E, T, A, B, C, D, 68)
+   F4(D, E, T, A, B, C, 69)
+   F4(C, D, E, T, A, B, 70)
+   F4(B, C, D, E, T, A, 71)
+   F4(A, B, C, D, E, T, 72)
+   F4(T, A, B, C, D, E, 73)
+   F4(E, T, A, B, C, D, 74)
+   F4(D, E, T, A, B, C, 75)
+   F4(C, D, E, T, A, B, 76)
+   F4(B, C, D, E, T, A, 77)
+   F4(A, B, C, D, E, T, 78)
+   F4(T, A, B, C, D, E, 79)
+
+   ADD(ARRAY4(DIGEST_ARR, 0), D)
+   ADD(ARRAY4(DIGEST_ARR, 1), T)
+   ADD(ARRAY4(DIGEST_ARR, 2), A)
+   ADD(ARRAY4(DIGEST_ARR, 3), B)
+   ADD(ARRAY4(DIGEST_ARR, 4), C)
+
+END_FUNCTION(sha160_core)
============================================================
--- src/dsa_gen.cpp	71213b478a52c337f6aad69d3942bdcb51193e3e
+++ src/dsa_gen.cpp	71213b478a52c337f6aad69d3942bdcb51193e3e
@@ -0,0 +1,140 @@
+/*************************************************
+* DSA Parameter Generation Source File           *
+* (C) 1999-2007 The Botan Project                *
+*************************************************/
+
+#include <botan/dl_group.h>
+#include <botan/numthry.h>
+#include <botan/libstate.h>
+#include <botan/lookup.h>
+#include <botan/bit_ops.h>
+#include <botan/parsing.h>
+#include <botan/rng.h>
+#include <algorithm>
+#include <memory>
+
+namespace Botan {
+
+namespace {
+
+/*************************************************
+* Check if this size is allowed by FIPS 186-3    *
+*************************************************/
+bool fips186_3_valid_size(u32bit pbits, u32bit qbits)
+   {
+   if(pbits == 1024 && qbits == 160)
+      return true;
+   if(pbits == 2048 && (qbits == 224 || qbits == 256))
+      return true;
+   if(pbits == 3072 && qbits == 256)
+      return true;
+   return false;
+   }
+
+}
+
+/*************************************************
+* Attempt DSA prime generation with given seed   *
+*************************************************/
+bool DL_Group::generate_dsa_primes(BigInt& p, BigInt& q,
+                                   u32bit pbits, u32bit qbits,
+                                   const MemoryRegion<byte>& seed_c)
+   {
+   if(!fips186_3_valid_size(pbits, qbits))
+      throw Invalid_Argument(
+         "FIPS 186-3 does not allow DSA domain parameters of " +
+         to_string(pbits) + "/" + to_string(qbits) + " bits long");
+
+   if(qbits == 224)
+      throw Invalid_Argument(
+         "DSA parameter generation with a q of 224 bits not supported");
+
+   if(seed_c.size() * 8 < qbits)
+      throw Invalid_Argument(
+         "Generating a DSA parameter set with a " + to_string(qbits) +
+         "long q requires a seed at least as many bits long");
+
+   std::auto_ptr<HashFunction> hash(get_hash("SHA-" + to_string(qbits)));
+
+   const u32bit HASH_SIZE = hash->OUTPUT_LENGTH;
+
+   class Seed
+      {
+      public:
+         Seed(const MemoryRegion<byte>& s) : seed(s) {}
+
+         operator MemoryRegion<byte>& () { return seed; }
+
+         Seed& operator++()
+            {
+            for(u32bit j = seed.size(); j > 0; --j)
+               if(++seed[j-1])
+                  break;
+            return (*this);
+            }
+      private:
+         SecureVector<byte> seed;
+      };
+
+   Seed seed(seed_c);
+
+   q.binary_decode(hash->process(seed));
+   q.set_bit(qbits-1);
+   q.set_bit(0);
+
+   if(!is_prime(q))
+      return false;
+
+   global_state().pulse(PRIME_FOUND);
+
+   const u32bit n = (pbits-1) / (HASH_SIZE * 8),
+                b = (pbits-1) % (HASH_SIZE * 8);
+
+   BigInt X;
+   SecureVector<byte> V(HASH_SIZE * (n+1));
+
+   for(u32bit j = 0; j != 4096; ++j)
+      {
+      global_state().pulse(PRIME_SEARCHING);
+
+      for(u32bit k = 0; k <= n; ++k)
+         {
+         ++seed;
+         hash->update(seed);
+         hash->final(V + HASH_SIZE * (n-k));
+         }
+
+      X.binary_decode(V + (HASH_SIZE - 1 - b/8),
+                      V.size() - (HASH_SIZE - 1 - b/8));
+      X.set_bit(pbits-1);
+
+      p = X - (X % (2*q) - 1);
+
+      if(p.bits() == pbits && is_prime(p))
+         {
+         global_state().pulse(PRIME_FOUND);
+         return true;
+         }
+      }
+   return false;
+   }
+
+/*************************************************
+* Generate DSA Primes                            *
+*************************************************/
+SecureVector<byte> DL_Group::generate_dsa_primes(BigInt& p, BigInt& q,
+                                                 u32bit pbits, u32bit qbits)
+   {
+   SecureVector<byte> seed(qbits/8);
+
+   while(true)
+      {
+      Global_RNG::randomize(seed, seed.size());
+      global_state().pulse(PRIME_SEARCHING);
+
+      if(generate_dsa_primes(p, q, pbits, qbits, seed))
+         return seed;
+      }
+   }
+
+}
============================================================
--- src/version.cpp	3947412507c78b8097be19bc56bffdfe731114f6
+++ src/version.cpp	3947412507c78b8097be19bc56bffdfe731114f6
@@ -0,0 +1,28 @@
+/*************************************************
+* Version Information Source File                *
+* (C) 1999-2007 The Botan Project                *
+*************************************************/
+
+#include <botan/version.h>
+#include <botan/parsing.h>
+
+namespace Botan {
+
+/*************************************************
+* Return the version as a string                 *
+*************************************************/
+std::string version_string()
+   {
+   return "Botan " + to_string(version_major()) + "." +
+                     to_string(version_minor()) + "." +
+                     to_string(version_patch());
+   }
+
+/*************************************************
+* Return parts of the version as integers        *
+*************************************************/
+u32bit version_major() { return BOTAN_VERSION_MAJOR; }
+u32bit version_minor() { return BOTAN_VERSION_MINOR; }
+u32bit version_patch() { return BOTAN_VERSION_PATCH; }
+
+}
============================================================
--- checks/bigint.cpp	350f7171b34e0063900a80401d6382a8de8c5010
+++ checks/bigint.cpp	51aea731b8d78f775d76dfa8eefa899ab31db372
@@ -5,6 +5,7 @@
 #include <cstdlib>

 #include <botan/bigint.h>
+#include <botan/exceptn.h>
 #include <botan/numthry.h>
 #include <botan/rng.h>
 using namespace Botan;
@@ -30,10 +31,7 @@ u32bit do_bigint_tests(const std::string
    std::ifstream test_data(filename.c_str());

    if(!test_data)
-       {
-       std::cout << "Couldn't open test file " << filename << std::endl;
-       std::exit(1);
-       }
+      throw Botan::Stream_IO_Error("Couldn't open test file " + filename);

    u32bit errors = 0, alg_count = 0;
    std::string algorithm;
@@ -43,10 +41,8 @@ u32bit do_bigint_tests(const std::string
    while(!test_data.eof())
       {
       if(test_data.bad() || test_data.fail())
-         {
-         std::cout << "File I/O error." << std::endl;
-         std::exit(1);
-         }
+         throw Botan::Stream_IO_Error("File I/O error reading from " +
+                                      filename);

       std::string line;
       std::getline(test_data, line);
============================================================
--- checks/check.cpp	73acdead18be7ece2112d96d83ea125593322960
+++ checks/check.cpp	13bc69c7aeadb063aee9c8bbb8db2aa68c767379
@@ -41,7 +41,8 @@ int main(int argc, char* argv[])

       if(opts.is_set("help") || argc <= 1)
          {
-         std::cerr << Botan::version_string() << " test driver\n"
+         std::cerr << "Test driver for "
+                   << Botan::version_string() << "\n"
                    << "Options:\n"
                    << "  --validate: Check test vectors\n"
                    << "  --benchmark: Benchmark everything\n"
@@ -49,6 +50,7 @@ int main(int argc, char* argv[])
                    << "         Benchmark only algorithms of a particular type\n"
                    << "  --html: Produce HTML output for benchmarks\n"
                    << "  --seconds=n: Benchmark for n seconds\n"
+                   << "  --init=<str>: Pass <str> to the library\n"
                    << "  --help: Print this message\n";
          return 1;
          }
============================================================
--- checks/pk.cpp	93e0079f5e99691acd65ce9689d47da57c81b0ea
+++ checks/pk.cpp	a35abb667d6a1455f720ca7d084150f1fe76a907
@@ -52,11 +52,8 @@ class Fixed_Output_RNG : public RandomNu
          {
          if(position < output.size())
             return output[position++];
-         std::cout << "Fixed_Output_RNG: Ran out of bits" << std::endl;
-         std::exit(1);
-         // Annoying: some compilers warn if a return is here (unreachable
-         // code), others warn if it's not (no return from function).
-         /* return 0; */
+
+         throw Botan::Invalid_State("Fixed_Output_RNG: out of bits");
          }
       void randomize(byte out[], u32bit len) throw()
          {
@@ -101,10 +98,7 @@ u32bit do_pk_validation_tests(const std:
    std::ifstream test_data(filename.c_str());

    if(!test_data)
-       {
-       std::cout << "Couldn't open test file " << filename << std::endl;
-       std::exit(1);
-       }
+      throw Botan::Stream_IO_Error("Couldn't open test file " + filename);

    u32bit errors = 0, alg_count = 0;
    std::string algorithm, print_algorithm;
@@ -112,10 +106,8 @@ u32bit do_pk_validation_tests(const std:
    while(!test_data.eof())
       {
       if(test_data.bad() || test_data.fail())
-         {
-         std::cout << "File I/O error." << std::endl;
-         std::exit(1);
-         }
+         throw Botan::Stream_IO_Error("File I/O error reading from " +
+                                      filename);

       std::string line;
       std::getline(test_data, line);
============================================================
--- checks/pk_bench.cpp	35b3cb0885e93f496427f3e742a3627daf7d202a
+++ checks/pk_bench.cpp	d25753ec590b0aa3c2042686f59e72f470b558d6
@@ -159,13 +159,15 @@ void bench_pk(const std::string& algo, b
       {
       #define DO_DSA(NUM_STR, GROUP)              \
          {                                        \
-         DSA_PrivateKey dsa(DL_Group(GROUP));     \
+         DSA_PrivateKey dsa(GROUP);               \
          bench_dsa(dsa, NUM_STR, seconds, html);  \
          }

-      DO_DSA("512",  "dsa/jce/512");
-      DO_DSA("768",  "dsa/jce/768");
-      DO_DSA("1024", "dsa/jce/1024");
+      DO_DSA("512",  DL_Group("dsa/jce/512"));
+      DO_DSA("768",  DL_Group("dsa/jce/768"));
+      DO_DSA("1024", DL_Group("dsa/jce/1024"));
+      //DO_DSA("2048", DL_Group(DL_Group::DSA_Kosherizer, 2048, 256));
+      //DO_DSA("3072", DL_Group(DL_Group::DSA_Kosherizer, 3072, 256));
       #undef DO_DSA
       }
    if(algo == "All" || algo == "DH")
============================================================
--- checks/validate.cpp	421f757824d705c52557bad0b4e4300c522bc9b7
+++ checks/validate.cpp	c8f8cd4ed6867ae6fd8bbe7c8af0f5c04f847664
@@ -9,6 +9,7 @@
 #include <cstdlib>

 #include <botan/filters.h>
+#include <botan/exceptn.h>
 #include <botan/rng.h>
 using namespace Botan_types;

@@ -51,10 +52,7 @@ u32bit do_validation_tests(const std::st
    bool first_mark = true;

    if(!test_data)
-       {
-       std::cout << "Couldn't open test file " << filename << std::endl;
-       std::exit(1);
-       }
+      throw Botan::Stream_IO_Error("Couldn't open test file " + filename);

    u32bit errors = 0, alg_count = 0;
    std::string algorithm;
@@ -66,10 +64,8 @@ u32bit do_validation_tests(const std::st
    while(!test_data.eof())
       {
       if(test_data.bad() || test_data.fail())
-         {
-         std::cout << "File I/O error." << std::endl;
-         std::exit(1);
-         }
+         throw Botan::Stream_IO_Error("File I/O error reading from " +
+                                      filename);

       std::string line;
       std::getline(test_data, line);
@@ -271,10 +267,7 @@ bool failed_test(const std::string& algo
             OK = false;

       if(!OK)
-         {
-         std::cout << "Peek testing failed!" << std::endl;
-         std::exit(1);
-         }
+         throw Botan::Self_Test_Failure("Peek testing failed in validate.cpp");
       }

    if(output == expected && !exp_pass)
============================================================
--- configure.pl	47c34d1c5e924c819aaf04bd3f0965f2d5c13121
+++ configure.pl	ddf8c9903adfd6d0b20a436b0bdeda99aba45cee
@@ -8,8 +8,8 @@ my $MAJOR_VERSION = 1;
 use File::Copy;

 my $MAJOR_VERSION = 1;
-my $MINOR_VERSION = 6;
-my $PATCH_VERSION = 2;
+my $MINOR_VERSION = 7;
+my $PATCH_VERSION = 0;

 my $VERSION_STRING = "$MAJOR_VERSION.$MINOR_VERSION.$PATCH_VERSION";

@@ -79,9 +79,22 @@ sub main {
     &$default_value_is('autoconfig', 1);
     &$default_value_is('debug', 0);
     &$default_value_is('shared', 'yes');
-    &$default_value_is('build-dir', 'build');
     &$default_value_is('local_config', '');

+    if(defined($$config{'build-dir'})) {
+        $$config{'botan-config'} = File::Spec->catfile($$config{'build-dir'}, 'botan-config');
+        $$config{'makefile'} = File::Spec->catfile($$config{'build-dir'}, 'Makefile');
+        $$config{'check_prefix'} = $$config{'build-dir'};
+        $$config{'lib_prefix'} = $$config{'build-dir'};
+    }
+    else { # defaults
+        $$config{'build-dir'} = 'build';
+        $$config{'botan-config'} = 'botan-config';
+        $$config{'makefile'} = 'Makefile';
+        $$config{'check_prefix'} = '';
+        $$config{'lib_prefix'} = '';
+    }
+
     choose_target($config, $target);

     my $os = $$config{'os'};
@@ -182,14 +195,12 @@ sub trace {
 sub trace {
     return unless $TRACING;

-    my (undef, undef, $line1) = caller(0);
-    my (undef, undef, $line2, $func1) = caller(1);
-    my (undef, undef, undef, $func2) = caller(2);
+    my (undef, undef, $line) = caller(0);
+    my (undef, undef, undef, $func) = caller(1);

-    $func1 =~ s/main:://;
-    $func2 =~ s/main:://;
+    $func =~ s/main:://;

-    warn with_diagnostic('trace', "at $func1:$line1 - ", @_);
+    warn with_diagnostic('trace', "at $func:$line - ", @_);
 }

 ##################################################
@@ -404,7 +415,7 @@ sub get_options {
                'prefix=s' => sub { &$save_option(@_); },
                'docdir=s' => sub { &$save_option(@_); },
                'libdir=s' => sub { &$save_option(@_); },
-               'build-dir=s' => sub { &$save_option('build', $_[0]); },
+               'build-dir=s' => sub { $$config{'build-dir'} = $_[1]; },
                'local-config=s' =>
                   sub { &$save_option('local_config', slurp_file($_[1])); },

@@ -413,8 +424,10 @@ sub get_options {
                'modules=s' => \@modules,
                'module-set=s' => \$module_set,

+               'trace' => sub { $TRACING = 1; },
                'debug' => sub { &$save_option($_[0], 1); },
                'disable-shared' => sub { $$config{'shared'} = 'no'; },
+
                'noauto' => sub { $$config{'autoconfig'} = 0; },
                'dumb-gcc|gcc295x' => sub { $$config{'gcc_bug'} = 1; }
                );
@@ -829,6 +842,9 @@ sub load_modules {

             push @defarray, split(/,/, $defs);
         }
+
+        $defines .= "\n" if(@defarray);
+
         foreach (sort @defarray) {
             die unless(defined $_ and $_ ne '');
             $defines .= "#define BOTAN_EXT_$_\n";
@@ -895,7 +911,7 @@ sub file_type {
     my ($config, $file) = @_;

     return ('sources', $$config{'src-dir'})
-        if($file =~ /\.cpp$/ or $file =~ /\.S$/);
+        if($file =~ /\.cpp$/ or $file =~ /\.c$/ or $file =~ /\.S$/);
     return ('includes', $$config{'include-dir'})
         if($file =~ /\.h$/);

@@ -1104,14 +1120,14 @@ sub get_module_info {

    my %info;
    $info{'name'} = $name;
-   $info{'external_libs'} = 0;
+   $info{'load_on'} = 'requeste'; # default unless specified
    $info{'libs'} = {};

    while($_ = &$reader()) {
        match_any_of($_, \%info, 'quoted', 'realname:note');
        match_any_of($_, \%info, 'unquoted', 'define:mp_bits');

-       $info{'external_libs'} = 1 if(/^uses_external_libs/);
+       $info{'load_on'} = $1 if(/^load_on: (.*)$/);

        read_list($_, $reader, 'arch', list_push(\@{$info{'arch'}}));
        read_list($_, $reader, 'cc', list_push(\@{$info{'cc'}}));
@@ -1262,13 +1278,15 @@ sub guess_mods {
     my $arch = $$config{'arch'};
     my $submodel = $$config{'submodel'};

+    my $asm_ok = ($$config{'debug'} == 0);
+
     my @usable_modules;

     foreach my $mod (sort keys %MODULES) {
         my %modinfo = %{ $MODULES{$mod} };

-        # If it uses external libs, the user has to request it specifically
-        next if($modinfo{'external_libs'});
+        next if($modinfo{'load_on'} eq 'request');
+        next if(!$asm_ok and $modinfo{'load_on'} eq 'asm_ok');

         my @cc_list = @{ $modinfo{'cc'} };
         next if(scalar @cc_list > 0 && !in_array($cc, \@cc_list));
@@ -1297,10 +1315,12 @@ sub write_pkg_config {

     $$config{'link_to'} = libs('-l', '', 'm', @{$$config{'mod_libs'}});

+    my $botan_config = $$config{'botan-config'};
+
     process_template(
        File::Spec->catfile($$config{'config-dir'}, 'botan-config.in'),
-       'botan-config', $config);
-    chmod 0755, 'botan-config';
+                     $botan_config, $config);
+    chmod 0755, $botan_config;

     delete $$config{'link_to'};
 }
@@ -1367,6 +1387,7 @@ sub build_cmds {
         my $obj_file = File::Spec->catfile($dir, $_);

         $obj_file =~ s/\.cpp$/.$obj_suffix/;
+        $obj_file =~ s/\.c$/.$obj_suffix/;
         $obj_file =~ s/\.S$/.$obj_suffix/;

         $output .= "$obj_file: $src_file\n$bld_line\n\n";
@@ -1505,7 +1526,7 @@ sub generate_makefile {
                             map_to($$config{'build_include_botan'},
                                    keys %{$$config{'includes'}}));

-   my $lib_objs = file_list($$config{'build_lib'}, '(\.cpp$|\.S$)',
+   my $lib_objs = file_list($$config{'build_lib'}, '(\.cpp$|\.c$|\.S$)',
                             '.' . $$config{'obj_suffix'},
                             %{$$config{'sources'}});

@@ -1562,7 +1583,7 @@ sub generate_makefile {

    trace("'$make_style' -> '$template'");

-   process_template($template, 'Makefile', $config);
+   process_template($template, $$config{'makefile'}, $config);
 }

 ##################################################
============================================================
--- doc/api.tex	8298bf084d4d113e2df22fdbe53366fd753e7deb
+++ doc/api.tex	f33b77380be868c39a2edb508c77051e5b94d88f
@@ -12,7 +12,7 @@

 \title{\textbf{Botan API Reference}}
 \author{}
-\date{2006/12/14}
+\date{2007/03/03}

 \newcommand{\filename}[1]{\texttt{#1}}
 \newcommand{\manpage}[2]{\texttt{#1}(#2)}
@@ -37,8 +37,8 @@
 \tableofcontents

 \parskip=5pt
-\pagebreak

+\pagebreak
 \section{Introduction}

 Botan is a C++ library which attempts to provide the most common cryptographic
@@ -46,48 +46,28 @@ \section{Introduction}
 runs on a wide variety of systems, using numerous different compilers and on
 many different CPU architectures.

-The base library is written in ISO C++, so it can be ported with minimal fuss,
-but Botan also supports a modules system, which allows system dependent code
-to be compiled into the library for use by application code.
+The base library is written in ISO C++, so it can be ported with
+minimal fuss, but Botan also supports a modules system. This system
+exposes system dependent code to the library through portable
+interfaces, extending the set of services available to users.

-While you are reading this, you may want to refer to the header files
-\filename{base.h} and \filename{pipe.h}. These files contain the classes that
-form the basic interface for the library.
-
-\subsection{Basic Conventions}
-
-With a very small number of exceptions, declarations in the library are
-contained within the namespace \namespace{Botan}. Botan declares several
-typedef'ed types to help buffer it against changes in machine architecture.
-These types are used extensively in the interface, and thus it would be often
-be convenient to use them without the \namespace{Botan} prefix. You can do so
-by \keyword{using} the namespace \namespace{Botan\_types} (this way you can use
-the type names without the namespace prefix, but the remainder of the library
-stays out of the global namespace). The included types are \type{byte} and
-\type{u32bit}, which are unsigned integer types.
-
-The headers for Botan are usually available in the form
-\filename{botan/headername.h}. For brevity in this documentation,
-headers are always just called \filename{headername.h}, but they
-should be used with the \filename{botan/} prefix in your actual code.
-
 \subsection{Targets}

 Botan's primary targets (system-wise) are 32 and 64-bit systems with
 at least a few megabytes of memory. Generally, given the choice
-between optimizing for 32-bit systems and 64-bit systems, Botan
-chooses 64-bits, simply on the theory that where performance really
-matters (servers), people are using 64-bit machines. And also because
-two of the three machines owned by the primary developer have 64-bit
-CPUs. But performance on 32 bit systems is also quite good.
+between optimizing for 32-bit systems and 64-bit systems, Botan is
+written to prefer 64-bit, simply on the theory that where performance
+is a real concern, modern 64-bit processors are the obvious
+choice. And also because two of the three machines owned by the
+primary developer have 64-bit CPUs. But performance on 32 bit systems
+is also quite good.

 Today smaller systems, such as handhelds, set-top boxes, and the
 bigger smart phones and smart cards, are also capable of using
 Botan. However, Botan uses a fairly large amount of code space (up to
 several megabytes, depending upon the compiler and options used),
-which could be prohibitive in some systems. Actual RAM usage is quite
-small, usually under 64K, though C++ runtime overheads might require
-additional memory.
+which could be prohibitive in some systems. Usage of RAM is fairly
+modest, usually under 64K.

 Botan's design makes it quite easy to remove unused algorithms in such a way
 that applications do not need to be recompiled to work, even applications that
@@ -95,8 +75,6 @@ \subsection{Targets}
 exists, and if Botan says yes, ask the library to give them such an object for
 that algorithm.

-\pagebreak
-
 \subsection{Why Botan?}

 Botan may be the perfect choice for your application. Or it might be a
@@ -160,19 +138,43 @@ \subsection{Why Botan?}
 \end{list}

 \pagebreak
+\section{Getting Started}

-\section{Initializing the Library}
+\subsection{Basic Conventions}

-The library needs to have various things done to it in order for it to
-work correctly. To make sure this is done properly, you should create
-a \type{LibraryInitializer} object at the start of your main()
-function, before you start using any part of Botan. The initializer
-does things like initializing the memory allocation system, setting up
-the algorithm lookup tables, finding out if there is a high resolution
-timer available to use, and similar such matters. With no arguments,
-the library is initialized with various default settings. So 99\% of
-the time, all you need is
+With a very small number of exceptions, declarations in the library
+are contained within the namespace \namespace{Botan}. Botan declares
+several typedef'ed types to help buffer it against changes in machine
+architecture.  These types are used extensively in the interface, and
+thus it would be often be convenient to use them without the
+\namespace{Botan} prefix. You can do so by \keyword{using} the
+namespace \namespace{Botan\_types} (this way you can use the type
+names without the namespace prefix, but the remainder of the library
+stays out of the global namespace). The included types are \type{byte}
+and \type{u32bit}, which are unsigned integer types.

+The headers for Botan are usually available in the form
+\filename{botan/headername.h}. For brevity in this documentation,
+headers are always just called \filename{headername.h}, but they
+should be used with the \filename{botan/} prefix in your actual code.
+
+\subsection{Initializing the Library}
+
+There are a set of core services which the library needs access to
+while it is performing requests. To ensure these are set up, you must
+create a \type{LibraryInitializer} object (using called 'init' in
+Botan example code; 'botan\_library' or 'botan\_init' make more sense
+in real code) prior to making any calls to Botan. This object's
+lifetime must exceed that of all other Botan objects your application
+creates; for this reason the best place to create the
+\type{LibraryInitializer} is at the start of your \function{main}
+function, since this guarantees that it will be created first and
+destroyed last. The initializer does things like initializing the
+memory allocation system, setting up the algorithm lookup tables,
+finding out if there is a high resolution timer available to use, and
+similar such matters. With no arguments, the library is initialized
+with various default settings. So 99\% of the time, all you need is
+
 \texttt{Botan::LibraryInitializer init;}

 at the start of your \texttt{main}. If you're not doing anything
@@ -191,24 +193,9 @@ \section{Initializing the Library}
 explicitly turn them on or off. Simply giving the name of the option
 without any argument signifies that the option should be toggled on.

-\noindent
-\textbf{Option ``secure\_memory''}: Try to create a more secure allocator type
--- one that either locks allocated memory into RAM, or that memory maps a disk
-file that it erases after use. If both are available, it will prefer the memory
-mapping mechanism, because locking memory requires privileges on many systems.
+\newcommand{\option}[1]{\noindent \textbf{Option ``#1''}}

-On systems that don't (currently) have any specialized allocators, like
-MS Windows, this option is ignored.
-
-\noindent
-\textbf{Option ``config=/path/to/configfile''}: Process the specified
-configuration file. Configuration files can specify things like the various
-options, new aliases, and new OIDs for algorithms. An example can be found in
-\filename{doc/botan.rc}. Currently only one config= argument will be processed,
-the rest will be ignored.
-
-\noindent
-\textbf{Option ``thread\_safe''}: The library should use mutexes for guarding
+\option{thread\_safe}: The library should use mutexes for guarding
 access to shared resources, such as the memory allocation system. If you pass
 the ``thread\_safe'' option, and the initializer can't find a useful mutex
 module, it will throw an exception. Botan seems to work in threaded programs,
@@ -216,37 +203,38 @@ \section{Initializing the Library}
 is not thread safe at the object level; any objects shared between threads need
 explicit locking.

-\noindent
-\textbf{Option ``use\_engines''}: Use any available ``engine'' modules to speed
-up processing. Currently Botan has support for engines based on the
-AEP1000/AEP2000 crypto hardware cards, GNU MP, and OpenSSL's BN
-library. Further support for crypto acceleration hardware will be added in
-future releases.
+\option{secure\_memory}: Try to create a more secure allocator type --
+one that either locks allocated memory into RAM, or that memory maps a
+disk file that it erases after use. If both are available, it will
+prefer the memory mapping mechanism, because locking memory requires
+privileges on many systems.

-\noindent
-\textbf{Option ``fips140''}: This option, in theory, toggles Botan into FIPS
-140 mode. Please note that Botan \emph{has not} been FIPS 140 validated at this
-time, and that a number of changes will be necessary before such a validation
-can occur. Do not use this option.
+On systems that don't (currently) have any specialized allocators, like
+MS Windows, this option is ignored.

-\noindent
-\textbf{Option ``fips140''}: This option, in theory, toggles Botan into FIPS
-140 mode. Please note that Botan \emph{has not} been FIPS 140 validated at this
-time, and that a number of changes will be necessary before such a validation
-can occur. Do not use this option.
+\option{config=/path/to/configfile}: Process the specified
+configuration file. Configuration files can specify things like the
+various options, new aliases, and new OIDs for algorithms. An example
+can be found in \filename{doc/botan.rc}. Currently only one config=
+argument will be processed, the rest will be ignored.

-\noindent
-\textbf{Option ``selftest''}: Run some basic self tests during
-startup.  Specifically this runs a set of tests for DES, TripleDES,
-AES, CMAC(AES), SHA-1, HMAC(SHA-1), SHA-256, and HMAC(SHA-256).
+\option{use\_engines}: Use any available ``engine'' modules to speed
+up processing. Currently Botan has support for engines based on the
+AEP1000/AEP2000 crypto hardware cards, GNU MP, and OpenSSL's BN
+library. Further support for crypto acceleration hardware will be
+added in future releases.

-This option, in theory, toggles Botan into FIPS
-140 mode. Please note that Botan \emph{has not} been FIPS 140 validated at this
-time, and that a number of changes will be necessary before such a validation
-can occur. Do not use this option.
+\option{fips140}: This option, in theory, toggles Botan into FIPS 140
+mode. Please note that Botan \emph{has not} been FIPS 140 validated at
+this time, and that a number of changes will be necessary before such
+a validation could occur. Do not use this option.

-\noindent
-\textbf{Option ``seed\_rng''}: Attempt to seed the global PRNGs at
+\option{selftest}: Run some basic self tests during startup.
+Specifically this runs a set of tests for DES, TripleDES, AES,
+CMAC(AES), SHA-1, HMAC(SHA-1), SHA-256, and HMAC(SHA-256). This option
+is enabled by default.
+
+\option{seed\_rng}: Attempt to seed the global PRNGs at
 startup. This option is toggled on by default, and can be disabled by passing
 ``seed\_rng=false''. This is primarily useful when you know that the built-in
 library entropy sources will not work, and you are providing you own entropy
@@ -260,18 +248,12 @@ \section{Initializing the Library}
 It is not strictly necessary to create a \type{LibraryInitializer};
 the actual code performing the initialization and shutdown are in
 static member functions of \type{LibraryInitializer}, called
-\function{initialize} and \function{deinitialize}. If you choose to
-use this interface, you should be very careful to make sure that
-\function{deinitialize} is always called, even in the case of
-exceptions, premature exit or abort, and so on. For this reason using
-\type{LibraryInitializer} is preferred, but there are cases where
-using it is impossible and an interface using plain functions is the
-only option.
+\function{initialize} and \function{deinitialize}. A
+\type{LibraryInitializer} merely provides a convenient RAII wrapper
+for the operations (and thus for the internal library state as well).

-\pagebreak
+\subsection{Gotchas}

-\section{Gotchas}
-
 There are a few things to watch out for to prevent problems when using Botan.

 Never allocate any kind of Botan object globally. The problem with doing this
@@ -291,256 +273,734 @@ \section{Gotchas}
 (since in most C++ runtimes, these objects will be destroyed after main has
 returned). This is inelegant, but seems to not cause many problems in practice.

-Never create a Botan memory object (\type{MemoryVector}, \type{SecureVector},
-\type{SecureBuffer}) with a type that is not a basic integer (\type{byte},
-\type{u16bit}, \type{u32bit}, \type{u64bit}). More strongly, if you, as a user
-of the library, are creating any memory buffer object that's not a
-\type{SecureVector<byte>} or maybe a \type{MemoryVector<byte>}, you're probably
-doing something wrong (I suppose there may be exceptions to this rule, but not
-many).
+Botan's memory object classes (\type{MemoryVector},
+\type{SecureVector}, \type{SecureBuffer}) are extremely primitive, and
+do not meet the requirements for an STL container object. After Botan
+starts adopting C++0x features, they will be replaced by typedefs of
+\type{std::vector} with a custom allocator.

-Don't include headers you don't have to. Past experience with Botan has shown
-that headers get renamed fairly regularly as internal design changes are made,
-but this need not affect you, if you follow the ``proper procedures''. Using
-the lookup interface defined in \filename{lookup.h} and \filename{look\_pk.h}
-will save you a great deal of pain in this regard, as it insulates you against
-many such changes.
+Prefer using the factory methods to creating objects directly on the
+stack. This helps insulate your code against changes in the
+implementation, and using a late binding allows your code to access
+faster implementations (hardware or faster software) that might be
+detected as available at runtime.

 Use a \function{try}/\function{catch} block inside your
-\function{main} function, and catch any \type{std::exception}
-throws. This is not strictly required, but if you don't, and Botan
-throws an exception, your application will die mysteriously and
-(probably) without any error message. Some compilers provide a useful
-diagnostic for an uncaught exception, but others simply abort the
-process, leaving your (or worse, a user of your application) wondering
-what went wrong.
+\function{main} function, and catch any \type{std::exception} throws
+(remember to catch by reference, as \type{std::exception}'s
+\function{what} method is polymorphic). This is not strictly required,
+but if you don't, and Botan throws an exception, the runtime will call
+\function{std::terminate}, which usually calls \function{abort} or
+something like it, leaving you (or worse, a user of your application)
+wondering what went wrong.

-\pagebreak
+\subsection{Information Flow: Pipes and Filters}

-\section{The Basic Interface}
+Many common uses of cryptography involve processing one or more
+streams of data (be it from sockets, files, or a hardware device).
+Botan provides services which make setting up data flows through
+various operations, such as compression, encryption, and base64
+encoding. Each of these operations is implemented in what are called
+\emph{filters} in Botan. A set of filters are created and placed into
+a \emph{pipe}, and information ``flows'' through the pipe until it
+reaches the end, where the output is collected for retrieval. If
+you're familiar with the Unix shell environment, this design will
+sound quite familiar.

-Botan has two different interfaces. The one documented in this section is meant
-more for implementing higher-level types (see the section on filters, later in
-this manual) than for use by applications. Using it safely requires a solid
-knowledge of encryption techniques and best practices, so unless you know, for
-example, what CBC mode and nonces are, and why PKCS \#1 padding is important,
-you should avoid this interface in favor of something working at a higher level
-(such as the CMS interface).
+Here is an example which uses a pipe to base64 encode some strings:

-\subsection{Basic Algorithm Abilities}
+\begin{verbatim}
+  Pipe pipe(new Base64_Encoder); // pipe owns the pointer
+  pipe.start_msg();
+  pipe.write(``message 1'');
+  pipe.end_msg(); // flushes buffers, increments message number

-There are a small handful of functions implemented by most of Botan's
-algorithm objects. Among these are:
+  // process_msg(x) is start_msg() && write(x) && end_msg()
+  pipe.process_msg(``message2'');

-\noindent
-\type{std::string} \function{name}():
+  std::string m1 = pipe.read_all_as_string(0); // ``message1''
+  std::string m2 = pipe.read_all_as_string(1); // ``message2''
+\end{verbatim}

-Returns a human-readable string of the name of this algorithm. Examples of
-names returned are ``Blowfish'' and ``HMAC(MD5)''. You can turn names back into
-algorithm objects using the functions in \filename{lookup.h}.
+Bytestreams in the pipe are grouped into messages; blocks of data that
+are processed in an identical fashion (\ie, with the same sequence of
+\type{Filter}s). Messages are delimited by calls to
+\function{start\_msg} and \function{end\_msg}. Each message in a pipe
+has its own number, which increments starting from zero.

-\noindent
-\type{void} \function{clear}():
+As you can see, the \type{Base64\_Encoder} was allocated using
+\keyword{new}; but where was it deallocated? When a filter object is
+passed to a \type{Pipe}, the pipe takes ownership of the object, and
+will deallocate it when it is no longer needed.

-Clear out the algorithm's internal state. A block cipher object will ``forget''
-its key, a hash function will ``forget'' any data put into it, etc. Basically,
-the object will look exactly as it did when you initially allocated it.
+There are two different ways to make use of messages. One is to send
+several messages through a \type{Pipe} without changing the \type{Pipe}'s
+configuration, so you end up with a sequence of messages; one use of this would
+be to send a sequence of identically encrypted UDP packets, for example (note
+that the \emph{data} need not be identical; it is just that each is encrypted,
+encoded, signed, etc in an identical fashion). Another is to change the filters
+that are used in the \type{Pipe} between each message, by adding or removing
+\type{Filter}s; functions that let you do this are documented in the Pipe API
+section.

-\noindent
-\function{clone}():
+Most operations in Botan have a corresponding filter for use in Pipe.
+Here's code that encrypts a string with AES-128 in CBC mode:

-This function is central to Botan's name-based interface. The \function{clone}
-has many different return types, such as \type{BlockCipher*} and
-\type{HashFunction*}, depending on what kind of object it is called on. Note
-that unlike Java's clone, this returns a new object in a ``pristine'' state;
-that is, operations done on the initial object before calling \function{clone}
-do not affect the initial state of the new clone.
+\begin{verbatim}
+  SymmetricKey key(16); // a random 128-bit key
+  InitializationVector iv(16); // a random 128-bit IV

-Cloned objects can (and should) be deallocated with the C++ \texttt{delete}
-operator.
+  // Notice the algorithm we want is specified by a string
+  Pipe pipe(get_cipher(``AES-128/CBC'', key, iv, ENCRYPTION));

-\subsection{Keys and IVs}
+  pipe.process_msg(``secrets'');
+  pipe.process_msg(``more secrets'');

-Both symmetric keys and initialization values can simply be considered byte (or
-octet) strings. These are represented by the classes \type{SymmetricKey} and
-\type{InitializationVector}, which are subclasses of \type{OctetString}.
+  MemoryVector<byte> c1 = pipe.read_all(0);

-Since often it's hard to distinguish between a key and IV, many things (such as
-key derivation mechanisms) return \type{OctetString} instead of
-\type{SymmetricKey} to allow its use as a key or an IV.
+  byte c2[4096] = { 0 };
+  u32bit got_out = pipe.read(c2, sizeof(c2), 1);
+  // use c2[0...got_out]
+\end{verbatim}

-\noindent
-\function{OctetString}(\type{u32bit} \arg{length}):
+\type{Pipe} also has convenience methods for dealing with
+\type{std::iostream}s. Here is an example of those, using
+the \type{Bzip\_Compression} filter (included as a module;
+if you have bzlib available, check \filename{building.pdf}
+for how to enable it) to compress a file:

-This constructor creates a new random key of size \arg{length}.
+\begin{verbatim}
+  std::ifstream in(``data.bin'', std::ios::binary)
+  std::ofstream out(``data.bin.bz2'', std::ios::binary)

-\noindent
-\function{OctetString}(\type{std::string} \arg{str}):
+  Pipe pipe(new Bzip_Compression);

-The argument \arg{str} is assumed to be a hex string; it is converted to binary
-and stored. Whitespace is ignored.
+  pipe.start_msg();
+  in >> pipe;
+  pipe.end_msg();
+  out << pipe;
+\end{verbatim}

-\noindent
-\function{OctetString}(\type{const byte} \arg{input}[], \type{u32bit}
-\arg{length}):
+However there is a hitch to the code above; the complete contents of
+the compressed data will be held in memory until the entire message
+has been compressed, at which time the statement \verb|out << pipe| is
+executed, and the data is freed as it is read from the pipe and
+written to the file. But if the file is very large, we might not have
+enough physical memory (or even enough virtual memory!) for that to be
+practical. So instead of storing the compressed data in the pipe for
+reading it out later, we divert it directly to the file:

-This constructor simply copies its input.
+\begin{verbatim}
+  std::ifstream in(``data.bin'', std::ios::binary)
+  std::ofstream out(``data.bin.bz2'', std::ios::binary)

-\subsection{Symmetrically Keyed Algorithms}
+  Pipe pipe(new Bzip_Compression, new DataSink_Stream(out));

-Block ciphers, stream ciphers, and MACs all handle keys in pretty much the same
-way. To make this similarity explicit, all algorithms of those types are
-derived from the \type{SymmetricAlgorithm} base class. This type has three
-functions:
+  pipe.start_msg();
+  in >> pipe;
+  pipe.end_msg();
+\end{verbatim}

-\noindent
-\type{void} \function{set\_key}(\type{const byte} \arg{key}[], \type{u32bit}
-\arg{length}):
+This is the first code we've seen so far that uses more than one
+filter in a pipe. The output of the compressor is sent to the
+\type{DataSink\_Stream}. Anything written to a \type{DataSink\_Stream}
+is written to a file; the filter produces no output. As soon as the
+compression algorithm finishes up a block of data, it will send it along,
+at which point it will immediately be written to disk; if you were to
+call \verb|pipe.read_all()| after \verb|pipe.end_msg()|, you'd get an
+empty vector out.

-Most algorithms only accept keys of certain lengths. If you attempt to call
-\function{set\_key} with a key length that is not supported, the exception
-\type{Invalid\_Key\_Length} will be thrown. There is also another version of
-\function{set\_key} that takes a \type{SymmetricKey} as an argument.
+Here's an example using two computational filters:

-\noindent
-\type{bool} \function{valid\_keylength}(\type{u32bit} \arg{length}) const:
+\begin{verbatim}
+   SymmetricKey key(32);
+   InitializationVector iv(16); // or use: block_size_of("AES")
+   Pipe encryptor(get_cipher("AES/CBC/PKCS7", key, iv, ENCRYPTION),
+                  new Base64_Encoder);
+   encryptor.start_msg();
+   file >> encryptor;
+   encryptor.end_msg(); // flush buffers, complete computations
+   std::cout << encryptor;
+\end{verbatim}

-This function returns true if a key of the given length will be accepted by
-the cipher.
+\subsection{Fork}

-There are also three constant data members of every \type{SymmetricAlgorithm}
-object, which specify exactly what limits there are on keys which that object
-can accept:
+It is fairly common that you might receive some data and want to perform more
+than one operation on it (\ie, encrypt it with DES and calculate the MD5 hash
+of the plaintext at the same time). That's where \type{Fork} comes
+in. \type{Fork} is a filter that takes input and passes it on to \emph{one or
+more} \type{Filter}s which are attached to it. \type{Fork} changes the nature
+of the pipe system completely. Instead of being a linked list, it becomes a
+tree.

-MAXIMUM\_KEYLENGTH: The maximum length of a key. Usually, this is at most 32
-(256 bits), even if the algorithm actually supports more. In a few rare cases
-larger keys will be supported.
+Each \type{Filter} in the fork is given its own output buffer, and
+thus its own message. For example, if you had previously written two
+messages into a \type{Pipe}, then you start a new one with a
+\type{Fork} which has three paths of \type{Filter}'s inside it, you
+add three new messages to the \type{Pipe}. The data you put into the
+\type{Pipe} is duplicated and sent into each set of \type{Filter}s,
+and the eventual output is placed into a dedicated message slot in the
+\type{Pipe}.

-MINIMUM\_KEYLENGTH: The minimum length of a key. This is at least 1.
+Messages in the \type{Pipe} are allocated in a depth-first manner. This is only
+interesting if you are using more than one \type{Fork} in a single \type{Pipe}.
+As an example, consider the following:

-KEYLENGTH\_MULTIPLE: The length of the key must be a multiple of this value.
+\begin{verbatim}
+   Pipe pipe(new Fork(
+                new Fork(
+                   new Base64_Encoder,
+                   new Fork(
+                      NULL,
+                      new Base64_Encoder
+                      )
+                   ),
+                new Hex_Encoder
+                )
+      );
+\end{verbatim}

-In all cases, \function{set\_key} must be called on an object before any data
-processing (encryption, decryption, etc) is done by that object. If this is not
-done, the results are undefined -- that is to say, Botan reserves the right in
-this situation to do anything from printing a nasty, insulting message on the
-screen to dumping core.
+In this case, message 0 will be the output of the first \type{Base64\_Encoder},
+message 1 will be a copy of the input (see below for how \type{Fork} interprets
+NULL pointers), message 2 will be the output of the second
+\type{Base64\_Encoder}, and message 3 will be the output of the
+\type{Hex\_Encoder}. As you can see, this results in message numbers being
+allocated in a top to bottom fashion, when looked at on the screen. However,
+note that there could be potential for bugs if this is not anticipated. For
+example, if your code is passed a \type{Filter}, and you assume it is a
+``normal'' one which only uses one message, your message offsets would be
+wrong, leading to some confusion during output.

-\subsection{Block Ciphers}
+If Fork's first argument is a null pointer, but a later argument is
+not, then Fork will feed a copy of its input directly through. Here's
+a case where that is useful:

-Block ciphers implement the interface \type{BlockCipher}, found in
-\filename{base.h}, as well as the \type{SymmetricAlgorithm} interface.
+\begin{verbatim}
+   // have std::string ciphertext, auth_code, key, iv, mac_key;

-\noindent
-\type{void} \function{encrypt}(\type{const byte} \arg{in}[BLOCK\_SIZE],
-                               \type{byte} \arg{out}[BLOCK\_SIZE]) const
+   Pipe pipe(new Base64_Decoder, get_cipher(``AES-128'', key, iv, DECRYPTION),
+             new Fork(
+                0
+                new MAC_Filter(``HMAC(SHA-1)'', mac_key)
+             )
+      );

-\noindent
-\type{void} \function{encrypt}(\type{byte} \arg{block}[BLOCK\_SIZE]) const
+   pipe.process_msg(ciphertext);
+   std::string plaintext = pipe.read_all_as_string(0);
+   SecureVector<byte> mac = pipe.read_all(1);

-These functions apply the block cipher transformation to \arg{in} and
-place the result in \arg{out}, or encrypts \arg{block} in place
-(\arg{in} may be the same as \arg{out}). BLOCK\_SIZE is a constant
-member of each class, which specifies how much data a block cipher can
-process at one time. Note that BLOCK\_SIZE is not a static class
-member, meaning you can (given a \type{BlockCipher*} named
-\arg{cipher}), call \verb|cipher->BLOCK_SIZE| to get the block size of
-that particular object. \type{BlockCipher}s have similar functions
-\function{decrypt}, which perform the inverse operation.
+   if(mac != auth_code)
+      error();
+\end{verbatim}

+Here we wanted to not only decrypt the message, but send the decrypted
+text through an additional computation, in order to compute the
+authentication code.
+
+Any \type{Filter}s which are attached to the \type{Pipe} after the
+\type{Fork} are implicitly attached onto the first branch created by
+the fork. For example, let's say you created this \type{Pipe}:
+
 \begin{verbatim}
-AES_128 cipher;
-SymmetricKey key(cipher.MAXIMUM_KEYLENGTH); // randomly created
-cipher.set_key(key);
+Pipe pipe(new Fork(new Hash_Filter("MD5"), new Hash_Filter("SHA-1")),
+          new Hex_Encoder);
+\end{verbatim}

-byte in[16] = { /* secrets */ };
-byte out[16];
-cipher.encrypt(in, out);
+And then called \function{start\_msg}, inserted some data, then
+\function{end\_msg}. Then \arg{pipe} would contain two messages. The
+first one (message number 0) would contain the MD5 sum of the input in
+hex encoded form, and the other would contain the SHA-1 sum of the
+input in raw binary. However, it's much better to use a \type{Chain}
+instead.
+
+\subsubsection{Chain}
+
+A \type{Chain} filter creates a chain of \type{Filter}s and
+encapsulates them inside a single filter (itself). This allows a
+sequence of filters to become a single filter, to be passed into or
+out of a function, or to a \type{Fork} constructor.
+
+You can call \type{Chain}'s constructor with up to 4 \type{Filter*}s
+(they will be added in order), or with an array of \type{Filter*}s and
+a \type{u32bit} which tells \type{Chain} how many \type{Filter*}s are
+in the array (again, they will be attached in order). Here's the
+example from the last section, using chain instead of relying on the
+obscure rule that version used.
+
+\begin{verbatim}
+  Pipe pipe(new Fork(
+                new Chain(new Hash_Filter("MD5"), new Hex_Encoder),
+                new Hash_Filter("SHA-1")
+                )
+           );
 \end{verbatim}

-\subsection{Stream Ciphers}
+\subsection{The Pipe API}

-Stream ciphers are somewhat different from block ciphers, in that encrypting
-data results in changing the internal state of the cipher. Also, you may
-encrypt any length of data in one go (in byte amounts).
+\subsubsection{Initializing Pipe}

-\noindent
-\type{void} \function{encrypt}(\type{const byte} \arg{in}[], \type{byte}
-\arg{out}[], \type{u32bit} \arg{length})
+By default, \type{Pipe} will do nothing at all; any input placed into
+the \type{Pipe} will be read back unchanged. Obviously, this has
+limited utility, and presumably you want to use one or more
+\type{Filter}s to somehow process the data. First, you can choose a
+set of \type{Filter}s to initialize the \type{Pipe} with via the
+constructor. You can pass it either a set of up to 4 \type{Filter*}s,
+or a pre-defined array and a length:

-\noindent
-\type{void} \function{encrypt}(\type{byte} \arg{data}[], \type{u32bit}
-\arg{length}):
+\begin{verbatim}
+   Pipe pipe1(new Filter1(/*args*/), new Filter2(/*args*/),
+              new Filter3(/*args*/), new Filter4(/*args*/));
+   Pipe pipe2(new Filter1(/*args*/), new Filter2(/*args*/));

-These functions encrypt the arbitrary length (well, less than 4 gigabyte long)
-string \arg{in} and place it into \arg{out}, or encrypts it in place in
-\arg{data}. The \function{decrypt} functions look just like
-\function{encrypt}.
+   Filter* filters[5] = {
+     new Filter1(/*args*/), new Filter2(/*args*/), new Filter3(/*args*/),
+     new Filter4(/*args*/), new Filter5(/*args*/) /* more if desired... */
+   };
+   Pipe pipe3(filters, 5);
+\end{verbatim}

-Stream ciphers implement the \type{SymmetricAlgorithm} interface.
+This is by far the most common way to initialize a \type{Pipe}. However,
+occasionally a more flexible initialization strategy is necessary; this is
+supported by 4 member functions: \function{prepend}(\type{Filter*}),
+\function{append}(\type{Filter*}), \function{pop}(), and \function{reset}().
+These functions may only be used while the \type{Pipe} in question is not in
+use; that is, either before calling \function{start\_msg}, or after
+\function{end\_msg} has been called (and no new calls to \function{start\_msg}
+have been made yet).

-Some stream ciphers support random access to any point in their cipher
-stream. For such ciphers, calling \type{void} \function{seek}(\type{u32bit}
-\arg{byte}) will change the cipher's state so that it as if the cipher had been
-keyed as normal, then encrypted \arg{byte} -- 1 bytes of data (so the next byte
-in the cipher stream is byte number \arg{byte}).
+The function \function{reset}() simply removes all the \type{Filter}s
+which the \type{Pipe} is currently using~--~it is reset to an
+initialize, ``empty'' state.  Any data which is being retained by the
+\type{Pipe} is retained after a \function{reset}(), and
+\function{reset}() does not affect the message numbers (discussed
+later).

-\subsection{Hash Functions / Message Authentication Codes}
+Calling \function{prepend} and \function{append} will either prepend
+or append the passed \type{Filter} object to the list of
+transformations. For example, if you \function{prepend} a
+\type{Filter} implementing encryption, and the \type{Pipe} already had
+a \type{Filter} which hex encoded the input, then the next set of
+input would be first encrypted, then hex encoded. Alternately, if you
+called \function{append}, then the input would be first be hex
+encoded, and then encrypted (which is not terribly useful in this
+particular example).

-Hash functions take their input without producing any output, only producing
-anything when all input has already taken place. MACs are very similar, but are
-additionally keyed. Both of these are derived from the base class
-\type{BufferedComputation}, which has the following functions.
+Finally, calling \function{pop}() will remove the first transformation
+of the \type{Pipe}. Say we had called \function{prepend} to put an
+encryption \type{Filter} into a \type{Pipe}; calling \function{pop}()
+would remove this \type{Filter} and return the \type{Pipe} to its
+state before we called \function{prepend}.

+\subsubsection{Giving Data to a Pipe}
+
+Input to a \type{Pipe} is delimited into messages, which can be read from
+independently (\ie, you can read 5 bytes from one message, and then all of
+another message, without either read affecting any other messages). The
+messages are delimited by calls to \function{start\_msg} and
+\function{end\_msg}. In between these two calls, you can write data into a
+\type{Pipe}, and it will be processed by the \type{Filter}(s) that it
+contains. Writes at any other time are invalid, and will result in an
+exception.
+
+As to writing, you can call any of the functions called \function{write}(),
+which can take any of: a \type{byte[]}/\type{u32bit} pair, a
+\type{SecureVector<byte>}, a \type{std::string}, a \type{DataSource\&}, or a
+single \type{byte}.
+
+Sometimes, you may want to do only a single write per message. In this case,
+you can use the \function{process\_msg} series of functions, which start a
+message, write their argument into the \type{Pipe}, and then end the
+message. In this case you would not make any explicit calls to
+\function{start\_msg}/\function{end\_msg}. The version of \function{write}
+which takes a single \type{byte} is not supported by \function{process\_msg},
+but all the other variants are.
+
+\type{Pipe} can also be used with the \verb|>>| operator, and will accept a
+\type{std::istream}, (or on Unix systems with the \verb|fd_unix| module), a
+Unix file descriptor. In either case, the entire contents of the file will be
+read into the \type{Pipe}.
+
+\subsubsection{Getting Output from a Pipe}
+
+Retrieving the processed data from a \type{Pipe} is a bit more complicated, for
+various reasons. In particular, because \type{Pipe} will separate each message
+into a separate buffer, you have to be able to retrieve data from each message
+independently. Each of \type{Pipe}'s read functions has a final parameter which
+specifies what message to read from (as a 32-bit integer). If this parameter is
+set to \type{Pipe::DEFAULT\_MESSAGE}, it will read the current default message
+(\type{DEFAULT\_MESSAGE} is also the default value of this parameter). The
+parameter will not be mentioned in further discussion of the reading API, but
+it is always there (unless otherwise noted).
+
+Reading is done with a variety of functions. The most basic are \type{u32bit}
+\function{read}(\type{byte} \arg{out}[], \type{u32bit} \arg{len}) and
+\type{u32bit} \function{read}(\type{byte\&} \arg{out}). Each reads into
+\arg{out} (either up to \arg{len} bytes, or a single byte for the one taking a
+\type{byte\&}), and returns the total number of bytes read. There is a variant
+of these functions, all named \function{peek}, which performs the same
+operations, but does not remove the bytes from the message (reading is a
+destructive operation with a \type{Pipe}).
+
+There are also the functions \type{SecureVector<byte>} \function{read\_all}(),
+and \type{std::string} \function{read\_all\_as\_string}(), which return the
+entire contents of the message, either as a memory buffer, or a
+\type{std::string} (which is generally only useful is the \type{Pipe} has
+encoded the message into a text string, such as when a \type{Base64\_Encoder}
+is used).
+
+To determine how many bytes are left in a message, call \type{u32bit}
+\function{remaining}() (which can also take an optional message
+number). Finally, there are some functions for managing the default message
+number: \type{u32bit} \function{default\_msg}() will return the current default
+message, \type{u32bit} \function{message\_count}() will return the total number
+of messages (0...\function{message\_count}()-1), and
+\function{set\_default\_msg}(\type{u32bit} \arg{msgno}) will set a new default
+message number (which must be a valid message number for that \type{Pipe}). The
+ability to set the default message number is particularly important in the case
+of using the file output operations (\verb|<<| with a \type{std::ostream} or
+Unix file descriptor), because there is no way to specify it explicitly when
+using the output operator.
+
+\subsection{A Filter Example}
+
+Here is some code which takes one or more filenames in \arg{argv} and
+calculates the result of several hash functions for each file. The complete
+program can be found as \filename{hasher.cpp} in the Botan distribution. For
+brevity, most error checking has been removed.
+
+\begin{verbatim}
+   string name[3] = { "MD5", "SHA-1", "RIPEMD-160" };
+   Botan::Filter* hash[3] = {
+      new Botan::Chain(new Botan::Hash_Filter(name[0]),
+                        new Botan::Hex_Encoder),
+      new Botan::Chain(new Botan::Hash_Filter(name[1]),
+                        new Botan::Hex_Encoder),
+      new Botan::Chain(new Botan::Hash_Filter(name[2]),
+                        new Botan::Hex_Encoder) };
+
+   Botan::Pipe pipe(new Botan::Fork(hash, COUNT));
+
+   for(u32bit j = 1; argv[j] != 0; j++)
+      {
+      ifstream file(argv[j]);
+      pipe.start_msg();
+      file >> pipe;
+      pipe.end_msg();
+      file.close();
+      for(u32bit k = 0; k != 3; k++)
+         {
+         pipe.set_default_msg(3*(j-1)+k);
+         cout << name[k] << "(" << argv[j] << ") = " << pipe << endl;
+         }
+      }
+\end{verbatim}
+
+
+\subsection{Filter Catalog}
+
+This section contains descriptions of every \type{Filter} included in
+the portable sections of Botan. \type{Filter}s provided by modules
+are documented elsewhere.
+
+\subsubsection{Keyed Filters}
+
+A few sections ago, it was mentioned that \type{Pipe} can process multiple
+messages, treating each of them exactly the same. Well, that was a bit of a
+lie. There are some algorithms (in particular, block ciphers not in ECB mode,
+and all stream ciphers) that change their state as data is put through them.
+
+Naturally, you might well want to reset the keys or (in the case of block
+cipher modes) IVs used by such filters, so multiple messages can be processed
+using completely different keys, or new IVs, or new keys and IVs, or whatever.
+And in fact, even for a MAC or an ECB block cipher, you might well want to
+change the key used from message to message.
+
+Enter \type{Keyed\_Filter}, which acts as an abstract interface for
+any filter that is uses keys: block cipher modes, stream ciphers,
+MACs, and so on. It has two functions, \function{set\_key} and
+\function{set\_iv}. Calling \function{set\_key} will, naturally, set
+(or reset) the key used by the algorithm. Setting the IV only makes
+sense in certain algorithms -- a call to \function{set\_iv} on an
+object that doesn't support IVs will be ignored. You \emph{must} call
+\function{set\_key} before calling \function{set\_iv}: while not all
+\type{Keyed\_Filter} objects require this, you should assume it is
+required anytime you are using a \type{Keyed\_Filter}.
+
+Here's a example:
+
+\begin{verbatim}
+   Keyed_Filter *cast, *hmac;
+   Pipe pipe(new Base64_Decoder,
+             // Note the assignments to the cast and hmac variables
+             cast = new CBC_Decryption("CAST-128", "PKCS7", cast_key, iv),
+             new Fork(
+                0, // Read the section 'Fork' to understand this
+                new Chain(
+                   hmac = new MAC_Filter("HMAC(SHA-1)", mac_key, 12),
+                   new Base64_Encoder
+                   )
+                )
+      );
+   pipe.start_msg();
+   [use pipe for a while, decrypt some stuff, derive new keys and IVs]
+   pipe.end_msg();
+
+   cast->set_key(cast_key2);
+   cast->set_iv(iv2);
+   hmac->set_key(mac_key2);
+
+   pipe.start_msg();
+   [use pipe for some other things]
+   pipe.end_msg();
+\end{verbatim}
+
+There are some requirements to using \type{Keyed\_Filter} which you must
+follow. If you call \function{set\_key} or \function{set\_iv} on a filter which
+is owned by a \type{Pipe}, you must do so while the \type{Pipe} is
+``unlocked''. This refers to the times when no messages are being processed by
+\type{Pipe} -- either before \type{Pipe}'s \function{start\_msg} is called, or
+after \function{end\_msg} is called (and no new call to \function{start\_msg}
+has happened yet). Doing otherwise will result in undefined behavior, probably
+silently getting invalid output.
+
+And remember: if you're resetting both values, reset the key \emph{first}.
+
+\subsubsection{Cipher Filters}
+
+Getting ahold of a \type{Filter} implementing a cipher is very easy. Simply
+make sure you're including the header \filename{lookup.h}, and call
+\function{get\_cipher}. Generally you will pass the return value directly into
+a \type{Pipe}. There are actually a couple different functions, which do pretty
+much the same thing:
+
+\function{get\_cipher}(\type{std::string} \arg{cipher\_spec},
+                       \type{SymmetricKey} \arg{key},
+                       \type{InitializationVector} \arg{iv},
+                       \type{Cipher\_Dir} \arg{dir});
+
+\function{get\_cipher}(\type{std::string} \arg{cipher\_spec},
+                       \type{SymmetricKey} \arg{key},
+                       \type{Cipher\_Dir} \arg{dir});
+
+The version that doesn't take an IV is useful for things that don't use them,
+like block ciphers in ECB mode, or most stream ciphers. If you specify a
+\arg{cipher\_spec} that does want a IV, and you use the version that doesn't
+take one, an exception will be thrown. The \arg{dir} argument can be either
+\type{ENCRYPTION} or \type{DECRYPTION}. In a few cases, like most (but not all)
+stream ciphers, these are equivalent, but even then it provides a way of
+showing the ``intent'' of the operation to readers of your code.
+
+The \arg{cipher\_spec} is a string that specifies what cipher is to be
+used. The general syntax for \arg{cipher\_spec} is ``STREAM\_CIPHER'',
+``BLOCK\_CIPHER/MODE'', or ``BLOCK\_CIPHER/MODE/PADDING''. In the case of
+stream ciphers, no mode is necessary, so just the name is sufficient. A block
+cipher requires a mode of some sort, which can be ``ECB'', ``CBC'', ``CFB(n)'',
+``OFB'', ``CTR-BE'', or ``EAX(n)''. The argument to CFB mode is how many bits
+of feedback should be used. If you just use ``CFB'' with no argument, it will
+default to using a feedback equal to the block size of the cipher. EAX mode
+also takes an optional bit argument, which tells EAX how large a tag size to
+use~--~generally this is the size of the block size of the cipher, which is the
+default if you don't specify any argument.
+
+In the case of the ECB and CBC modes, a padding method can also be
+specified. If it is not supplied, ECB defaults to not padding, and CBC defaults
+to using PKCS \#5/\#7 compatible padding. The padding methods currently
+available are ``NoPadding'', ``PKCS7'', ``OneAndZeros'', and ``CTS''. CTS
+padding is currently only available for CBC mode, but the others can also be
+used in ECB mode.
+
+Some example \arg{cipher\_spec} arguments are: ``DES/CFB(32)'',
+``TripleDES/OFB'', ``Blowfish/CBC/CTS'', ``SAFER-SK(10)/CBC/OneAndZeros'',
+``AES/EAX'', ``ARC4''
+
+``CTR-BE'' refers to counter mode where the counter is incremented as if it
+were a big-endian encoded integer. This is compatible with most other
+implementations, but it is possible some will use the incompatible little
+endian convention. This version would be denoted as ``CTR-LE'' if it were
+supported.
+
+``EAX'' is a new cipher mode designed by Wagner, Rogaway, and Bellare. It is an
+authenticated cipher mode (that is, no separate authentication is needed), has
+provable security, and is free from patent entanglements. It runs about half as
+fast as most of the other cipher modes (like CBC, OFB, or CTR), which is not
+bad considering you don't need to use an authentication code.
+
+\subsubsection{Hashes and MACs}
+
+Hash functions and MACs don't need anything special when it comes to
+filters. Both just take their input and produce no output until
+\function{end\_msg()} is called, at which time they complete the hash or MAC
+and send that as output.
+
+These \type{Filter}s take a string naming the type to be used. If for some
+reason you name something that doesn't exist, an exception will be thrown.
+
 \noindent
-\type{void} \function{update}(\type{const byte} \arg{input}[], \type{u32bit}
-\arg{length})
+\function{Hash\_Filter}(\type{std::string} \arg{hash},
+                        \type{u32bit} \arg{outlength}):

+This type hashes its input with \arg{hash}. When \function{end\_msg} is called
+on the owning \type{Pipe}, the hash is completed and the digest is sent on to
+the next thing in the pipe. The argument \arg{outlength} specifies how much of
+the output of the hash will be passed along to the next filter when
+\function{end\_msg} is called. By default, it will pass the entire hash.
+
+Examples of names for \function{Hash\_Filter} are ``SHA-1'' and ``Whirlpool''.
+
 \noindent
-\type{void} \function{update}(\type{byte} \arg{input})
+\function{MAC\_Filter}(\type{std::string} \arg{mac},
+                       \type{const SymmetricKey\&} \arg{key},
+                       \type{u32bit} \arg{outlength}):

+The constructor for a \type{MAC\_Filter} takes a key, used in calculating the
+MAC, and a length parameter, which has semantics exactly the same as the one
+passed to \type{Hash\_Filter}s constructor.
+
+Examples for \arg{mac} are ``HMAC(SHA-1)'', ``CMAC(AES-128)'', and the
+exceptionally long, strange, and probably useless name
+``CMAC(Lion(Tiger(20,3),MARK-4,1024))''.
+
+\subsubsection{PK Filters}
+
+There are four classes in this category, \type{PK\_Encryptor\_Filter},
+\type{PK\_Decryptor\_Filter}, \type{PK\_Signer\_Filter}, and
+\type{PK\_Verifier\_Filter}. Each takes a pointer to an object of the
+appropriate type (\type{PK\_Encryptor}, \type{PK\_Decryptor}, etc) which is
+deleted by the destructor. These classes are found in \filename{pk\_filts.h}.
+
+Three of these, for encryption, decryption, and signing are pretty much
+identical conceptually. Each of them buffers its input until the end of the
+message is marked with a call to the \function{end\_msg} function. Then they
+encrypt, decrypt, or sign their input and send the output (the ciphertext, the
+plaintext, or the signature) into the next filter.
+
+Signature verification works a little differently, because it needs to know
+what the signature is in order to check it. You can either pass this in along
+with the constructor, or call the function \function{set\_signature} -- with
+this second method, you need to keep a pointer to the filter around so you can
+send it this command. In either case, after \function{end\_msg} is called, it
+will try to verify the signature (if the signature has not been set by either
+method, an exception will be thrown here). It will then send a single byte onto
+the next filter -- a 1 or a 0, which specifies whether the signature verified
+or not (respectively).
+
+For more information about PK algorithms (including creating the appropriate
+objects to pass to the constructors), read the section ``Public Key
+Cryptography'' in this manual.
+
+\subsubsection{Encoders}
+
+Often you want your data to be in some form of text (for sending over channels
+which aren't 8-bit clean, printing it, etc). The filters \type{Hex\_Encoder}
+and \type{Base64\_Encoder} will convert arbitrary binary data into hex or
+base64 formats. Not surprisingly, you can use \type{Hex\_Decoder} and
+\type{Base64\_Decoder} to convert it back into its original form.
+
+Both of the encoders can take a few options about how the data should be
+formatted (all of which have defaults). The first is a \type{bool} which simply
+says if the encoder should insert line breaks. This defaults to
+false. Line breaks don't matter either way to the decoder, but it makes the
+output a bit more appealing to the human eye, and a few transport mechanisms
+(notably some email systems) limit the maximum line length.
+
+The second encoder option is an integer specifying how long such lines will be
+(obviously this will be ignored if line-breaking isn't being used). The default
+tends to be in the range of 60-80 characters, but is not specified exactly. If
+you want a specific value, set it. Otherwise the default should be fine.
+
+Lastly, \type{Hex\_Encoder} takes an argument of type \type{Case}, which can be
+\type{Uppercase} or \type{Lowercase} (default is \type{Uppercase}). This
+specifies what case the characters A-F should be output as. The base64 encoder
+has no such option, because it uses both upper and lower case letters for its
+output.
+
+The decoders both take a single option, which tells it how the object should
+behave in the case of invalid input. The enum (called \type{Decoder\_Checking})
+can take on any of three values: \type{NONE}, \type{IGNORE\_WS}, and
+\type{FULL\_CHECK}. With \type{NONE} (the default, for compatibility with
+previous releases), invalid input (for example, a ``z'' character in supposedly
+hex input) will simply be ignored. With \type{IGNORE\_WS}, whitespace will be
+ignored by the decoder, but receiving other non-valid data will raise an
+exception. Finally, \type{FULL\_CHECK} will raise an exception for \emph{any}
+characters not in the encoded character set, including whitespace.
+
+You can find the declarations for these types in \filename{hex.h} and
+\filename{base64.h}.
+
+\subsection{Rolling Your Own}
+
+The system of filters and pipes was designed in an attempt to make it
+as simple as possible to write new \type{Filter} objects. There are
+essentially four functions that need to be implemented by an object
+deriving from \type{Filter}:
+
 \noindent
-\type{void} \function{update}(\type{const std::string \&} \arg{input})
+\type{void} \function{write}(\type{byte} \arg{input}[], \type{u32bit}
+\arg{length}):

-Updates the hash/mac calculation with \arg{input}.
+The \function{write} function is what is called when a filter receives input
+for it to process. The filter is \emph{not} required to process it right away;
+many filters buffer their input before producing any output. A filter will
+usually have \function{write} called many times during its lifetime.

 \noindent
-\type{void} \function{final}(\type{byte} \arg{out}[OUTPUT\_LENGTH])
+\type{void} \function{send}(\type{byte} \arg{output}[], \type{u32bit}
+\arg{length}):

+Eventually, a filter will want to produce some output to send along to the next
+filter in the pipeline. It does so by calling \function{send} with whatever it
+wants to send along to the next filter. There is also a version of
+\function{send} taking a single byte argument, as a convenience.
+
 \noindent
-\type{SecureVector<byte>} \function{final}():
+\type{void} \function{start\_msg()}:

-Complete the hash/MAC calculation and place the result into \arg{out}.
-OUTPUT\_LENGTH is a public constant in each object that gives the length of the
-hash in bytes. After you call \function{final}, the hash function is reset to
-its initial state, so it may be reused immediately.
+This function is optional. Implement it if your \type{Filter} would like to do
+some processing or setup at the start of each message (for an example, see the
+Zlib compression module).

-The second method of using final is to call it with no arguments at all, as
-shown in the second prototype. It will return the hash/mac value in a memory
-buffer, which will have size OUTPUT\_LENGTH.
+\noindent
+\type{void} \function{end\_msg()}:

-There are also a pair of functions called \function{process}. They are
-essentially a combination of a single \function{update}, and \function{final}.
-Both versions return the final value, rather than placing it an array. Calling
-\function{process} with a single byte value isn't available, mostly because it
-would rarely be useful.
+Implementing the \function{end\_msg} function is optional. It is called when it
+has been requested that filters finish up their computations. Note that they
+must \emph{not} deallocate their resources; this should be done by their
+destructor. They should simply finish up with whatever computation they have
+been working on (for example, a compressing filter would flush the compressor
+and \function{send} the final block), and empty any buffers in preparation for
+processing a fresh new set of input. It is essentially the inverse of
+\function{start\_msg}.

-A MAC can be viewed (in most cases) as simply a keyed hash function, so classes
-which are derived from \type{MessageAuthenticationCode} have \function{update}
-and \function{final} classes just like a \type{HashFunction} (and like a
-\type{HashFunction}, after \function{final} is called, it can be used to make a
-new MAC right away; the key is kept around).
+Additionally, if necessary, filters can define a constructor that takes any
+needed arguments, and a destructor to deal with deallocating memory, closing
+files, etc.

-A MAC has the \type{SymmetricAlgorithm} interface in addition to the
-\type{BufferedComputation} interface.
+There is also a \type{BufferingFilter} class (in \filename{buf\_filt.h}) which
+will take a message and split it up into an initial block which can be of any
+size (including zero), a sequence of fixed sized blocks of any non-zero size,
+and last (possibly zero-sized) final block. This might make a useful base class
+for your filters, depending on what you have in mind.

+
 \pagebreak
+\section{Public Key Cryptography}

-\section{Public Key Cryptography}
+Let's create an RSA private key:

-Public key algorithms were added in Botan 0.8.0. The major base classes can be
-found in \filename{pubkey.h}.
+\begin{verbatim}
+   RSA_PrivateKey priv_rsa(1024 /* bits */);
+\end{verbatim}

+We can easily turn this into a public key, which we can then send to
+someone:
+
+\begin{verbatim}
+   RSA_PublicKey pub_rsa = priv_rsa;
+\end{verbatim}
+
+
+
+
 \subsection{Creating PK Algorithm Key Objects}

 The library has interfaces for encryption, signatures, etc that do not require
@@ -808,35 +1268,39 @@ \subsubsection{Public Keys}
 }
 \end{verbatim}

-Basically, \function{X509::encode} will take an \type{X509\_PublicKey} (as of
-now, that's any RSA, DSA, or Diffie-Hellman key) and encodes it using
-\arg{enc}, which can be either \type{PEM} or \type{RAW\_BER}. Using \type{PEM}
-is \emph{highly} recommended for many reasons, including compatibility with
-other software, for transmission over 8-bit unclean channels, because it can be
-identified by a human without special tools, and because it sometimes allows
-more sane behavior of tools that process the data. It will place the encoding
-into \arg{out}. Remember that if you have just created the \type{Pipe} that you
-are passing to \function{X509::encode}, you need to call \function{start\_msg}
-first. Particularly with public keys, about 99\% of the time you just want to
-PEM encode the key and then write it to a file or something. In this case, it's
-probably easier to use \function{X509::PEM\_encode}. This function will simply
-return the PEM encoding of the key as a \type{std::string}.
+Basically, \function{X509::encode} will take an \type{X509\_PublicKey}
+(as of now, that's any RSA, DSA, or Diffie-Hellman key) and encodes it
+using \arg{enc}, which can be either \type{PEM} or
+\type{RAW\_BER}. Using \type{PEM} is \emph{highly} recommended for
+many reasons, including compatibility with other software, for
+transmission over 8-bit unclean channels, because it can be identified
+by a human without special tools, and because it sometimes allows more
+sane behavior of tools that process the data. It will place the
+encoding into \arg{out}. Remember that if you have just created the
+\type{Pipe} that you are passing to \function{X509::encode}, you need
+to call \function{start\_msg} first. Particularly with public keys,
+about 99\% of the time you just want to PEM encode the key and then
+write it to a file or something. In this case, it's probably easier to
+use \function{X509::PEM\_encode}. This function will simply return the
+PEM encoding of the key as a \type{std::string}.

-For loading a public key, the preferred method is one of the variants of
-\function{load\_key}. This function will return a newly allocated key based on
-the data from whatever source it is using (assuming, of course, the source is
-in fact storing a representation of a public key). The encoding used (PEM or
-BER) need not be specified; the format will be detected automatically. The key
-is allocated with \function{new}, and should be released with \function{delete}
-when you are done with it. The first takes a generic \type{DataSource} which
-you have to allocate~--~the others are simple wrapper functions that take
-either a filename or a memory buffer.
+For loading a public key, the preferred method is one of the variants
+of \function{load\_key}. This function will return a newly allocated
+key based on the data from whatever source it is using (assuming, of
+course, the source is in fact storing a representation of a public
+key). The encoding used (PEM or BER) need not be specified; the format
+will be detected automatically. The key is allocated with
+\function{new}, and should be released with \function{delete} when you
+are done with it. The first takes a generic \type{DataSource} which
+you have to allocate~--~the others are simple wrapper functions that
+take either a filename or a memory buffer.

-So what can you do with the return value of \function{load\_key}? On its own, a
-\type{X509\_PublicKey} isn't particularly useful; you can't encrypt messages or
-verify signatures, or much else. But, using \function{dynamic\_cast}, you can
-figure out what kind of operations the key supports. Then, you can cast the key
-to the appropriate type and pass it to a higher-level class. For example:
+So what can you do with the return value of \function{load\_key}? On
+its own, a \type{X509\_PublicKey} isn't particularly useful; you can't
+encrypt messages or verify signatures, or much else. But, using
+\function{dynamic\_cast}, you can figure out what kind of operations
+the key supports. Then, you can cast the key to the appropriate type
+and pass it to a higher-level class. For example:

 \begin{verbatim}
    /* Might be RSA, might be ElGamal, might be ... */
@@ -849,8 +1313,6 @@ \subsubsection{Public Keys}
    SecureVector<byte> cipher = enc->encrypt(some_message, size_of_message);
 \end{verbatim}

-\pagebreak
-
 \subsubsection{Private Keys}

 There are two different options for private key import/export. The first is a
@@ -977,665 +1439,6 @@ \subsubsection{Limitations}
 the current one (\ie, a newly standardized format).

 \pagebreak
-
-\section{Filters and Pipes}
-
-\subsection{Basic Filter Usage}
-
-Up until this point, using Botan would be very tedious; to do anything you
-would have to bother with putting data into arrays, doing whatever you want
-with it, and then sending it someplace. The filter metaphor (defining a series
-of operations which take some amount of input, process it, then send it along
-to the next filter) works very well in this situation. If you've ever used a
-Unix system, the usage of filters in Botan should be very intuitive (and even
-if you haven't, don't worry, it's pretty easy). For instance, here is how you
-encrypt a file with AES in CBC mode with PKCS\#7 padding, then encode it with
-Base64 and send it to standard output (we assume that \verb|file| is an open
-\type{istream}):
-
-\begin{verbatim}
-   SymmetricKey key(32);
-   InitializationVector iv(16); // or use: block_size_of("AES")
-   Pipe encryptor(get_cipher("AES/CBC/PKCS7", key, iv, ENCRYPTION),
-                  new Base64_Encoder);
-   encryptor.start_msg();
-   file >> encryptor;
-   encryptor.end_msg(); // flush buffers, complete computations
-   std::cout << encryptor;
-\end{verbatim}
-
-\type{Pipe} works in conjunction with the \type{Filter} class (for example, the
-\type{CBC\_Encryption} and \type{Base64\_Encoder} types used above are
-\type{Filter}s), but you never have to deal with them directly; \type{Pipe}
-handles all the required housekeeping. \type{Pipe} is fully documented in the
-section titled ``The Pipe API'', which appears later in this section.
-
-A useful ability of \type{Pipe} is to split up the work up into what are called
-``messages''. Messages are blocks of data that are processed in an identical
-fashion (\ie, with the same sequence of \type{Filter}s). Messages are delimited
-by the \function{start\_msg} and \function{end\_msg} functions, as shown
-above. There are two different ways to make use of messages. One is to send
-several messages through a \type{Pipe} without changing the \type{Pipe}'s
-configuration, so you end up with a sequence of messages; one use of this would
-be to send a sequence of identically encrypted UDP packets, for example (note
-that the \emph{data} need not be identical; it is just that each is encrypted,
-encoded, signed, etc in an identical fashion). Another is to change the filters
-that are used in the \type{Pipe} between each message, by adding or removing
-\type{Filter}s; functions that let you do this are documented in the Pipe API
-section. Pipe's full interface definition can be found in \filename{pipe.h}
-
-\subsubsection{Fork}
-
-It's fairly common that you might receive some data and want to perform more
-than one operation on it (\ie, encrypt it with DES and calculate the MD5 hash
-of the plaintext at the same time). That's where \type{Fork} comes
-in. \type{Fork} is a filter that takes input and passes it on to \emph{one or
-more} \type{Filter}s which are attached to it. \type{Fork} changes the nature
-of the pipe system completely. Instead of being a linked list, it becomes a
-tree.
-
-Before messages were added to Botan, using \type{Fork} was significantly more
-complicated, requiring you to keep pointers to \type{Fork} objects you
-allocated and sending control information to them when you wanted to read your
-output. Now, however, things are much simpler. Each \type{Filter} in the fork
-is given its own output buffer, and thus its own message. For example, if you
-have previously written two messages into a \type{Pipe}, then you start a new
-one with a \type{Fork} which has three paths of \type{Filter}'s inside it, you
-add three new messages to the \type{Pipe}. The data you put into the
-\type{Pipe} is duplicated and sent into each set of \type{Filter}s, and the
-eventual output is placed into a dedicated message slot in the \type{Pipe}.
-
-Messages in the \type{Pipe} are allocated in a depth-first manner. This is only
-interesting if you are using more than one \type{Fork} in a single \type{Pipe}.
-As an example, consider the following:
-
-\begin{verbatim}
-   Pipe pipe(new Fork(
-                new Fork(
-                   new Base64_Encoder,
-                   new Fork(
-                      NULL,
-                      new Base64_Encoder
-                      )
-                   ),
-                new Hex_Encoder
-                )
-      );
-\end{verbatim}
-
-In this case, message 0 will be the output of the first \type{Base64\_Encoder},
-message 1 will be a copy of the input (see below for how \type{Fork} interprets
-NULL pointers), message 2 will be the output of the second
-\type{Base64\_Encoder}, and message 3 will be the output of the
-\type{Hex\_Encoder}. As you can see, this results in message numbers being
-allocated in a top to bottom fashion, when looked at on the screen. However,
-note that there could be potential for bugs if this is not anticipated. For
-example, if your code is passed a \type{Filter}, and you assume it is a
-``normal'' one which only uses one message, your message offsets would be
-wrong, leading to some confusion during output.
-
-An alternate method (which is \emph{not} used) would be to give the first
-message to the first \type{Base64\_Encoder}, the second to the
-\type{Hex\_Encoder}, and then the last two messages to the two \type{Filter}s
-in the innermost \type{Fork}.
-
-The \filename{hasher} and \filename{hasher2} examples show two different ways
-of using \type{Pipe} and \type{Fork}.
-
-There is a very useful trick that you can do with \type{Fork}. Let's say you
-had some data that had been encrypted with a block cipher, and then hex
-encoded. In addition, a hex encoded MAC of the plaintext had been calculated
-and included with the message. You not only want to decrypt the data, you want
-to verify the MAC. So the first two filters in the pipe will decode the hex,
-and decrypt the raw ciphertext. But now, how are you going to both a) get the
-plaintext, and b) calculate the MAC of the plaintext? This is actually very
-simple, if a bit obscure.
-
-What you have to do is, after the filters that do the initial decoding, create
-a \type{Fork}. For the first argument, pass a null pointer. The fork object
-will understand that this means that you don't want to do any more processing
-on that line of the fork; you just want the data that was placed in. And then
-in the second argument you would pass in a \type{MAC\_Filter} so you could
-compute a MAC of the plaintext. An alternative is to define a simple
-passthrough/null \type{Filter}, which just calls \function{send} whenever
-\arg{write} is called. This is (in the author's opinion) pointless, but there
-is nothing stopping you from doing so if desired.
-
-For an example of this technique, look at the \filename{rsa\_dec} example in
-\filename{doc/examples/}.
-
-Any \type{Filter}s which are attached to the \type{Pipe} after the \type{Fork}
-are implicitly attached onto the first branch created by the fork. For example,
-let's say you created this \type{Pipe}:
-
-\begin{verbatim}
-Pipe pipe(new Fork(new Hash_Filter("MD5"), new Hash_Filter("SHA-1")),
-          new Hex_Encoder);
-\end{verbatim}
-
-And then called \function{start\_msg}, inserted some data, then
-\function{end\_msg}. Then \arg{pipe} would contain two messages. The first one
-(message number 0) would contain the MD5 sum of the input in hex encoded form,
-and the other would contain the SHA-1 sum of the input in raw binary.
-
-\subsubsection{Chain}
-
-\type{Chain} is about as simple as it gets. \type{Chain} creates a chain of
-\type{Filter}s and encapsulates them inside a single filter (itself). This is
-primarily useful for passing a sequence of filters into something which is
-expecting only a single \type{Filter} (most notably, \type{Fork}). You can call
-\type{Chain}'s constructor with up to 4 \type{Filter*}s (they will be added in
-order), or with an array of \type{Filter*}s and a \type{u32bit} which tells
-\type{Chain} how many \type{Filter*}s are in the array (again, they will be
-attached in order). See the section ``A Filter Example'' for an example of
-using \type{Chain}.
-
-\subsubsection{Data Sources}
-
-A \type{DataSource} is a simple abstraction for a thing that stores bytes. This
-type is used fairly heavily in the areas of the API related to ASN.1
-encoding/decoding. The following types are \type{DataSource}s: \type{Pipe},
-\type{SecureQueue}, and a couple of special purpose ones:
-\type{DataSource\_Memory} and \type{DataSource\_Stream}.
-
-You can create a \type{DataSource\_Memory} with an array of bytes and a length
-field. The object will make a copy of the data, so you don't have to worry
-about keeping that memory allocated. This is mostly for internal use, but if it
-comes in handy, feel free to use it.
-
-A \type{DataSource\_Stream} is probably more useful than the memory based
-one. It's constructors take either a \type{std::istream} or a
-\type{std::string}. If it's a stream, the data source will use the
-\type{istream} to satisfy read requests (this is particularly useful to use
-with \type{std::cin}). If the string version is used, it will attempt to open
-up a file with that name and read from it.
-
-\subsubsection{Data Sinks}
-
-A \type{DataSink} (in \filename{data\_snk.h}) is a \type{Filter} which takes
-arbitrary amounts of input, and produces no output. Generally, this means it's
-doing something with the data outside the realm of what
-\type{Filter}/\type{Pipe} can handle, for example, writing it to a file (which
-is what the \type{DataSink\_Stream} does). There is no need for
-\type{DataSink}s which write to a \type{std::string} or memory buffer, because
-\type{Pipe} can handle that by itself.
-
-Here's a quick example of using a \type{DataSink}, which encrypts
-\filename{in.txt} and sends the output to \filename{out.txt}. There is
-no explicit output operation; the writing of \filename{out.txt} is
-implicit.
-
-\begin{verbatim}
-   DataSource_Stream in("in.txt");
-   Pipe pipe(new CBC_Encryption("Blowfish", "PKCS7", key, iv),
-             new DataSink_Stream("out.txt"));
-   pipe.process_msg(in);
-\end{verbatim}
-
-A real advantage of this is that even if ``in.txt'' is large (say, 1
-gigabyte), only as much memory is needed for internal I/O buffers will actually
-be used. A naive use of \type{Pipe} would, in that case, use up about 1
-gigabyte of memory, by storing the full encrypted version of the file in
-memory, and then writing it all out at once.
-
-\subsection{The Pipe API}
-
-Using \type{Pipe} is supposed to be pretty easy (especially in the common,
-simple cases). The usage is generally as follows: Initialize a \type{Pipe} with
-the filters you want to use, write some data into it, and then read some
-processed data out.
-
-\subsubsection{Initializing Pipe}
-
-By default, \type{Pipe} will do nothing at all; any input placed into the
-\type{Pipe} will be read back unchanged. Obviously, this has limited utility,
-and presumably you want to use one or more \type{Filter}s to somehow process
-the data. First, you can choose a set of \type{Filter}s to initialize the
-\type{Pipe} with via the constructor. Namely, you can pass it either a set of
-up to 4 \type{Filter*}s, or a pre-defined array and a length:
-
-\begin{verbatim}
-   Pipe pipe1(new Filter1(/*args*/), new Filter2(/*args*/),
-              new Filter3(/*args*/), new Filter4(/*args*/));
-   Pipe pipe2(new Filter1(/*args*/), new Filter2(/*args*/));
-
-   Filter* filters[5] = {
-     new Filter1(/*args*/), new Filter2(/*args*/), new Filter3(/*args*/),
-     new Filter4(/*args*/), new Filter5(/*args*/) /* more if desired... */
-   };
-   Pipe pipe3(filters, 5);
-\end{verbatim}
-
-This is by far the most common way to initialize a \type{Pipe}. However,
-occasionally a more flexible initialization strategy is necessary; this is
-supported by 4 member functions: \function{prepend}(\type{Filter*}),
-\function{append}(\type{Filter*}), \function{pop}(), and \function{reset}().
-These functions may only be used while the \type{Pipe} in question is not in
-use; that is, either before calling \function{start\_msg}, or after
-\function{end\_msg} has been called (and no new calls to \function{start\_msg}
-have been made yet).
-
-The function \function{reset}() simply removes all the \type{Filter}s which the
-\type{Pipe} is currently using~--~it is reset to an initialize, ``empty''
-state.  Any data which is being retained by the \type{Pipe} is retained after a
-\function{reset}(), and \function{reset}() does not affect the message numbers
-(discussed later).
-
-Calling \function{prepend} and \function{append} will either prepend or append
-the passed \type{Filter} object to the list of transformations. For example, if
-you \function{prepend} a \type{Filter} implementing encryption, and the
-\type{Pipe} already had a \type{Filter} which hex encoded the input, then the
-next set of input would be first encrypted, then hex encoded. Alternately, if
-you called \function{append}, then the input would be first be hex encoded, and
-then encrypted (which is not terribly useful in this particular example).
-
-Finally, calling \function{pop}() will remove the first transformation of the
-\type{Pipe}. Say we had called \function{prepend} to put an encryption
-\type{Filter} into a \type{Pipe}; calling \function{pop}() would remove this
-\type{Filter} and return the \type{Pipe} to it's state before we called
-\function{prepend}.
-
-\subsubsection{Giving Data to a Pipe}
-
-Input to a \type{Pipe} is delimited into messages, which can be read from
-independently (\ie, you can read 5 bytes from one message, and then all of
-another message, without either read affecting any other messages). The
-messages are delimited by calls to \function{start\_msg} and
-\function{end\_msg}. In between these two calls, you can write data into a
-\type{Pipe}, and it will be processed by the \type{Filter}(s) that it
-contains. Writes at any other time are invalid, and will result in an
-exception.
-
-As to writing, you can call any of the functions called \function{write}(),
-which can take any of: a \type{byte[]}/\type{u32bit} pair, a
-\type{SecureVector<byte>}, a \type{std::string}, a \type{DataSource\&}, or a
-single \type{byte}.
-
-Sometimes, you may want to do only a single write per message. In this case,
-you can use the \function{process\_msg} series of functions, which start a
-message, write their argument into the \type{Pipe}, and then end the
-message. In this case you would not make any explicit calls to
-\function{start\_msg}/\function{end\_msg}. The version of \function{write}
-which takes a single \type{byte} is not supported by \function{process\_msg},
-but all the other variants are.
-
-\type{Pipe} can also be used with the \verb|>>| operator, and will accept a
-\type{std::istream}, (or on Unix systems with the \verb|fd_unix| module), a
-Unix file descriptor. In either case, the entire contents of the file will be
-read into the \type{Pipe}.
-
-\subsubsection{Getting Output from a Pipe}
-
-Retrieving the processed data from a \type{Pipe} is a bit more complicated, for
-various reasons. In particular, because \type{Pipe} will separate each message
-into a separate buffer, you have to be able to retrieve data from each message
-independently. Each of \type{Pipe}'s read functions has a final parameter which
-specifies what message to read from (as a 32-bit integer). If this parameter is
-set to \type{Pipe::DEFAULT\_MESSAGE}, it will read the current default message
-(\type{DEFAULT\_MESSAGE} is also the default value of this parameter). The
-parameter will not be mentioned in further discussion of the reading API, but
-it is always there (unless otherwise noted).
-
-Reading is done with a variety of functions. The most basic are \type{u32bit}
-\function{read}(\type{byte} \arg{out}[], \type{u32bit} \arg{len}) and
-\type{u32bit} \function{read}(\type{byte\&} \arg{out}). Each reads into
-\arg{out} (either up to \arg{len} bytes, or a single byte for the one taking a
-\type{byte\&}), and returns the total number of bytes read. There is a variant
-of these functions, all named \function{peek}, which performs the same
-operations, but does not remove the bytes from the message (reading is a
-destructive operation with a \type{Pipe}).
-
-There are also the functions \type{SecureVector<byte>} \function{read\_all}(),
-and \type{std::string} \function{read\_all\_as\_string}(), which return the
-entire contents of the message, either as a memory buffer, or a
-\type{std::string} (which is generally only useful is the \type{Pipe} has
-encoded the message into a text string, such as when a \type{Base64\_Encoder}
-is used).
-
-To determine how many bytes are left in a message, call \type{u32bit}
-\function{remaining}() (which can also take an optional message
-number). Finally, there are some functions for managing the default message
-number: \type{u32bit} \function{default\_msg}() will return the current default
-message, \type{u32bit} \function{message\_count}() will return the total number
-of messages (0...\function{message\_count}()-1), and
-\function{set\_default\_msg}(\type{u32bit} \arg{msgno}) will set a new default
-message number (which must be a valid message number for that \type{Pipe}). The
-ability to set the default message number is particularly important in the case
-of using the file output operations (\verb|<<| with a \type{std::ostream} or
-Unix file descriptor), because there is no way to specify it explicitly when
-using the output operator.
-
-\pagebreak
-
-\subsection{A Filter Example}
-
-Here is some code which takes one or more filenames in \arg{argv} and
-calculates the result of several hash functions for each file. The complete
-program can be found as \filename{hasher.cpp} in the Botan distribution. For
-brevity, most error checking has been removed.
-
-\begin{verbatim}
-   string name[3] = { "MD5", "SHA-1", "RIPEMD-160" };
-   Botan::Filter* hash[3] = {
-      new Botan::Chain(new Botan::Hash_Filter(name[0]),
-                        new Botan::Hex_Encoder),
-      new Botan::Chain(new Botan::Hash_Filter(name[1]),
-                        new Botan::Hex_Encoder),
-      new Botan::Chain(new Botan::Hash_Filter(name[2]),
-                        new Botan::Hex_Encoder) };
-
-   Botan::Pipe pipe(new Botan::Fork(hash, COUNT));
-
-   for(u32bit j = 1; argv[j] != 0; j++)
-      {
-      ifstream file(argv[j]);
-      pipe.start_msg();
-      file >> pipe;
-      pipe.end_msg();
-      file.close();
-      for(u32bit k = 0; k != 3; k++)
-         {
-         pipe.set_default_msg(3*(j-1)+k);
-         cout << name[k] << "(" << argv[j] << ") = " << pipe << endl;
-         }
-      }
-\end{verbatim}
-
-\pagebreak
-
-\subsection{Rolling Your Own}
-
-Well, now that you know how filters work in Botan, you might want to write
-your own. Lucky for you, all of the hard work is done by the \type{Filter} base
-class, leaving you to handle the details of what your filter is supposed to
-do. Remember that if you get confused about any of this, you can always look at
-the implementation of Botan's filters to see exactly how everything works.
-
-There are basically only four functions that a filter need worry about:
-
-\noindent
-\type{void} \function{write}(\type{byte} \arg{input}[], \type{u32bit}
-\arg{length}):
-
-The \function{write} function is what is called when a filter receives input
-for it to process. The filter is \emph{not} required to process it right away;
-many filters buffer their input before producing any output. A filter will
-usually have \function{write} called many times during it's lifetime.
-
-\noindent
-\type{void} \function{send}(\type{byte} \arg{output}[], \type{u32bit}
-\arg{length}):
-
-Eventually, a filter will want to produce some output to send along to the next
-filter in the pipeline. It does so by calling \function{send} with whatever it
-wants to send along to the next filter. There is also a version of
-\function{send} taking a single byte argument, as a convenience.
-
-\noindent
-\type{void} \function{start\_msg()}:
-
-This function is optional. Implement it if your \type{Filter} would like to do
-some processing or setup at the start of each message (for an example, see the
-Zlib compression module).
-
-\noindent
-\type{void} \function{end\_msg()}:
-
-Implementing the \function{end\_msg} function is optional. It is called when it
-has been requested that filters finish up their computations. Note that they
-must \emph{not} deallocate their resources; this should be done by their
-destructor. They should simply finish up with whatever computation they have
-been working on (for example, a compressing filter would flush the compressor
-and \function{send} the final block), and empty any buffers in preparation for
-processing a fresh new set of input. It is essentially the inverse of
-\function{start\_msg}.
-
-Additionally, if necessary, filters can define a constructor that takes any
-needed arguments, and a destructor to deal with deallocating memory, closing
-files, etc.
-
-There is also a \type{BufferingFilter} class (in \filename{buf\_filt.h}) which
-will take a message and split it up into an initial block which can be of any
-size (including zero), a sequence of fixed sized blocks of any non-zero size,
-and last (possibly zero-sized) final block. This might make a useful base class
-for your filters, depending on what you have in mind.
-
-\pagebreak
-
-\subsection{Filter Catalog}
-
-This section contains descriptions of every \type{Filter} included in Botan.
-Note that modules which provide \type{Filter}s are documented elsewhere --
-these \type{Filter}s are available on any installation of Botan.
-
-\subsubsection{Keyed Filters}
-
-A few sections ago, it was mentioned that \type{Pipe} can process multiple
-messages, treating each of them exactly the same. Well, that was a bit of a
-lie. There are some algorithms (in particular, block ciphers not in ECB mode,
-and all stream ciphers) that change their state as data is put through them.
-
-Naturally, you might well want to reset the keys or (in the case of block
-cipher modes) IVs used by such filters, so multiple messages can be processed
-using completely different keys, or new IVs, or new keys and IVs, or whatever.
-And in fact, even for a MAC or an ECB block cipher, you might well want to
-change the key used from message to message.
-
-Enter \type{Keyed\_Filter}. It's a base class of any filter that is keyed:
-block cipher modes, stream ciphers, MACs, whatever. It has two functions,
-\function{set\_key} and \function{set\_iv}. Calling \function{set\_key} will,
-naturally, set (or reset) the key used by the algorithm. Setting the IV only
-makes sense in certain algorithms -- a call to \function{set\_iv} on an object
-that doesn't support IVs will be ignored. You \emph{must} call
-\function{set\_key} before calling \function{set\_iv}: while not all
-\type{Keyed\_Filter} objects require this, you should assume it is required
-anytime you are using a \type{Keyed\_Filter}.
-
-Here's a example:
-
-\begin{verbatim}
-   Keyed_Filter *cast, *hmac;
-   Pipe pipe(new Base64_Decoder,
-             // Note the assignments to the cast and hmac variables
-             cast = new CBC_Decryption("CAST-128", "PKCS7", cast_key, iv),
-             new Fork(
-                0, // Read the section 'Fork' to understand this
-                new Chain(
-                   hmac = new MAC_Filter("HMAC(SHA-1)", mac_key, 12),
-                   new Base64_Encoder
-                   )
-                )
-      );
-   pipe.start_msg();
-   [use pipe for a while, decrypt some stuff, derive new keys and IVs]
-   pipe.end_msg();
-
-   cast->set_key(cast_key2);
-   cast->set_iv(iv2);
-   hmac->set_key(mac_key2);
-
-   pipe.start_msg();
-   [use pipe for some other things]
-   pipe.end_msg();
-\end{verbatim}
-
-There are some requirements to using \type{Keyed\_Filter} which you must
-follow. If you call \function{set\_key} or \function{set\_iv} on a filter which
-is owned by a \type{Pipe}, you must do so while the \type{Pipe} is
-``unlocked''. This refers to the times when no messages are being processed by
-\type{Pipe} -- either before \type{Pipe}'s \function{start\_msg} is called, or
-after \function{end\_msg} is called (and no new call to \function{start\_msg}
-has happened yet). Doing otherwise will result in undefined behavior, probably
-silently getting invalid output.
-
-And remember: if you're resetting both values, reset the key \emph{first}.
-
-\pagebreak
-
-\subsubsection{Cipher Filters}
-
-Getting ahold of a \type{Filter} implementing a cipher is very easy. Simply
-make sure you're including the header \filename{lookup.h}, and call
-\function{get\_cipher}. Generally you will pass the return value directly into
-a \type{Pipe}. There are actually a couple different functions, which do pretty
-much the same thing:
-
-\function{get\_cipher}(\type{std::string} \arg{cipher\_spec},
-                       \type