diff options
38 files changed, 152 insertions, 2453 deletions
diff --git a/configure.py b/configure.py index 6fd730ae4..2b1a330ee 100755 --- a/configure.py +++ b/configure.py @@ -157,8 +157,6 @@ class BuildConfigurationInformation(object): self.manual_dir = os.path.join(self. doc_output_dir, 'manual') def build_doc_commands(): - yield '$(COPY) readme.txt %s' % (self.doc_output_dir) - if options.with_sphinx: yield 'sphinx-build $(SPHINX_OPTS) -b html doc %s' % ( self.manual_dir) diff --git a/doc/examples/GNUmakefile b/doc/examples/GNUmakefile deleted file mode 100644 index 49bccfd38..000000000 --- a/doc/examples/GNUmakefile +++ /dev/null @@ -1,24 +0,0 @@ - -BOTAN_CONFIG = botan-config - -CXX = g++ -CFLAGS = -O2 -ansi -std=c++11 -W -Wall -I../../build/include -LIBS = -L../.. -lbotan-1.11 - -SRCS=$(wildcard *.cpp) - -PROGS=$(patsubst %.cpp,%,$(SRCS)) - -all: $(PROGS) - -clean: - @rm -f $(PROGS) - -%: %.cpp - $(CXX) $(CFLAGS) $? $(LIBS) -o $@ - -eax_test: eax_test.cpp - $(CXX) $(CFLAGS) $? $(LIBS) -lboost_regex -o $@ - -asio_tls_server: asio_tls_server.cpp credentials.h - $(CXX) $(CFLAGS) $< $(LIBS) -lboost_thread -lboost_system -o $@ diff --git a/doc/examples/bench.cpp b/doc/examples/bench.cpp deleted file mode 100644 index 48ba5b48c..000000000 --- a/doc/examples/bench.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/benchmark.h> -#include <botan/init.h> -#include <botan/auto_rng.h> -#include <botan/libstate.h> - -using namespace Botan; - -#include <iostream> - -namespace { - -const std::string algos[] = { - "AES-128", - "AES-192", - "AES-256", - "Blowfish", - "CAST-128", - "CAST-256", - "DES", - "DESX", - "TripleDES", - "GOST", - "IDEA", - "KASUMI", - "Lion(SHA-256,Salsa20,8192)", - "Luby-Rackoff(SHA-512)", - "MARS", - "MISTY1", - "Noekeon", - "RC2", - "RC5(12)", - "RC5(16)", - "RC6", - "SAFER-SK(10)", - "SEED", - "Serpent", - "Skipjack", - "Square", - "TEA", - "Twofish", - "XTEA", - "Adler32", - "CRC32", - "GOST-34.11", - "HAS-160", - "MD2", - "MD4", - "MD5", - "RIPEMD-128", - "RIPEMD-160", - "SHA-160", - "SHA-256", - "SHA-384", - "SHA-512", - "Skein-512", - "Tiger", - "Whirlpool", - "CMAC(AES-128)", - "HMAC(SHA-1)", - "X9.19-MAC", - "", -}; - - -void benchmark_algo(const std::string& algo, - RandomNumberGenerator& rng) - { - std::chrono::milliseconds ms(1000); - Algorithm_Factory& af = global_state().algorithm_factory(); - - auto speeds = algorithm_benchmark(algo, af, rng, ms, 16); - - std::cout << algo << ":"; - - for(auto s: speeds) - std::cout << " " << s.second << " [" << s.first << "]"; - std::cout << "\n"; - } - -} - -int main(int argc, char* argv[]) - { - LibraryInitializer init; - - AutoSeeded_RNG rng; - - if(argc == 1) // no args, benchmark everything - { - for(size_t i = 0; algos[i] != ""; ++i) - benchmark_algo(algos[i], rng); - } - else - { - for(size_t i = 1; argv[i]; ++i) - benchmark_algo(argv[i], rng); - } - } diff --git a/doc/examples/benchmark.cpp b/doc/examples/benchmark.cpp deleted file mode 100644 index a11054c0c..000000000 --- a/doc/examples/benchmark.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/botan.h> -#include <botan/benchmark.h> - -#include <iostream> -#include <string> -#include <map> -#include <cstdlib> - -int main(int argc, char* argv[]) - { - if(argc <= 2) - { - std::cout << "Usage: " << argv[0] << " seconds <algo1> <algo2> ...\n"; - return 1; - } - - Botan::LibraryInitializer init; - - Botan::AutoSeeded_RNG rng; - - Botan::Algorithm_Factory& af = Botan::global_state().algorithm_factory(); - - std::chrono::milliseconds ms(static_cast<std::chrono::milliseconds::rep>(1000 * std::atof(argv[1]))); - - for(size_t i = 2; argv[i]; ++i) - { - std::string algo = argv[i]; - - auto results = algorithm_benchmark(algo, af, rng, ms, 16); - - std::cout << algo << ":\n"; - for(std::map<std::string, double>::iterator r = results.begin(); - r != results.end(); ++r) - { - std::cout << " " << r->first << ": " << r->second << " MiB/s\n"; - } - std::cout << "\n"; - } - } diff --git a/doc/examples/checksum.cpp b/doc/examples/checksum.cpp deleted file mode 100644 index dba7a7d70..000000000 --- a/doc/examples/checksum.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/botan.h> -#include <botan/filters.h> - -#include <iostream> - -using namespace Botan; - -int main(int argc, char* argv[]) - { - if(argc != 2) - { - std::cout << "Usage: " << argv[0] << " filename\n"; - return 1; - } - - Botan::LibraryInitializer init; - - Pipe pipe(new Fork( - new Chain(new Hash_Filter("CRC24"), new Hex_Encoder), - new Chain(new Hash_Filter("CRC32"), new Hex_Encoder), - new Chain(new Hash_Filter("Adler32"), new Hex_Encoder) - )); - - DataSource_Stream in(argv[1]); - - pipe.process_msg(in); - - std::cout << pipe.read_all_as_string(0) << "\n"; - std::cout << pipe.read_all_as_string(1) << "\n"; - std::cout << pipe.read_all_as_string(2) << "\n"; - } diff --git a/doc/examples/cryptobox.cpp b/doc/examples/cryptobox.cpp deleted file mode 100644 index 38d750d17..000000000 --- a/doc/examples/cryptobox.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/botan.h> -#include <botan/cryptobox.h> -#include <fstream> -#include <iostream> -#include <vector> - -using namespace Botan; - -int main(int argc, char* argv[]) - { - LibraryInitializer init; - - AutoSeeded_RNG rng; - - if(argc != 3) - { - std::cout << "Usage: cryptobox pass filename\n"; - return 1; - } - - std::string pass = argv[1]; - std::string filename = argv[2]; - - std::ifstream input(filename.c_str(), std::ios::binary); - - std::vector<byte> file_contents; - while(input.good()) - { - byte filebuf[4096] = { 0 }; - input.read((char*)filebuf, sizeof(filebuf)); - size_t got = input.gcount(); - - file_contents.insert(file_contents.end(), filebuf, filebuf+got); - } - - std::string ciphertext = CryptoBox::encrypt(&file_contents[0], - file_contents.size(), - pass, rng); - - std::cout << ciphertext; - - /* - std::cout << CryptoBox::decrypt((const byte*)&ciphertext[0], - ciphertext.length(), - pass); - */ - } diff --git a/doc/examples/decrypt.cpp b/doc/examples/decrypt.cpp deleted file mode 100644 index 42c4071c7..000000000 --- a/doc/examples/decrypt.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -/* -Decrypt files encrypted with the 'encrypt' example application. - -I'm being lazy and writing the output to stdout rather than stripping -off the ".enc" suffix and writing it there. So all diagnostics go to -stderr so there is no confusion. -*/ - -#include <fstream> -#include <iostream> -#include <string> -#include <vector> -#include <cstring> -#include <memory> - -#include <botan/botan.h> - -#if defined(BOTAN_HAS_COMPRESSOR_ZLIB) - #include <botan/zlib.h> -#endif - -using namespace Botan; - -secure_vector<byte> b64_decode(const std::string&); - -int main(int argc, char* argv[]) - { - if(argc < 2) - { - std::cout << "Usage: " << argv[0] << " [-p passphrase] file\n" - << " -p : Use this passphrase to decrypt\n"; - return 1; - } - - Botan::LibraryInitializer init; - - std::string filename, passphrase; - - for(int j = 1; argv[j] != 0; j++) - { - if(std::strcmp(argv[j], "-p") == 0) - { - if(argv[j+1]) - { - passphrase = argv[j+1]; - j++; - } - else - { - std::cout << "No argument for -p option" << std::endl; - return 1; - } - } - else - { - if(filename != "") - { - std::cout << "You can only specify one file at a time\n"; - return 1; - } - filename = argv[j]; - } - } - - if(passphrase == "") - { - std::cout << "You have to specify a passphrase!" << std::endl; - return 1; - } - - std::ifstream in(filename.c_str()); - if(!in) - { - std::cout << "ERROR: couldn't open " << filename << std::endl; - return 1; - } - - std::string algo; - - try { - std::string header, salt_str, mac_str; - std::getline(in, header); - std::getline(in, algo); - std::getline(in, salt_str); - std::getline(in, mac_str); - - if(header != "-------- ENCRYPTED FILE --------") - { - std::cout << "ERROR: File is missing the usual header" << std::endl; - return 1; - } - - const BlockCipher* cipher_proto = global_state().algorithm_factory().prototype_block_cipher(algo); - - if(!cipher_proto) - { - std::cout << "Don't know about the block cipher \"" << algo << "\"\n"; - return 1; - } - - const u32bit key_len = cipher_proto->maximum_keylength(); - const u32bit iv_len = cipher_proto->block_size(); - - std::auto_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(SHA-1)")); - - const u32bit PBKDF2_ITERATIONS = 8192; - - secure_vector<byte> salt = b64_decode(salt_str); - - SymmetricKey bc_key = pbkdf->derive_key(key_len, "BLK" + passphrase, - &salt[0], salt.size(), - PBKDF2_ITERATIONS); - - InitializationVector iv = pbkdf->derive_key(iv_len, "IVL" + passphrase, - &salt[0], salt.size(), - PBKDF2_ITERATIONS); - - SymmetricKey mac_key = pbkdf->derive_key(16, "MAC" + passphrase, - &salt[0], salt.size(), - PBKDF2_ITERATIONS); - - Pipe pipe(new Base64_Decoder, - get_cipher(algo + "/CBC", bc_key, iv, DECRYPTION), -#ifdef BOTAN_HAS_COMPRESSOR_ZLIB - new Zlib_Decompression, -#endif - new Fork( - 0, - new Chain(new MAC_Filter("HMAC(SHA-1)", mac_key), - new Base64_Encoder) - ) - ); - - pipe.start_msg(); - in >> pipe; - pipe.end_msg(); - - std::string our_mac = pipe.read_all_as_string(1); - if(our_mac != mac_str) - std::cout << "WARNING: MAC in message failed to verify\n"; - - std::cout << pipe.read_all_as_string(0); - } - catch(Algorithm_Not_Found) - { - std::cout << "Don't know about the block cipher \"" << algo << "\"\n"; - return 1; - } - catch(Decoding_Error) - { - std::cout << "Bad passphrase or corrupt file\n"; - return 1; - } - catch(std::exception& e) - { - std::cout << "Exception caught: " << e.what() << std::endl; - return 1; - } - return 0; - } - -secure_vector<byte> b64_decode(const std::string& in) - { - Pipe pipe(new Base64_Decoder); - pipe.process_msg(in); - return pipe.read_all(); - } diff --git a/doc/examples/dh.cpp b/doc/examples/dh.cpp deleted file mode 100644 index d62d49f65..000000000 --- a/doc/examples/dh.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include <botan/botan.h> -#include <botan/dh.h> -#include <botan/pubkey.h> -using namespace Botan; - -#include <iostream> -#include <memory> - -int main() - { - try - { - LibraryInitializer init; - - AutoSeeded_RNG rng; - - // Alice and Bob agree on a DH domain to use - DL_Group shared_domain("modp/ietf/2048"); - - // Alice creates a DH key - DH_PrivateKey private_a(rng, shared_domain); - - // Bob creates a key with a matching group - DH_PrivateKey private_b(rng, shared_domain); - - // Alice sends to Bob her public key and a session parameter - std::vector<byte> public_a = private_a.public_value(); - const std::string session_param = - "Alice and Bob's shared session parameter"; - - // Bob sends his public key to Alice - std::vector<byte> public_b = private_b.public_value(); - - // Now Alice performs the key agreement operation - PK_Key_Agreement ka_alice(private_a, "KDF2(SHA-256)"); - SymmetricKey alice_key = ka_alice.derive_key(32, public_b, session_param); - - // Bob does the same: - PK_Key_Agreement ka_bob(private_b, "KDF2(SHA-256)"); - SymmetricKey bob_key = ka_bob.derive_key(32, public_a, session_param); - - if(alice_key == bob_key) - { - std::cout << "The two keys matched, everything worked\n"; - std::cout << "The shared key was: " << alice_key.as_string() << "\n"; - } - else - { - std::cout << "The two keys didn't match! Hmmm...\n"; - std::cout << "Alice's key was: " << alice_key.as_string() << "\n"; - std::cout << "Bob's key was: " << bob_key.as_string() << "\n"; - } - - // Now use the shared key for encryption or MACing or whatever - } - catch(std::exception& e) - { - std::cout << e.what() << std::endl; - return 1; - } - return 0; - } diff --git a/doc/examples/dsa_kgen.cpp b/doc/examples/dsa_kgen.cpp deleted file mode 100644 index f68b20834..000000000 --- a/doc/examples/dsa_kgen.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include <iostream> -#include <fstream> -#include <string> -#include <botan/botan.h> -#include <botan/dsa.h> -#include <botan/rng.h> -using namespace Botan; - -#include <memory> - -int main(int argc, char* argv[]) - { - try - { - if(argc != 1 && argc != 2) - { - std::cout << "Usage: " << argv[0] << " [passphrase]" << std::endl; - return 1; - } - - std::ofstream priv("dsapriv.pem"); - std::ofstream pub("dsapub.pem"); - if(!priv || !pub) - { - std::cout << "Couldn't write output files" << std::endl; - return 1; - } - - Botan::LibraryInitializer init; - - AutoSeeded_RNG rng; - - //DL_Group group(rng, DL_Group::DSA_Kosherizer, 2048, 256); - DL_Group group("dsa/jce/1024"); - - DSA_PrivateKey key(rng, group); - - pub << X509::PEM_encode(key); - if(argc == 1) - priv << PKCS8::PEM_encode(key); - else - priv << PKCS8::PEM_encode(key, rng, argv[1]); - } - catch(std::exception& e) - { - std::cout << "Exception caught: " << e.what() << std::endl; - } - return 0; - } diff --git a/doc/examples/ecdsa.cpp b/doc/examples/ecdsa.cpp deleted file mode 100644 index b0a66a888..000000000 --- a/doc/examples/ecdsa.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/botan.h> -#include <botan/ecdsa.h> -#include <botan/pubkey.h> - -#include <memory> -#include <iostream> - -using namespace Botan; - -int main() - { - Botan::LibraryInitializer init; - - try - { - AutoSeeded_RNG rng; - - EC_Domain_Params params("secp160r1"); - - ECDSA_PrivateKey ecdsa(rng, params); - - ECDSA_PublicKey ecdsa_pub = ecdsa; - - /* - std::cout << params.get_curve().get_p() << "\n"; - std::cout << params.get_order() << "\n"; - std::cout << X509::PEM_encode(ecdsa); - std::cout << PKCS8::PEM_encode(ecdsa); - */ - - PK_Signer signer(ecdsa, "EMSA1(SHA-256)"); - - const char* message = "Hello World"; - - signer.update((const byte*)message, strlen(message)); - - std::vector<byte> sig = signer.signature(rng); - - std::cout << sig.size() << "\n"; - - PK_Verifier verifier(ecdsa_pub, "EMSA1(SHA-256)"); - - verifier.update((const byte*)message, strlen(message)); - - bool ok = verifier.check_signature(sig); - if(ok) - std::cout << "Signature valid\n"; - else - std::cout << "Bad signature\n"; - } - catch(std::exception& e) - { - std::cout << e.what() << "\n"; - } - } diff --git a/doc/examples/encrypt.cpp b/doc/examples/encrypt.cpp deleted file mode 100644 index 158806936..000000000 --- a/doc/examples/encrypt.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -/* -Encrypt a file using a block cipher in CBC mode. Compresses the plaintext -with Zlib, MACs with HMAC(SHA-1). Stores the block cipher used in the file, -so you don't have to specify it when decrypting. - -What a real application would do (and what this example should do), is test for -the presence of the Zlib module, and use it only if it's available. Then add -some marker to the stream so the other side knows whether or not the plaintext -was compressed. Bonus points for supporting multiple compression schemes. - -Another flaw is that is stores the entire ciphertext in memory, so if the file -you're encrypting is 1 Gb... you better have a lot of RAM. -*/ - -#include <fstream> -#include <iostream> -#include <string> -#include <vector> -#include <cstring> -#include <memory> - -#include <botan/botan.h> - -#if defined(BOTAN_HAS_COMPRESSOR_ZLIB) - #include <botan/zlib.h> -#endif - -using namespace Botan; - -std::string b64_encode(const secure_vector<byte>&); - -int main(int argc, char* argv[]) - { - if(argc < 2) - { - std::cout << "Usage: " << argv[0] << " [-c algo] -p passphrase file\n" - " -p : Use this passphrase to encrypt\n" - " -c : Encrypt with block cipher 'algo' (default 3DES)\n"; - return 1; - } - - Botan::LibraryInitializer init; - - std::string algo = "TripleDES"; - std::string filename, passphrase; - - // Holy hell, argument processing is a PITA - for(int j = 1; argv[j] != 0; j++) - { - if(std::strcmp(argv[j], "-c") == 0) - { - if(argv[j+1]) - { - algo = argv[j+1]; - j++; - } - else - { - std::cout << "No argument for -c option" << std::endl; - return 1; - } - } - else if(std::strcmp(argv[j], "-p") == 0) - { - if(argv[j+1]) - { - passphrase = argv[j+1]; - j++; - } - else - { - std::cout << "No argument for -p option" << std::endl; - return 1; - } - } - else - { - if(filename != "") - { - std::cout << "You can only specify one file at a time\n"; - return 1; - } - filename = argv[j]; - } - } - - if(passphrase == "") - { - std::cout << "You have to specify a passphrase!" << std::endl; - return 1; - } - - std::ifstream in(filename.c_str(), std::ios::binary); - if(!in) - { - std::cout << "ERROR: couldn't open " << filename << std::endl; - return 1; - } - - std::string outfile = filename + ".enc"; - std::ofstream out(outfile.c_str()); - if(!out) - { - std::cout << "ERROR: couldn't open " << outfile << std::endl; - return 1; - } - - try - { - const BlockCipher* cipher_proto = global_state().algorithm_factory().prototype_block_cipher(algo); - - if(!cipher_proto) - { - std::cout << "Don't know about the block cipher \"" << algo << "\"\n"; - return 1; - } - - const u32bit key_len = cipher_proto->maximum_keylength(); - const u32bit iv_len = cipher_proto->block_size(); - - AutoSeeded_RNG rng; - - std::auto_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(SHA-1)")); - - secure_vector<byte> salt(8); - rng.randomize(&salt[0], salt.size()); - - const u32bit PBKDF2_ITERATIONS = 8192; - - SymmetricKey bc_key = pbkdf->derive_key(key_len, "BLK" + passphrase, - &salt[0], salt.size(), - PBKDF2_ITERATIONS); - - InitializationVector iv = pbkdf->derive_key(iv_len, "IVL" + passphrase, - &salt[0], salt.size(), - PBKDF2_ITERATIONS); - - SymmetricKey mac_key = pbkdf->derive_key(16, "MAC" + passphrase, - &salt[0], salt.size(), - PBKDF2_ITERATIONS); - - // Just to be all fancy we even write a (simple) header. - out << "-------- ENCRYPTED FILE --------" << std::endl; - out << algo << std::endl; - out << b64_encode(salt) << std::endl; - - Pipe pipe(new Fork( - new Chain(new MAC_Filter("HMAC(SHA-1)", mac_key), - new Base64_Encoder - ), - new Chain( -#ifdef BOTAN_HAS_COMPRESSOR_ZLIB - new Zlib_Compression, -#endif - get_cipher(algo + "/CBC", bc_key, iv, ENCRYPTION), - new Base64_Encoder(true) - ) - ) - ); - - pipe.start_msg(); - in >> pipe; - pipe.end_msg(); - - out << pipe.read_all_as_string(0) << std::endl; - out << pipe.read_all_as_string(1); - - } - catch(Algorithm_Not_Found) - { - std::cout << "Don't know about the block cipher \"" << algo << "\"\n"; - return 1; - } - catch(std::exception& e) - { - std::cout << "Exception caught: " << e.what() << std::endl; - return 1; - } - return 0; - } - -std::string b64_encode(const secure_vector<byte>& in) - { - Pipe pipe(new Base64_Encoder); - pipe.process_msg(in); - return pipe.read_all_as_string(); - } diff --git a/doc/examples/encrypt2.cpp b/doc/examples/encrypt2.cpp deleted file mode 100644 index c6c735af9..000000000 --- a/doc/examples/encrypt2.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/botan.h> -#include <botan/pbkdf2.h> -#include <botan/hmac.h> -#include <botan/sha160.h> - -#include <fstream> - -using namespace Botan; - -int main() - { - Botan::LibraryInitializer init; - - AutoSeeded_RNG rng; - - std::string passphrase = "secret"; - - std::ifstream infile("readme.txt"); - std::ofstream outfile("readme.txt.enc"); - - PKCS5_PBKDF2 pbkdf2(new HMAC(new SHA_160)); - - const u32bit PBKDF2_ITERATIONS = 8192; - - secure_vector<byte> salt(8); - rng.randomize(&salt[0], salt.size()); - - secure_vector<byte> master_key = pbkdf2.derive_key(48, passphrase, - &salt[0], salt.size(), - PBKDF2_ITERATIONS).bits_of(); - - KDF* kdf = get_kdf("KDF2(SHA-1)"); - - SymmetricKey key = kdf->derive_key(20, master_key, "cipher key"); - - SymmetricKey mac_key = kdf->derive_key(20, master_key, "hmac key"); - - InitializationVector iv = kdf->derive_key(8, master_key, "cipher iv"); - - Pipe pipe(new Fork( - new Chain( - get_cipher("Blowfish/CBC/PKCS7", key, iv, ENCRYPTION), - new Base64_Encoder, - new DataSink_Stream(outfile) - ), - new Chain( - new MAC_Filter("HMAC(SHA-1)", mac_key), - new Hex_Encoder) - ) - ); - - outfile.write((const char*)&salt[0], salt.size()); - - pipe.start_msg(); - infile >> pipe; - pipe.end_msg(); - - secure_vector<byte> hmac = pipe.read_all(1); - outfile.write((const char*)&hmac[0], hmac.size()); - } diff --git a/doc/examples/gen_certs.cpp b/doc/examples/gen_certs.cpp deleted file mode 100644 index 14ae5a0a9..000000000 --- a/doc/examples/gen_certs.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -/* -* Generate a root CA plus httpd, dovecot, and postfix certs/keys -* -*/ - -#include <botan/botan.h> -#include <botan/rsa.h> -#include <botan/x509self.h> -#include <botan/x509_ca.h> -#include <chrono> - -using namespace Botan; - -#include <iostream> -#include <fstream> - -namespace { - -void fill_commoninfo(X509_Cert_Options& opts) - { - opts.country = "US"; - opts.organization = "randombit.net"; - opts.email = "[email protected]"; - opts.locality = "Vermont"; - } - -X509_Certificate make_ca_cert(RandomNumberGenerator& rng, - const Private_Key& priv_key, - const X509_Time& now, - const X509_Time& later) - { - X509_Cert_Options opts; - fill_commoninfo(opts); - opts.common_name = "randombit.net CA"; - opts.start = now; - opts.end = later; - opts.CA_key(); - - return X509::create_self_signed_cert(opts, priv_key, "SHA-256", rng); - } - -PKCS10_Request make_server_cert_req(const Private_Key& key, - const std::string& hostname, - RandomNumberGenerator& rng) - { - X509_Cert_Options opts; - opts.common_name = hostname; - fill_commoninfo(opts); - - opts.add_ex_constraint("PKIX.ServerAuth"); - - return X509::create_cert_req(opts, key, "SHA-1", rng); - } - -void save_pair(const std::string& name, - const std::string& password, - const X509_Certificate& cert, - const Private_Key& key, - RandomNumberGenerator& rng) - { - std::string cert_fsname = name + "_cert.pem"; - std::string key_fsname = name + "_key.pem"; - - std::ofstream cert_out(cert_fsname.c_str()); - cert_out << cert.PEM_encode() << "\n"; - cert_out.close(); - - std::ofstream key_out(key_fsname.c_str()); - if(password != "") - key_out << PKCS8::PEM_encode(key, rng, password); - else - key_out << PKCS8::PEM_encode(key); - key_out.close(); - } - -} - -typedef std::chrono::duration<int, std::ratio<31556926>> years; - -int main() - { - auto current_time = std::chrono::system_clock::now(); - - X509_Time now = X509_Time(current_time); - X509_Time later = X509_Time(current_time + years(4)); - - LibraryInitializer init; - - AutoSeeded_RNG rng; - - RSA_PrivateKey ca_key(rng, 2048); - - X509_Certificate ca_cert = make_ca_cert(rng, ca_key, now, later); - - const std::string ca_password = "sekrit"; - - save_pair("ca", ca_password, ca_cert, ca_key, rng); - - X509_CA ca(ca_cert, ca_key, "SHA-256"); - - RSA_PrivateKey httpd_key(rng, 1536); - X509_Certificate httpd_cert = ca.sign_request( - make_server_cert_req(httpd_key, "www.randombit.net", rng), - rng, now, later); - - save_pair("httpd", "", httpd_cert, httpd_key, rng); - - RSA_PrivateKey bugzilla_key(rng, 1536); - X509_Certificate bugzilla_cert = ca.sign_request( - make_server_cert_req(bugzilla_key, "bugs.randombit.net", rng), - rng, now, later); - - save_pair("bugzilla", "", bugzilla_cert, bugzilla_key, rng); - - RSA_PrivateKey postfix_key(rng, 1536); - X509_Certificate postfix_cert = ca.sign_request( - make_server_cert_req(postfix_key, "mail.randombit.net", rng), - rng, now, later); - - save_pair("postfix", "", postfix_cert, postfix_key, rng); - - RSA_PrivateKey dovecot_key(rng, 1536); - X509_Certificate dovecot_cert = ca.sign_request( - make_server_cert_req(dovecot_key, "imap.randombit.net", rng), - rng, now, later); - - save_pair("dovecot", "", dovecot_cert, dovecot_key, rng); - } diff --git a/doc/examples/hash_fd.cpp b/doc/examples/hash_fd.cpp deleted file mode 100644 index 32acdbec3..000000000 --- a/doc/examples/hash_fd.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -/* -This is just like the normal hash application, but uses the Unix I/O -system calls instead of C++ iostreams. Previously, this version was -much faster and smaller, but GCC 3.1's libstdc++ seems to have been -improved enough that the difference is now fairly minimal. - -Nicely enough, doing the change required changing only about 3 lines -of code. -*/ - -#include <iostream> -#include <botan/botan.h> - -#if !defined(BOTAN_HAS_PIPE_UNIXFD_IO) - #error "You didn't compile the pipe_unixfd module into Botan" -#endif - -#include <fcntl.h> -#include <unistd.h> - -int main(int argc, char* argv[]) - { - if(argc < 3) - { - std::cout << "Usage: " << argv[0] << " digest <filenames>" << std::endl; - return 1; - } - - Botan::LibraryInitializer init; - - try - { - Botan::Pipe pipe(new Botan::Hash_Filter(argv[1]), - new Botan::Hex_Encoder); - - int skipped = 0; - for(int j = 2; argv[j] != 0; j++) - { - int file = open(argv[j], O_RDONLY); - if(file == -1) - { - std::cout << "ERROR: could not open " << argv[j] << std::endl; - skipped++; - continue; - } - pipe.start_msg(); - file >> pipe; - pipe.end_msg(); - close(file); - pipe.set_default_msg(j-2-skipped); - std::cout << pipe << " " << argv[j] << std::endl; - } - } - catch(Botan::Algorithm_Not_Found) - { - std::cout << "Don't know about the hash function \"" << argv[1] << "\"" - << std::endl; - } - catch(std::exception& e) - { - std::cout << "Exception caught: " << e.what() << std::endl; - } - return 0; - } diff --git a/doc/examples/hash_quickly.cpp b/doc/examples/hash_quickly.cpp deleted file mode 100644 index 87937efff..000000000 --- a/doc/examples/hash_quickly.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -/* -Try to find the fastest SHA-1 implementation and use it to hash -files. In most programs this isn't worth the bother and -overhead. However with large amount of input, it is worth it. On tests -on a Core2 system with the SHA-1 SSE2 code enabled, over a few hundred -Mb or so the overhead paid for itself. - -Of course you could also just do this once and save it as an -application config, which is probably the smart thing to do. -*/ - -#include <botan/botan.h> -#include <botan/benchmark.h> -#include <botan/filters.h> - -#include <iostream> -#include <fstream> -#include <string> -#include <map> -#include <cstdlib> - -namespace { - -void set_fastest_implementation(const std::string& algo, - Botan::RandomNumberGenerator& rng, - std::chrono::milliseconds ms = std::chrono::milliseconds(30)) - { - Botan::Algorithm_Factory& af = Botan::global_state().algorithm_factory(); - - std::map<std::string, double> results = - Botan::algorithm_benchmark(algo, af, rng, ms, 16); - - std::string fastest_provider = ""; - double best_res = 0; - - for(std::map<std::string, double>::iterator r = results.begin(); - r != results.end(); ++r) - { - std::cout << r->first << " @ " << r->second << " MiB/sec\n"; - - if(fastest_provider == "" || r->second > best_res) - { - fastest_provider = r->first; - best_res = r->second; - } - } - - std::cout << "Using " << fastest_provider << "\n"; - - af.set_preferred_provider(algo, fastest_provider); - } - -} - -int main(int argc, char* argv[]) - { - if(argc <= 1) - { - std::cout << "Usage: " << argv[0] << " <file> <file> ...\n"; - return 1; - } - - Botan::LibraryInitializer init; - Botan::AutoSeeded_RNG rng; - - const std::string hash = "SHA-1"; - - set_fastest_implementation(hash, rng); - - // Here we intentionally use the 'old style' lookup interface - // which will also respect the provider settings. Or can use: - // global_state().algorithm_factory().make_hash_function(hash) - Botan::Pipe pipe( - new Botan::Hash_Filter(Botan::get_hash(hash)), - new Botan::Hex_Encoder - ); - - for(size_t i = 1; argv[i]; ++i) - { - std::ifstream in(argv[i], std::ios::binary); - if(!in) - continue; - - pipe.start_msg(); - in >> pipe; - pipe.end_msg(); - - std::cout << argv[i] << " = " - << pipe.read_all_as_string(Botan::Pipe::LAST_MESSAGE) << "\n"; - - } - } diff --git a/doc/examples/hasher.cpp b/doc/examples/hasher.cpp deleted file mode 100644 index e5c52ba55..000000000 --- a/doc/examples/hasher.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <fstream> -#include <iostream> -#include <string> -#include <botan/botan.h> - -int main(int argc, char* argv[]) - { - if(argc < 2) - { - std::cout << "Usage: " << argv[0] << " <filenames>" << std::endl; - return 1; - } - - Botan::LibraryInitializer init; - - const int COUNT = 3; - std::string name[COUNT] = { "MD5", "SHA-1", "RIPEMD-160" }; - - for(int j = 1; argv[j] != 0; j++) - { - Botan::Filter* hash[COUNT] = { - 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)); - - std::ifstream file(argv[j], std::ios::binary); - if(!file) - { - std::cout << "ERROR: could not open " << argv[j] << std::endl; - continue; - } - pipe.start_msg(); - file >> pipe; - pipe.end_msg(); - file.close(); - for(int k = 0; k != COUNT; k++) - { - pipe.set_default_msg(k); - std::cout << name[k] << "(" << argv[j] << ") = " << pipe << std::endl; - } - } - return 0; - } diff --git a/doc/examples/hasher2.cpp b/doc/examples/hasher2.cpp deleted file mode 100644 index b6303b644..000000000 --- a/doc/examples/hasher2.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* -* (C) 2001 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -/* -Identical to hasher.cpp, but uses Pipe in a different way. - -Note this tends to be much less efficient than hasher.cpp, because it -does three passes over the file. For a small file, it doesn't really -matter. But for a large file, or for something you can't re-read -easily (socket, stdin, ...) this is a bad idea. -*/ - -#include <fstream> -#include <iostream> -#include <string> -#include <botan/botan.h> - -int main(int argc, char* argv[]) - { - if(argc < 2) - { - std::cout << "Usage: " << argv[0] << " <filenames>" << std::endl; - return 1; - } - - Botan::LibraryInitializer init; - - const int COUNT = 3; - std::string name[COUNT] = { "MD5", "SHA-1", "RIPEMD-160" }; - - Botan::Pipe pipe; - - int skipped = 0; - for(int j = 1; argv[j] != 0; j++) - { - Botan::Filter* hash[COUNT] = { - new Botan::Hash_Filter(name[0]), - new Botan::Hash_Filter(name[1]), - new Botan::Hash_Filter(name[2]), - }; - - std::ifstream file(argv[j], std::ios::binary); - if(!file) - { - std::cout << "ERROR: could not open " << argv[j] << std::endl; - skipped++; - continue; - } - for(int k = 0; k != COUNT; k++) - { - pipe.reset(); - pipe.append(hash[k]); - pipe.append(new Botan::Hex_Encoder); - pipe.start_msg(); - - // trickiness: the >> op reads until EOF, but seekg won't work - // unless we're in the "good" state (which EOF is not). - file.clear(); - file.seekg(0, std::ios::beg); - file >> pipe; - pipe.end_msg(); - } - file.close(); - for(int k = 0; k != COUNT; k++) - { - std::string out = pipe.read_all_as_string(COUNT*(j-1-skipped) + k); - std::cout << name[k] << "(" << argv[j] << ") = " << out << std::endl; - } - } - - return 0; - } diff --git a/doc/examples/keywrap.cpp b/doc/examples/keywrap.cpp deleted file mode 100644 index 93cdbfb84..000000000 --- a/doc/examples/keywrap.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* -* NIST keywrap example -* (C) 2011 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/botan.h> -#include <botan/rfc3394.h> -#include <botan/hex.h> -#include <iostream> - -int main() - { - using namespace Botan; - - LibraryInitializer init; - - AutoSeeded_RNG rng; - - // The key to encrypt - SymmetricKey key(rng, 24); - - // The key encryption key - SymmetricKey kek(rng, 32); - - std::cout << "Original: " << key.as_string() << "\n"; - - Algorithm_Factory& af = global_state().algorithm_factory(); - - secure_vector<byte> enc = rfc3394_keywrap(key.bits_of(), kek, af); - - std::cout << "Encrypted: " << hex_encode(enc) << "\n"; - - secure_vector<byte> dec = rfc3394_keyunwrap(enc, kek, af); - - std::cout << "Decrypted: " << hex_encode(dec) << "\n"; - } diff --git a/doc/examples/make_prime.cpp b/doc/examples/make_prime.cpp deleted file mode 100644 index acaaac698..000000000 --- a/doc/examples/make_prime.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/numthry.h> -#include <botan/auto_rng.h> -#include <botan/botan.h> - -using namespace Botan; - -#include <set> -#include <iostream> -#include <iterator> -#include <map> - -int main() - { - Botan::LibraryInitializer init; - AutoSeeded_RNG rng; - - std::set<BigInt> primes; - - std::map<int, int> bit_count; - - int not_new = 0; - - while(primes.size() < 10000) - { - u32bit start_cnt = primes.size(); - - u32bit bits = 18; - - if(rng.next_byte() % 128 == 0) - bits -= rng.next_byte() % (bits-2); - - bit_count[bits]++; - - //std::cout << "random_prime(" << bits << ")\n"; - - BigInt p = random_prime(rng, bits); - - if(p.bits() != bits) - { - std::cout << "Asked for " << bits << " got " << p - << " " << p.bits() << " bits\n"; - return 1; - } - - primes.insert(random_prime(rng, bits)); - - if(primes.size() != start_cnt) - std::cout << primes.size() << "\n"; - else - not_new++; - - //std::cout << "miss: " << not_new << "\n"; - - if(not_new % 100000 == 0) - { - for(std::map<int, int>::iterator i = bit_count.begin(); - i != bit_count.end(); ++i) - std::cout << "bit_count[" << i->first << "] = " - << i->second << "\n"; - std::copy(primes.begin(), primes.end(), - std::ostream_iterator<BigInt>(std::cout, " ")); - } - } - - std::cout << "Generated all? primes\n"; - /* - for(u32bit j = 0; j != PRIME_TABLE_SIZE; ++j) - { - if(primes.count(PRIMES[j]) != 1) - std::cout << "Missing " << PRIMES[j] << "\n"; - } - */ - } diff --git a/doc/examples/new_engine.cpp b/doc/examples/new_engine.cpp deleted file mode 100644 index 7e51df2e2..000000000 --- a/doc/examples/new_engine.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* -* Adding an application specific engine -* (C) 2004,2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/stream_cipher.h> -#include <botan/engine.h> - -using namespace Botan; - -class XOR_Cipher : public StreamCipher - { - public: - void clear() throw() { mask.clear(); mask_pos = 0; } - - // what we want to call this cipher - std::string name() const { return "XOR"; } - - // return a new object of this type - StreamCipher* clone() const { return new XOR_Cipher; } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(1, 32); - } - - XOR_Cipher() : mask_pos(0) {} - private: - void cipher(const byte in[], byte out[], size_t length) - { - for(size_t j = 0; j != length; j++) - { - out[j] = in[j] ^ mask[mask_pos]; - mask_pos = (mask_pos + 1) % mask.size(); - } - } - - void key_schedule(const byte key[], size_t length) - { - mask.resize(length); - copy_mem(&mask[0], key, length); - } - - secure_vector<byte> mask; - u32bit mask_pos; - }; - -class Application_Engine : public Engine - { - public: - std::string provider_name() const { return "application"; } - - StreamCipher* find_stream_cipher(const SCAN_Name& request, - Algorithm_Factory&) const - { - if(request.algo_name() == "XOR") - return new XOR_Cipher; - return 0; - } - }; - -#include <botan/botan.h> -#include <iostream> -#include <string> - -int main() - { - - Botan::LibraryInitializer init; - - global_state().algorithm_factory().add_engine( - new Application_Engine); - - // a hex key value - SymmetricKey key("010203040506070809101112AAFF"); - - /* - Since stream ciphers are typically additive, the encryption and - decryption ops are the same, so this isn't terribly interesting. - - If this where a block cipher you would have to add a cipher mode and - padding method, such as "/CBC/PKCS7". - */ - Pipe enc(get_cipher("XOR", key, ENCRYPTION), new Hex_Encoder); - Pipe dec(new Hex_Decoder, get_cipher("XOR", key, DECRYPTION)); - - // I think the pigeons are actually asleep at midnight... - std::string secret = "The pigeon flys at midnight."; - - std::cout << "The secret message is '" << secret << "'" << std::endl; - - enc.process_msg(secret); - std::string cipher = enc.read_all_as_string(); - - std::cout << "The encrypted secret message is " << cipher << std::endl; - - dec.process_msg(cipher); - secret = dec.read_all_as_string(); - - std::cout << "The decrypted secret message is '" - << secret << "'" << std::endl; - - return 0; - } diff --git a/doc/examples/package.cpp b/doc/examples/package.cpp deleted file mode 100644 index 02cf52816..000000000 --- a/doc/examples/package.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/botan.h> -#include <botan/serpent.h> -#include <botan/package.h> - -#include <iostream> -#include <fstream> -#include <vector> - -using namespace Botan; - -namespace { - -std::vector<byte> slurp_file(const std::string& filename) - { - std::ifstream in(filename.c_str(), std::ios::binary); - - std::vector<byte> out; - byte buf[4096] = { 0 }; - - while(in.good()) - { - in.read((char*)buf, sizeof(buf)); - ssize_t got = in.gcount(); - - out.insert(out.end(), buf, buf+got); - } - - return out; - } - -} - -int main(int argc, char* argv[]) - { - if(argc != 2) - { - std::cout << "Usage: " << argv[0] << " filename\n"; - return 1; - } - - LibraryInitializer init; - - AutoSeeded_RNG rng; - - BlockCipher* cipher = new Serpent; - - std::vector<byte> input = slurp_file(argv[1]); - std::vector<byte> output(input.size() + cipher->block_size()); - - aont_package(rng, new Serpent, - &input[0], input.size(), - &output[0]); - - std::vector<byte> unpackage_output(output.size() - cipher->block_size()); - - aont_unpackage(new Serpent, - &output[0], output.size(), - &unpackage_output[0]); - - if(unpackage_output == input) - std::cout << "Package/unpackage worked\n"; - else - std::cout << "Something went wrong :(\n"; - } diff --git a/doc/examples/pqg_gen.cpp b/doc/examples/pqg_gen.cpp deleted file mode 100644 index c272f793e..000000000 --- a/doc/examples/pqg_gen.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <iostream> -#include <fstream> -#include <string> -#include <vector> -#include <map> -#include <memory> - -#include <botan/botan.h> -#include <botan/auto_rng.h> -#include <botan/hex.h> -#include <botan/numthry.h> -#include <botan/dl_group.h> -using namespace Botan; - -bool check(RandomNumberGenerator& rng, - std::map<std::string, std::string>); - -int main() - { - try { - Botan::LibraryInitializer init("use_engines"); - - AutoSeeded_RNG rng; - - std::ifstream in("PQGGen.rsp"); - if(!in) - throw std::runtime_error("Can't open response file"); - - std::map<std::string, std::string> inputs; - - while(in.good()) - { - std::string line; - std::getline(in, line); - - if(line == "" || line[0] == '[' || line[0] == '#') - continue; - - std::vector<std::string> name_and_val = split_on(line, '='); - - if(name_and_val.size() != 2) - throw std::runtime_error("Unexpected input: " + line); - - name_and_val[0].erase(name_and_val[0].size()-1); - name_and_val[1].erase(0, 1); - - std::string name = name_and_val[0], value = name_and_val[1]; - - inputs[name] = value; - - if(name == "H") - { - bool result = check(rng, inputs); - std::cout << "." << std::flush; - if(result == false) - { - std::cout << " Check failed\n"; - - std::map<std::string, std::string>::const_iterator i; - - for(i = inputs.begin(); i != inputs.end(); i++) - std::cout << i->first << " = " << i->second << "\n"; - - std::cout << "\n"; - } - - inputs.clear(); - } - } - } - catch(std::exception& e) - { - std::cout << e.what() << std::endl; - return 1; - } - return 0; - } - -bool check(RandomNumberGenerator& rng, - std::map<std::string, std::string> inputs) - { - BigInt p("0x"+inputs["P"]), - q("0x"+inputs["Q"]), - g("0x"+inputs["G"]), - h("0x"+inputs["H"]); - - if(h < 1 || h >= p-1) return false; - - //u32bit c = to_u32bit(inputs["c"]); - - std::vector<byte> seed = hex_decode(inputs["Seed"]); - - BigInt our_p, our_q; - - u32bit qbits = (p.bits() <= 1024) ? 160 : 256; - - Algorithm_Factory& af = global_state().algorithm_factory(); - - bool found = generate_dsa_primes(rng, af, our_p, our_q, - p.bits(), qbits, seed); - - if(!found) /* bad seed */ - return false; - - if(our_p != p) return false; - if(our_q != q) return false; - - BigInt our_g = power_mod(h, (p-1)/q, p); - - if(our_g != g) return false; - - return true; - } diff --git a/doc/examples/rng_test.cpp b/doc/examples/rng_test.cpp deleted file mode 100644 index a6ee6da78..000000000 --- a/doc/examples/rng_test.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/botan.h> -#include <botan/x931_rng.h> -#include <botan/hex.h> -#include <botan/lookup.h> - -#include <iostream> -#include <fstream> -#include <deque> -#include <stdexcept> - -using namespace Botan; - -namespace { - -class Fixed_Output_RNG : public RandomNumberGenerator - { - public: - bool is_seeded() const { return !buf.empty(); } - - byte random() - { - if(buf.empty()) - throw std::runtime_error("Out of bytes"); - - byte out = buf.front(); - buf.pop_front(); - return out; - } - - void randomize(byte out[], size_t len) throw() - { - for(size_t j = 0; j != len; j++) - out[j] = random(); - } - - std::string name() const { return "Fixed_Output_RNG"; } - - void reseed(size_t) {} - - void clear() throw() {} - - void add_entropy(const byte in[], size_t len) - { - buf.insert(buf.end(), in, in + len); - } - - void add_entropy_source(EntropySource* es) { delete es; } - - Fixed_Output_RNG() {} - private: - std::deque<byte> buf; - }; - -void x931_tests(std::vector<std::pair<std::string, std::string> > vecs, - const std::string& cipher) - { - for(size_t j = 0; j != vecs.size(); ++j) - { - const std::string result = vecs[j].first; - const std::string input = vecs[j].second; - - ANSI_X931_RNG prng(get_block_cipher(cipher), - new Fixed_Output_RNG); - - std::vector<byte> x = hex_decode(input); - prng.add_entropy(&x[0], x.size()); - - secure_vector<byte> output(result.size() / 2); - prng.randomize(&output[0], output.size()); - - if(hex_decode(result) != output) - std::cout << "FAIL"; - else - std::cout << "PASS"; - - std::cout << " Seed " << input << " " - << "Got " << hex_encode(output) << " " - << "Exp " << result << "\n"; - } - - } - -std::vector<std::pair<std::string, std::string> > -read_file(const std::string& fsname) - { - std::ifstream in(fsname.c_str()); - - std::vector<std::pair<std::string, std::string> > out; - - while(in.good()) - { - std::string line; - std::getline(in, line); - - if(line == "") - break; - - std::vector<std::string> l = split_on(line, ':'); - - if(l.size() != 2) - throw std::runtime_error("Bad line " + line); - - out.push_back(std::make_pair(l[0], l[1])); - } - - return out; - } - -} - -int main() - { - Botan::LibraryInitializer init; - - x931_tests(read_file("ANSI931_AES128VST.txt.vst"), "AES-128"); - x931_tests(read_file("ANSI931_AES192VST.txt.vst"), "AES-192"); - x931_tests(read_file("ANSI931_AES256VST.txt.vst"), "AES-256"); - x931_tests(read_file("ANSI931_TDES2VST.txt.vst"), "TripleDES"); - x931_tests(read_file("ANSI931_TDES3VST.txt.vst"), "TripleDES"); - } diff --git a/doc/examples/rsa_dec.cpp b/doc/examples/rsa_dec.cpp deleted file mode 100644 index 98768cda7..000000000 --- a/doc/examples/rsa_dec.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* -* (C) 2002-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -/* -Decrypt an encrypted RSA private key. Then use that key to decrypt a -message. This program can decrypt messages generated by rsa_enc, and uses the -same key format as that generated by rsa_kgen. -*/ - -#include <iostream> -#include <fstream> -#include <string> -#include <memory> - -#include <botan/botan.h> -#include <botan/pubkey.h> -#include <botan/rsa.h> -using namespace Botan; - -secure_vector<byte> b64_decode(const std::string&); -SymmetricKey derive_key(const std::string&, const SymmetricKey&, u32bit); - -const std::string SUFFIX = ".enc"; - -int main(int argc, char* argv[]) - { - if(argc != 4) - { - std::cout << "Usage: " << argv[0] << " keyfile messagefile passphrase" - << std::endl; - return 1; - } - - Botan::LibraryInitializer init; - - try - { - AutoSeeded_RNG rng; - - std::auto_ptr<PKCS8_PrivateKey> key( - PKCS8::load_key(std::string(argv[1]), rng, std::string(argv[3]))); - - RSA_PrivateKey* rsakey = dynamic_cast<RSA_PrivateKey*>(key.get()); - if(!rsakey) - { - std::cout << "The loaded key is not a RSA key!\n"; - return 1; - } - - std::ifstream message(argv[2]); - if(!message) - { - std::cout << "Couldn't read the message file." << std::endl; - return 1; - } - - std::string outfile(argv[2]); - outfile = outfile.replace(outfile.find(SUFFIX), SUFFIX.length(), ""); - - std::ofstream plaintext(outfile.c_str(), std::ios::binary); - if(!plaintext) - { - std::cout << "Couldn't write the plaintext to " - << outfile << std::endl; - return 1; - } - - std::string enc_masterkey_str; - std::getline(message, enc_masterkey_str); - std::string mac_str; - std::getline(message, mac_str); - - secure_vector<byte> enc_masterkey = b64_decode(enc_masterkey_str); - - PK_Decryptor_EME decryptor(*rsakey, "EME1(SHA-1)"); - - secure_vector<byte> masterkey = decryptor.decrypt(enc_masterkey); - - SymmetricKey cast_key = derive_key("CAST", masterkey, 16); - InitializationVector iv = derive_key("IV", masterkey, 8); - SymmetricKey mac_key = derive_key("MAC", masterkey, 16); - - Pipe pipe(new Base64_Decoder, - get_cipher("CAST-128/CBC/PKCS7", cast_key, iv, DECRYPTION), - new Fork( - 0, - new Chain( - new MAC_Filter("HMAC(SHA-1)", mac_key, 12), - new Base64_Encoder - ) - ) - ); - - pipe.start_msg(); - message >> pipe; - pipe.end_msg(); - - std::string our_mac = pipe.read_all_as_string(1); - - if(our_mac != mac_str) - std::cout << "WARNING: MAC in message failed to verify\n"; - - plaintext << pipe.read_all_as_string(0); - } - catch(std::exception& e) - { - std::cout << "Exception caught: " << e.what() << std::endl; - return 1; - } - return 0; - } - -secure_vector<byte> b64_decode(const std::string& in) - { - Pipe pipe(new Base64_Decoder); - pipe.process_msg(in); - return pipe.read_all(); - } - -SymmetricKey derive_key(const std::string& param, - const SymmetricKey& masterkey, - u32bit outputlength) - { - std::auto_ptr<KDF> kdf(get_kdf("KDF2(SHA-1)")); - return kdf->derive_key(outputlength, masterkey.bits_of(), param); - } diff --git a/doc/examples/rsa_enc.cpp b/doc/examples/rsa_enc.cpp deleted file mode 100644 index b8e5d874b..000000000 --- a/doc/examples/rsa_enc.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* -* (C) 2002 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -/* - Grab an RSA public key from the file given as an argument, grab a message - from another file, and encrypt the message. - - Algorithms used: - RSA with EME1(SHA-1) padding to encrypt the master key - CAST-128 in CBC mode with PKCS#7 padding to encrypt the message. - HMAC with SHA-1 is used to authenticate the message - - The keys+IV used are derived from the master key (the thing that's encrypted - with RSA) using KDF2(SHA-1). The 3 outputs of KDF2 are parameterized by P, - where P is "CAST", "IV" or "MAC", in order to make each key/IV unique. - - The format is: - 1) First line is the master key, encrypted with the recipients public key - using EME1(SHA-1), and then base64 encoded. - 2) Second line is the first 96 bits (12 bytes) of the HMAC(SHA-1) of - the _plaintext_ - 3) Following lines are base64 encoded ciphertext (CAST-128 as described), - each broken after ~72 characters. -*/ - -#include <iostream> -#include <fstream> -#include <string> -#include <memory> - -#include <botan/botan.h> -#include <botan/pubkey.h> -#include <botan/rsa.h> -#include <botan/base64.h> - -using namespace Botan; - -SymmetricKey derive_key(const std::string&, const SymmetricKey&, u32bit); - -int main(int argc, char* argv[]) - { - if(argc != 3) - { - std::cout << "Usage: " << argv[0] << " keyfile messagefile" << std::endl; - return 1; - } - - std::ifstream message(argv[2], std::ios::binary); - if(!message) - { - std::cout << "Couldn't read the message file." << std::endl; - return 1; - } - - Botan::LibraryInitializer init; - - std::string output_name(argv[2]); - output_name += ".enc"; - std::ofstream ciphertext(output_name.c_str()); - if(!ciphertext) - { - std::cout << "Couldn't write the ciphertext to " << output_name - << std::endl; - return 1; - } - - try { - std::auto_ptr<X509_PublicKey> key(X509::load_key(argv[1])); - RSA_PublicKey* rsakey = dynamic_cast<RSA_PublicKey*>(key.get()); - if(!rsakey) - { - std::cout << "The loaded key is not a RSA key!\n"; - return 1; - } - - AutoSeeded_RNG rng; - - PK_Encryptor_EME encryptor(*rsakey, "EME1(SHA-1)"); - - /* Generate the master key (the other keys are derived from this) - - Basically, make the key as large as can be encrypted by this key, up - to a limit of 256 bits. For 512 bit keys, the master key will be >160 - bits. A >600 bit key will use the full 256 bit master key. - - In theory, this is not enough, because we derive 16+16+8=40 bytes of - secrets (if you include the IV) using the master key, so they are not - statistically indepedent. Practically speaking I don't think this is - a problem. - */ - SymmetricKey masterkey(rng, - std::min<size_t>(32, - encryptor.maximum_input_size())); - - SymmetricKey cast_key = derive_key("CAST", masterkey, 16); - SymmetricKey mac_key = derive_key("MAC", masterkey, 16); - SymmetricKey iv = derive_key("IV", masterkey, 8); - - std::vector<byte> encrypted_key = - encryptor.encrypt(masterkey.bits_of(), rng); - - ciphertext << base64_encode(encrypted_key) << std::endl; - - Pipe pipe(new Fork( - new Chain( - get_cipher("CAST-128/CBC/PKCS7", cast_key, iv, - ENCRYPTION), - new Base64_Encoder(true) // true == do linebreaking - ), - new Chain( - new MAC_Filter("HMAC(SHA-1)", mac_key, 12), - new Base64_Encoder - ) - ) - ); - - pipe.start_msg(); - message >> pipe; - pipe.end_msg(); - - /* Write the MAC as the second line. That way we can pull it off right - from the start, and feed the rest of the file right into a pipe on the - decrypting end. - */ - - ciphertext << pipe.read_all_as_string(1) << std::endl; - ciphertext << pipe.read_all_as_string(0); - } - catch(std::exception& e) - { - std::cout << "Exception: " << e.what() << std::endl; - } - return 0; - } - -SymmetricKey derive_key(const std::string& param, - const SymmetricKey& masterkey, - u32bit outputlength) - { - std::auto_ptr<KDF> kdf(get_kdf("KDF2(SHA-1)")); - return kdf->derive_key(outputlength, masterkey.bits_of(), param); - } diff --git a/doc/examples/rsa_manykey.cpp b/doc/examples/rsa_manykey.cpp deleted file mode 100644 index c282e7882..000000000 --- a/doc/examples/rsa_manykey.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -/* -Generate a whole sequence of keys (for benchmarking) -*/ - -#include <iostream> -#include <fstream> -#include <string> -#include <cstdlib> -#include <memory> - -#include <botan/botan.h> -#include <botan/rsa.h> -#include <botan/parsing.h> -using namespace Botan; - -int main() - { - Botan::LibraryInitializer init; - - AutoSeeded_RNG rng; - - for(u32bit j = 512; j <= 8192; j += 256) - { - std::cout << j << "..."; - - RSA_PrivateKey key(rng, j); - - std::ofstream priv(("rsa/" + std::to_string(j) + ".pem").c_str()); - priv << PKCS8::PEM_encode(key); - priv.close(); - - std::cout << " done" << std::endl; - } - - return 0; - } diff --git a/doc/examples/sig_gen.cpp b/doc/examples/sig_gen.cpp deleted file mode 100644 index cf273216a..000000000 --- a/doc/examples/sig_gen.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <iostream> -#include <fstream> -#include <string> -#include <vector> -#include <map> -#include <memory> - -#include <botan/botan.h> -#include <botan/dsa.h> -#include <botan/pubkey.h> -using namespace Botan; - -bool check(std::map<std::string, std::string>); - -int main() - { - try { - Botan::LibraryInitializer init; - - std::ifstream in("SigGen.rsp"); - if(!in) - throw Exception("Can't open response file"); - - std::map<std::string, std::string> inputs; - - while(in.good()) - { - std::string line; - std::getline(in, line); - - if(line == "" || line[0] == '[' || line[0] == '#') - continue; - - std::vector<std::string> name_and_val = split_on(line, '='); - - if(name_and_val.size() != 2) - throw Decoding_Error("Unexpected input: " + line); - - name_and_val[0].erase(name_and_val[0].size()-1); - name_and_val[1].erase(0, 1); - - std::string name = name_and_val[0], value = name_and_val[1]; - - inputs[name] = value; - - if(name == "S") - { - bool result = check(inputs); - if(result == false) - { - std::cout << " Check failed\n"; - - std::map<std::string, std::string>::const_iterator i; - - for(i = inputs.begin(); i != inputs.end(); i++) - std::cout << i->first << " = " << i->second << "\n"; - } - inputs["Msg"] = inputs["R"] = inputs["S"] = ""; - } - } - } - catch(std::exception& e) - { - std::cout << e.what() << std::endl; - return 1; - } - return 0; - } - -bool check(std::map<std::string, std::string> inputs) - { - BigInt p("0x"+inputs["P"]), - q("0x"+inputs["Q"]), - g("0x"+inputs["G"]), - y("0x"+inputs["Y"]); - - DSA_PublicKey key(DL_Group(p, q, g), y); - - Pipe pipe(new Hex_Decoder); - - pipe.process_msg(inputs["Msg"]); - pipe.start_msg(); - pipe.write(inputs["R"]); - pipe.write(inputs["S"] ); - pipe.end_msg(); - - PK_Verifier verifier(key, "EMSA1(SHA-1)"); - - return verifier.verify_message(pipe.read_all(0), pipe.read_all(1)); - } diff --git a/doc/examples/stack.cpp b/doc/examples/stack.cpp deleted file mode 100644 index 0c00ed183..000000000 --- a/doc/examples/stack.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* -* (C) 2002 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -/* -An Botan example application showing how to use the pop and prepend -functions of Pipe. Based on the md5 example. It's output should always -be identical to such. -*/ - -#include <iostream> -#include <fstream> -#include <botan/botan.h> - -int main(int argc, char* argv[]) - { - if(argc < 2) - { - std::cout << "Usage: " << argv[0] << " <filenames>" << std::endl; - return 1; - } - - Botan::LibraryInitializer init; - - // this is a pretty vacuous example, but it's useful as a test - Botan::Pipe pipe; - - // CPS == Current Pipe Status, ie what Filters are set up - - pipe.prepend(new Botan::Hash_Filter("MD5")); - // CPS: MD5 - - pipe.prepend(new Botan::Hash_Filter("RIPEMD-160")); - // CPS: RIPEMD-160 | MD5 - - pipe.prepend(new Botan::Chain( - new Botan::Hash_Filter("RIPEMD-160"), - new Botan::Hash_Filter("RIPEMD-160"))); - // CPS: (RIPEMD-160 | RIPEMD-160) | RIPEMD-160 | MD5 - - pipe.pop(); // will pop everything inside the Chain as well as Chain itself - // CPS: RIPEMD-160 | MD5 - - pipe.pop(); // will get rid of the RIPEMD-160 Hash_Filter - // CPS: MD5 - - pipe.prepend(new Botan::Hash_Filter("SHA-1")); - // CPS: SHA-1 | MD5 - - pipe.append(new Botan::Hex_Encoder); - // CPS: SHA-1 | MD5 | Hex_Encoder - - pipe.prepend(new Botan::Hash_Filter("SHA-1")); - // CPS: SHA-1 | SHA-1 | MD5 | Hex_Encoder - - pipe.pop(); // Get rid of the Hash_Filter(SHA-1) - pipe.pop(); // Get rid of the other Hash_Filter(SHA-1) - // CPS: MD5 | Hex_Encoder - // The Hex_Encoder is safe because it is at the end of the Pipe, - // and pop() pulls off the Filter that is at the start. - - pipe.prepend(new Botan::Hash_Filter("RIPEMD-160")); - // CPS: RIPEMD-160 | MD5 | Hex_Encoder - - pipe.pop(); // Get rid of that last prepended Hash_Filter(RIPEMD-160) - // CPS: MD5 | Hex_Encoder - - int skipped = 0; - for(int j = 1; argv[j] != 0; j++) - { - std::ifstream file(argv[j], std::ios::binary); - if(!file) - { - std::cout << "ERROR: could not open " << argv[j] << std::endl; - skipped++; - continue; - } - pipe.start_msg(); - file >> pipe; - pipe.end_msg(); - file.close(); - pipe.set_default_msg(j-1-skipped); - std::cout << pipe << " " << argv[j] << std::endl; - } - return 0; - } diff --git a/doc/release_process.rst b/doc/release_process.rst index 88daff0c6..953b7dda2 100644 --- a/doc/release_process.rst +++ b/doc/release_process.rst @@ -11,9 +11,9 @@ Pre Release Checks Confirm that the release notes under ``doc/relnotes`` are accurate and complete and that the version number in ``botan_version.py`` is -correct. Update the release date in the release notes and in -``readme.txt``, and change the entry for the appropriate branch in -``doc/download.rst`` to point to the new release. +correct. Update the release date in the release notes and change the +entry for the appropriate branch in ``doc/download.rst`` to point to +the new release. Check in these changes (alone, with no other modifications) with a checkin message along the lines of "Update for X.Y.Z release", then @@ -84,12 +84,9 @@ new release is available. Post Release Process ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Immediately after the new release is created, update -``botan_version.py`` and ``readme.txt`` once again, incrementing the -version number and removing the release dates in ``readme.txt``. - -Add a new release notes file for the next release, including a new -entry in ``relnotes/index.rst``. +Immediately after the new release is created, increment the version +number in ``botan_version.py`` and add a new release notes file for +the next release, including a new entry in ``relnotes/index.rst``. Use "Not Yet Released" as the placeholder for the release date. Use checkin message "Bump for X.Y.Z". diff --git a/readme.txt b/readme.txt deleted file mode 100644 index 7123956e2..000000000 --- a/readme.txt +++ /dev/null @@ -1,11 +0,0 @@ - -Botan is a C++ class library for performing a wide variety of -cryptographic operations. It is released under the 2 clause BSD -license; see doc/license.rst for the specifics. You can file bugs in -Bugzilla (http://bugs.randombit.net/) or by sending a report to the -botan-devel mailing list. More information about the mailing list is -at http://lists.randombit.net/mailman/listinfo/botan-devel/ - -You can find documentation online at http://botan.randombit.net/ as -well as in the doc directory in the distribution. Several examples can -be found in doc/examples as well. diff --git a/src/build-data/innosetup.in b/src/build-data/innosetup.in index a0928ca40..e9109e65f 100644 --- a/src/build-data/innosetup.in +++ b/src/build-data/innosetup.in @@ -44,8 +44,7 @@ Source: "..\botan.dll.manifest"; DestDir: "{app}"; Components: dll; Flags: skipi Source: "include\botan\*"; DestDir: "{app}\include\botan"; Components: includes; AfterInstall: ConvertLineEndings -Source: "..\readme.txt"; DestDir: "{app}\doc"; Components: docs; AfterInstall: ConvertLineEndings -Source: "..\doc\*.rst"; DestDir: "{app}\doc"; Excludes: "license.txt"; Components: docs; AfterInstall: ConvertLineEndings +Source: "..\doc\*.rst"; DestDir: "{app}\doc"; Excludes: "license.rst"; Components: docs; AfterInstall: ConvertLineEndings Source: "..\doc\examples\*.cpp"; DestDir: "{app}\doc\examples"; Components: docs; AfterInstall: ConvertLineEndings diff --git a/doc/examples/python/cipher.py b/src/scripts/examples/cipher.py index 1be2759ae..1be2759ae 100755 --- a/doc/examples/python/cipher.py +++ b/src/scripts/examples/cipher.py diff --git a/doc/examples/python/cryptobox.py b/src/scripts/examples/cryptobox.py index f76ed6bc3..f76ed6bc3 100755 --- a/doc/examples/python/cryptobox.py +++ b/src/scripts/examples/cryptobox.py diff --git a/doc/examples/python/nisttest.py b/src/scripts/examples/nisttest.py index 1260b1226..1260b1226 100755 --- a/doc/examples/python/nisttest.py +++ b/src/scripts/examples/nisttest.py diff --git a/doc/examples/python/results.vec b/src/scripts/examples/results.vec index 7a3824001..7a3824001 100644 --- a/doc/examples/python/results.vec +++ b/src/scripts/examples/results.vec diff --git a/doc/examples/python/rng_test.py b/src/scripts/examples/rng_test.py index 06c79b84e..06c79b84e 100755 --- a/doc/examples/python/rng_test.py +++ b/src/scripts/examples/rng_test.py diff --git a/doc/examples/python/rsa.py b/src/scripts/examples/rsa.py index 998b72b7b..998b72b7b 100755 --- a/doc/examples/python/rsa.py +++ b/src/scripts/examples/rsa.py diff --git a/src/tests/test_bigint.cpp b/src/tests/test_bigint.cpp index 45a20cef6..7f866d212 100644 --- a/src/tests/test_bigint.cpp +++ b/src/tests/test_bigint.cpp @@ -11,126 +11,79 @@ #include <fstream> #include <iostream> #include <cstdlib> +#include <iterator> #include <botan/auto_rng.h> #include <botan/bigint.h> #include <botan/exceptn.h> #include <botan/numthry.h> -using namespace Botan; -size_t check_add(const std::vector<std::string>&); -size_t check_sub(const std::vector<std::string>&); -size_t check_mul(const std::vector<std::string>&); -size_t check_sqr(const std::vector<std::string>&); -size_t check_div(const std::vector<std::string>&); -size_t check_mod(const std::vector<std::string>&, - Botan::RandomNumberGenerator& rng); -size_t check_shr(const std::vector<std::string>&); -size_t check_shl(const std::vector<std::string>&); +using namespace Botan; -size_t check_powmod(const std::vector<std::string>&); -size_t check_primetest(const std::vector<std::string>&, - Botan::RandomNumberGenerator&); +namespace { -size_t test_bigint() +size_t test_make_prime() { - const std::string filename = CHECKS_DIR "/mp_valid.dat"; - std::ifstream test_data(filename.c_str()); + AutoSeeded_RNG rng; - if(!test_data) - throw Botan::Stream_IO_Error("Couldn't open test file " + filename); + std::set<BigInt> primes; - size_t total_errors = 0; - size_t errors = 0, alg_count = 0; - std::string algorithm; - bool first = true; - size_t counter = 0; + std::map<int, int> bit_count; - AutoSeeded_RNG rng; + int not_new = 0; - while(!test_data.eof()) + while(primes.size() < 10000) { - if(test_data.bad() || test_data.fail()) - throw Botan::Stream_IO_Error("File I/O error reading from " + - filename); - - std::string line; - std::getline(test_data, line); + u32bit start_cnt = primes.size(); - strip(line); - if(line.size() == 0) continue; + u32bit bits = 18; - // Do line continuation - while(line[line.size()-1] == '\\' && !test_data.eof()) - { - line.replace(line.size()-1, 1, ""); - std::string nextline; - std::getline(test_data, nextline); - strip(nextline); - if(nextline.size() == 0) continue; - line += nextline; - } + if(rng.next_byte() % 128 == 0) + bits -= rng.next_byte() % (bits-2); - if(line[0] == '[' && line[line.size() - 1] == ']') - { - if(!first) - test_report("Bigint " + algorithm, alg_count, errors); + bit_count[bits]++; - algorithm = line.substr(1, line.size() - 2); + //std::cout << "random_prime(" << bits << ")\n"; - total_errors += errors; - errors = 0; - alg_count = 0; - counter = 0; + BigInt p = random_prime(rng, bits); - first = false; - continue; + if(p.bits() != bits) + { + std::cout << "Asked for " << bits << " got " << p + << " " << p.bits() << " bits\n"; + return 1; } - std::vector<std::string> substr = parse(line); - -#if DEBUG - std::cout << "Testing: " << algorithm << std::endl; -#endif + primes.insert(random_prime(rng, bits)); - size_t new_errors = 0; - if(algorithm.find("Addition") != std::string::npos) - new_errors = check_add(substr); - else if(algorithm.find("Subtraction") != std::string::npos) - new_errors = check_sub(substr); - else if(algorithm.find("Multiplication") != std::string::npos) - new_errors = check_mul(substr); - else if(algorithm.find("Square") != std::string::npos) - new_errors = check_sqr(substr); - else if(algorithm.find("Division") != std::string::npos) - new_errors = check_div(substr); - else if(algorithm.find("Modulo") != std::string::npos) - new_errors = check_mod(substr, rng); - else if(algorithm.find("LeftShift") != std::string::npos) - new_errors = check_shl(substr); - else if(algorithm.find("RightShift") != std::string::npos) - new_errors = check_shr(substr); - else if(algorithm.find("ModExp") != std::string::npos) - new_errors = check_powmod(substr); - else if(algorithm.find("PrimeTest") != std::string::npos) - new_errors = check_primetest(substr, rng); + if(primes.size() != start_cnt) + std::cout << primes.size() << "\n"; else - std::cout << "Unknown MPI test " << algorithm << std::endl; + not_new++; - counter++; - alg_count++; - errors += new_errors; + //std::cout << "miss: " << not_new << "\n"; - if(new_errors) - std::cout << "ERROR: BigInt " << algorithm << " failed test #" - << std::dec << alg_count << std::endl; + if(not_new % 100000 == 0) + { + for(std::map<int, int>::iterator i = bit_count.begin(); + i != bit_count.end(); ++i) + std::cout << "bit_count[" << i->first << "] = " + << i->second << "\n"; + std::copy(primes.begin(), primes.end(), + std::ostream_iterator<BigInt>(std::cout, " ")); + } } - return total_errors; + std::cout << "Generated all? primes\n"; + /* + for(u32bit j = 0; j != PRIME_TABLE_SIZE; ++j) + { + if(primes.count(PRIMES[j]) != 1) + std::cout << "Missing " << PRIMES[j] << "\n"; + } + */ } -namespace { - // c==expected, d==a op b, e==a op= b size_t results(std::string op, const BigInt& a, const BigInt& b, @@ -163,8 +116,6 @@ size_t results(std::string op, } } -} - size_t check_add(const std::vector<std::string>& args) { BigInt a(args[0]); @@ -355,3 +306,105 @@ size_t check_primetest(const std::vector<std::string>& args, } return 0; } + +} + +size_t test_bigint() + { + const std::string filename = CHECKS_DIR "/mp_valid.dat"; + std::ifstream test_data(filename.c_str()); + + if(!test_data) + throw Botan::Stream_IO_Error("Couldn't open test file " + filename); + + size_t total_errors = 0; + size_t errors = 0, alg_count = 0; + std::string algorithm; + bool first = true; + size_t counter = 0; + + AutoSeeded_RNG rng; + + while(!test_data.eof()) + { + if(test_data.bad() || test_data.fail()) + throw Botan::Stream_IO_Error("File I/O error reading from " + + filename); + + std::string line; + std::getline(test_data, line); + + strip(line); + if(line.size() == 0) continue; + + // Do line continuation + while(line[line.size()-1] == '\\' && !test_data.eof()) + { + line.replace(line.size()-1, 1, ""); + std::string nextline; + std::getline(test_data, nextline); + strip(nextline); + if(nextline.size() == 0) continue; + line += nextline; + } + + if(line[0] == '[' && line[line.size() - 1] == ']') + { + if(!first) + test_report("Bigint " + algorithm, alg_count, errors); + + algorithm = line.substr(1, line.size() - 2); + + total_errors += errors; + errors = 0; + alg_count = 0; + counter = 0; + + first = false; + continue; + } + + std::vector<std::string> substr = parse(line); + +#if DEBUG + std::cout << "Testing: " << algorithm << std::endl; +#endif + + size_t new_errors = 0; + if(algorithm.find("Addition") != std::string::npos) + new_errors = check_add(substr); + else if(algorithm.find("Subtraction") != std::string::npos) + new_errors = check_sub(substr); + else if(algorithm.find("Multiplication") != std::string::npos) + new_errors = check_mul(substr); + else if(algorithm.find("Square") != std::string::npos) + new_errors = check_sqr(substr); + else if(algorithm.find("Division") != std::string::npos) + new_errors = check_div(substr); + else if(algorithm.find("Modulo") != std::string::npos) + new_errors = check_mod(substr, rng); + else if(algorithm.find("LeftShift") != std::string::npos) + new_errors = check_shl(substr); + else if(algorithm.find("RightShift") != std::string::npos) + new_errors = check_shr(substr); + else if(algorithm.find("ModExp") != std::string::npos) + new_errors = check_powmod(substr); + else if(algorithm.find("PrimeTest") != std::string::npos) + new_errors = check_primetest(substr, rng); + else + std::cout << "Unknown MPI test " << algorithm << std::endl; + + counter++; + alg_count++; + errors += new_errors; + + if(new_errors) + std::cout << "ERROR: BigInt " << algorithm << " failed test #" + << std::dec << alg_count << std::endl; + } + + //total_errors += test_make_prime(); + + return total_errors; + } + |