diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/tests/test_bigint.cpp | 85 | ||||
-rw-r--r-- | src/tests/test_dl_group.cpp | 26 | ||||
-rw-r--r-- | src/tests/tests.cpp | 12 |
3 files changed, 120 insertions, 3 deletions
diff --git a/src/tests/test_bigint.cpp b/src/tests/test_bigint.cpp index 096788f17..1d442a8bb 100644 --- a/src/tests/test_bigint.cpp +++ b/src/tests/test_bigint.cpp @@ -30,7 +30,9 @@ class BigInt_Unit_Tests : public Test results.push_back(test_bigint_sizes()); results.push_back(test_random_integer()); + results.push_back(test_random_prime()); results.push_back(test_encode()); + results.push_back(test_bigint_io()); return results; } @@ -80,6 +82,51 @@ class BigInt_Unit_Tests : public Test return result; } + Test::Result test_random_prime() + { + Test::Result result("BigInt prime generation"); + + result.test_throws("Invalid arg", []{ Botan::random_prime(Test::rng(), 0); }); + result.test_throws("Invalid arg", []{ Botan::random_prime(Test::rng(), 1); }); + result.test_throws("Invalid arg", []{ Botan::random_prime(Test::rng(), 2, 0); }); + result.test_throws("Invalid arg", []{ Botan::random_prime(Test::rng(), 2, 1, 1, 3); }); + result.test_throws("Invalid arg", []{ Botan::random_prime(Test::rng(), 2, 1, 0, 2); }); + + BigInt p = Botan::random_prime(Test::rng(), 2); + result.confirm("Only two 2-bit primes", p == 2 || p == 3); + + p = Botan::random_prime(Test::rng(), 3); + result.confirm("Only two 3-bit primes", p == 5 || p == 7); + + p = Botan::random_prime(Test::rng(), 4); + result.confirm("Only two 4-bit primes", p == 11 || p == 13); + + for(size_t bits = 5; bits <= 32; ++bits) + { + p = Botan::random_prime(Test::rng(), bits); + result.test_eq("Expected bit size", p.bits(), bits); + result.test_eq("P is prime", Botan::is_prime(p, Test::rng()), true); + } + + for(size_t bits = 5; bits <= 32; ++bits) + { + const BigInt last_p = p; + p = Botan::random_prime(Test::rng(), bits, last_p); + + result.test_eq("Relatively prime", Botan::gcd(last_p, p), 1); + result.test_eq("Expected bit size", p.bits(), bits); + result.test_eq("P is prime", Botan::is_prime(p, Test::rng()), true); + } + + const size_t safe_prime_bits = 65; + const BigInt safe_prime = Botan::random_safe_prime(Test::rng(), safe_prime_bits); + result.test_eq("Safe prime size", safe_prime.bits(), safe_prime_bits); + result.confirm("P is prime", Botan::is_prime(safe_prime, Test::rng())); + result.confirm("(P-1)/2 is prime", Botan::is_prime((safe_prime-1)/2, Test::rng())); + + return result; + } + Test::Result test_random_integer() { Test::Result result("BigInt::random_integer"); @@ -164,6 +211,44 @@ class BigInt_Unit_Tests : public Test return result; } + + Test::Result test_bigint_io() + { + Test::Result result("BigInt IO operators"); + + const std::map<std::string, Botan::BigInt> str_to_val = { + { "-13", -Botan::BigInt(13) }, + { "0", Botan::BigInt(0) }, + { "0x13", Botan::BigInt(0x13) }, + { "1", Botan::BigInt(1) }, + { "4294967297", Botan::BigInt(2147483648)*2 + 1 } + }; + + for(auto vec : str_to_val) + { + Botan::BigInt n; + std::istringstream iss; + + iss.str(vec.first); + iss >> n; + result.test_eq("input '" + vec.first + "'", n, vec.second); + } + + BigInt n = 33; + + std::ostringstream oss; + oss << n; + result.test_eq("output 33 dec", oss.str(), "33"); + + oss.str(""); + oss << std::hex << n; + result.test_eq("output 33 hex", oss.str(), "21"); + + result.test_throws("octal output not supported", + [&]{ oss << std::oct << n; }); + + return result; + } }; BOTAN_REGISTER_TEST("bigint_unit", BigInt_Unit_Tests); diff --git a/src/tests/test_dl_group.cpp b/src/tests/test_dl_group.cpp index 27757fdfe..bb3e3d962 100644 --- a/src/tests/test_dl_group.cpp +++ b/src/tests/test_dl_group.cpp @@ -27,7 +27,7 @@ class DL_Group_Tests : public Test results.push_back(test_dl_encoding()); results.push_back(test_dl_named(rng)); - //results.push_back(test_dl_generate(rng)); + results.push_back(test_dl_generate(rng)); return results; } @@ -70,19 +70,39 @@ class DL_Group_Tests : public Test { Test::Result result("DL_Group generate"); + result.start_timer(); + Botan::DL_Group dsa1024(rng, Botan::DL_Group::DSA_Kosherizer, 1024); result.test_eq("DSA p size", dsa1024.get_p().bits(), 1024); result.test_eq("DSA q size", dsa1024.get_q().bits(), 160); - result.test_eq("DSA g size", dsa1024.get_g().bits(), 1024); + result.test_lte("DSA g size", dsa1024.get_g().bits(), 1024); result.test_eq("DSA group verifies", dsa1024.verify_group(rng, true), true); Botan::DL_Group dh1050(rng, Botan::DL_Group::Prime_Subgroup, 1050, 175); result.test_eq("DH p size", dh1050.get_p().bits(), 1050); result.test_eq("DH q size", dh1050.get_q().bits(), 175); - result.test_eq("DH g size", dh1050.get_g().bits(), 2); + result.test_lte("DH g size", dh1050.get_g().bits(), 1050); result.test_eq("DH group verifies", dh1050.verify_group(rng, true), true); + // From FIPS 186-3 test data + const std::vector<uint8_t> seed = Botan::hex_decode("1F5DA0AF598EEADEE6E6665BF880E63D8B609BA2"); + + result.test_throws("invalid params", [&] { Botan::DL_Group invalid(rng, seed, 1024, 224); }); + result.test_throws("invalid params", [&] { Botan::DL_Group invalid(rng, seed, 3072, 224); }); + result.test_throws("invalid params", [&] { Botan::DL_Group invalid(rng, seed, 2048, 256); }); + + Botan::DL_Group dsa_from_seed(rng, seed, 1024, 160); + + result.test_eq("DSA q from seed", dsa_from_seed.get_q(), + Botan::BigInt("0xAB1A788BCE3C557A965A5BFA6908FAA665FDEB7D")); + + // Modulo just to avoid embedding entire 1024-bit P in src file + result.test_eq("DSA p from seed", dsa_from_seed.get_p() % 4294967291, 2513712339); + + result.test_eq("DSA group from seed verifies", dsa_from_seed.verify_group(rng, true), true); + result.end_timer(); + return result; } diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp index a4d81135a..6a7e6292a 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -250,6 +250,18 @@ bool Test::Result::test_lt(const std::string& what, size_t produced, size_t expe return test_success(); } +bool Test::Result::test_lte(const std::string& what, size_t produced, size_t expected) + { + if(produced > expected) + { + std::ostringstream err; + err << m_who << " " << what << " unexpected result " << produced << " > " << expected; + return test_failure(err.str()); + } + + return test_success(); + } + bool Test::Result::test_gte(const std::string& what, size_t produced, size_t expected) { if(produced < expected) |