From 57789ce48e65ed83244130b077aa35a6696feab9 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 18 Sep 2008 01:03:19 +0000 Subject: Add a program that checks the X9.31 PRNG against a set of NIST test vectors --- doc/examples/rng_test.cpp | 134 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 doc/examples/rng_test.cpp (limited to 'doc') diff --git a/doc/examples/rng_test.cpp b/doc/examples/rng_test.cpp new file mode 100644 index 000000000..0a245ca9e --- /dev/null +++ b/doc/examples/rng_test.cpp @@ -0,0 +1,134 @@ +#include +#include +#include + +#include +#include +#include +#include + +using namespace Botan; + +std::vector > read_file(const std::string&); + +SecureVector decode_hex(const std::string& in) + { + SecureVector result; + + try { + Botan::Pipe pipe(new Botan::Hex_Decoder); + pipe.process_msg(in); + result = pipe.read_all(); + } + catch(std::exception& e) + { + result.destroy(); + } + return result; + } + +std::string hex_encode(const byte in[], u32bit len) + { + Botan::Pipe pipe(new Botan::Hex_Encoder); + pipe.process_msg(in, len); + return pipe.read_all_as_string(); + } + +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[], u32bit len) throw() + { + for(u32bit j = 0; j != len; j++) + out[j] = random(); + } + + std::string name() const { return "Fixed_Output_RNG"; } + + void clear() throw() {} + + void add_randomness(const byte in[], u32bit len) throw() + { + buf.insert(buf.end(), in, in + len); + } + + Fixed_Output_RNG() {} + private: + std::deque buf; + }; + +void x931_tests(std::vector > 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(cipher, new Fixed_Output_RNG); + + SecureVector x = decode_hex(input); + prng.add_entropy(x.begin(), x.size()); + + SecureVector output(result.size() / 2); + prng.randomize(output, output.size()); + + if(decode_hex(result) != output) + std::cout << "FAIL"; + else + std::cout << "PASS"; + + std::cout << " Seed " << input << " " + << "Got " << hex_encode(output, output.size()) << " " + << "Exp " << result << "\n"; + } + + } + +int main() + { + 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"); + } + + +std::vector > read_file(const std::string& fsname) + { + std::ifstream in(fsname.c_str()); + + std::vector > out; + + while(in.good()) + { + std::string line; + std::getline(in, line); + + if(line == "") + break; + + std::vector l; + boost::split(l, line, boost::is_any_of(":")); + + if(l.size() != 2) + throw std::runtime_error("Bad line " + line); + + out.push_back(std::make_pair(l[0], l[1])); + } + + return out; + } -- cgit v1.2.3