aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatej Kenda <[email protected]>2015-11-19 16:51:27 +0100
committerMatej Kenda <[email protected]>2015-11-19 16:51:27 +0100
commitfb103b7d1fe333b3d7424a36ea2f9b90df8b49ef (patch)
tree4606a4ba9cc981cc0d975f0ec7724d060424e5e1 /src
parent94d89769739ebe05e048f217b03672fb0c336fca (diff)
parent9bff61f4c577661bf4a62a860baf190d4ea8ed6a (diff)
Merge branch 'master' of github.com:randombit/botan into fix_algo_registry_locking_windows
Diffstat (limited to 'src')
-rw-r--r--src/cmd/mce.cpp6
-rw-r--r--src/lib/cert/cvc/cvc_gen_cert.h2
-rw-r--r--src/lib/cert/x509/x509path.cpp2
-rw-r--r--src/lib/cert/x509/x509path.h3
-rw-r--r--src/lib/compression/bzip2/bzip2.h2
-rw-r--r--src/lib/compression/lzma/lzma.h2
-rw-r--r--src/lib/ffi/ffi.cpp2
-rw-r--r--src/lib/ffi/ffi.h2
-rw-r--r--src/lib/hash/sha2_64/sha2_64.h2
-rw-r--r--src/lib/kdf/kdf.cpp1
-rw-r--r--src/lib/math/ec_gfp/point_gfp.cpp4
-rw-r--r--src/lib/math/mp/mp_generic/mp_madd.h21
-rw-r--r--src/lib/math/mp/mp_types.h13
-rw-r--r--src/lib/pubkey/mceies/mceies.cpp4
-rw-r--r--src/lib/rng/rng.h1
-rw-r--r--src/lib/stream/rc4/openssl_rc4.cpp14
-rw-r--r--src/lib/tls/credentials_manager.cpp13
-rw-r--r--src/lib/tls/msg_client_kex.cpp5
-rw-r--r--src/lib/tls/msg_server_kex.cpp54
-rw-r--r--src/lib/tls/sessions_sql/tls_session_manager_sql.cpp56
-rw-r--r--src/lib/tls/sessions_sql/tls_session_manager_sql.h4
-rw-r--r--src/lib/tls/tls_policy.cpp7
-rw-r--r--src/lib/tls/tls_reader.h2
-rw-r--r--src/lib/tls/tls_session.cpp19
-rw-r--r--src/lib/tls/tls_session_manager.h11
-rw-r--r--src/lib/tls/tls_session_manager_memory.cpp11
-rw-r--r--src/lib/tls/tls_suite_info.cpp7
-rw-r--r--src/lib/utils/calendar.cpp8
-rw-r--r--src/lib/utils/calendar.h4
-rw-r--r--src/lib/utils/database.h2
-rw-r--r--src/lib/utils/mul128.h12
-rw-r--r--src/lib/utils/sqlite3/sqlite3.cpp10
-rw-r--r--src/lib/utils/sqlite3/sqlite3.h2
-rwxr-xr-xsrc/scripts/tls_suite_info.py33
-rw-r--r--src/tests/catchy/catch.hpp9416
-rw-r--r--src/tests/catchy/catchy_tests.h128
-rw-r--r--src/tests/catchy/test_base.cpp25
-rw-r--r--src/tests/catchy/test_base64.cpp232
-rw-r--r--src/tests/catchy/test_bigint.cpp169
-rw-r--r--src/tests/catchy/test_cvc.cpp40
-rw-r--r--src/tests/catchy/test_stl_util.cpp21
-rw-r--r--src/tests/catchy/test_utils.cpp302
-rw-r--r--src/tests/catchy/test_x509.cpp142
-rw-r--r--src/tests/data/base64.vec73
-rw-r--r--src/tests/data/bcrypt.vec9
-rw-r--r--src/tests/data/bigint.vec2582
-rw-r--r--src/tests/data/block/lion.vec2
-rw-r--r--src/tests/data/dates.vec18
-rw-r--r--src/tests/data/hash/comp4p.vec2
-rw-r--r--src/tests/data/hash/gost.vec2
-rw-r--r--src/tests/data/hash/md5.vec2
-rw-r--r--src/tests/data/hash/parallel.vec4
-rw-r--r--src/tests/data/hash/sha1.vec2
-rw-r--r--src/tests/data/hash/tiger.vec4
-rw-r--r--src/tests/data/mac/hmac.vec2
-rw-r--r--src/tests/data/mp_valid.dat5477
-rw-r--r--src/tests/data/ocb_long.vec36
-rw-r--r--src/tests/data/passhash9.vec3
-rw-r--r--src/tests/data/pubkey/dsa.vec16
-rw-r--r--src/tests/data/pubkey/elgamal.vec20
-rw-r--r--src/tests/data/rfc3394.vec26
-rw-r--r--src/tests/data/rfc6979.vec14
-rw-r--r--src/tests/data/transform.vec0
-rw-r--r--src/tests/data/util.vec58
-rw-r--r--src/tests/test_aead.cpp208
-rw-r--r--src/tests/test_bigint.cpp757
-rw-r--r--src/tests/test_block.cpp108
-rw-r--r--src/tests/test_c25519.cpp176
-rw-r--r--src/tests/test_compression.cpp249
-rw-r--r--src/tests/test_cryptobox.cpp75
-rw-r--r--src/tests/test_cvc.cpp543
-rw-r--r--src/tests/test_dh.cpp110
-rw-r--r--src/tests/test_dlies.cpp118
-rw-r--r--src/tests/test_dsa.cpp101
-rw-r--r--src/tests/test_ecc_pointmul.cpp90
-rw-r--r--src/tests/test_ecdsa.cpp94
-rw-r--r--src/tests/test_elg.cpp97
-rw-r--r--src/tests/test_ffi.cpp665
-rw-r--r--src/tests/test_fuzzer.cpp102
-rw-r--r--src/tests/test_gf2m.cpp76
-rw-r--r--src/tests/test_gost_3410.cpp93
-rw-r--r--src/tests/test_hash.cpp116
-rw-r--r--src/tests/test_kdf.cpp59
-rw-r--r--src/tests/test_keywrap.cpp98
-rw-r--r--src/tests/test_mac.cpp118
-rw-r--r--src/tests/test_main.cpp244
-rw-r--r--src/tests/test_mce.cpp104
-rw-r--r--src/tests/test_mceliece.cpp351
-rw-r--r--src/tests/test_modes.cpp127
-rw-r--r--src/tests/test_nr.cpp101
-rw-r--r--src/tests/test_ocb.cpp178
-rw-r--r--src/tests/test_passhash.cpp139
-rw-r--r--src/tests/test_pbkdf.cpp66
-rw-r--r--src/tests/test_pubkey.cpp530
-rw-r--r--src/tests/test_pubkey.h137
-rw-r--r--src/tests/test_rfc6979.cpp99
-rw-r--r--src/tests/test_rng.cpp131
-rw-r--r--src/tests/test_rsa.cpp193
-rw-r--r--src/tests/test_rw.cpp104
-rw-r--r--src/tests/test_srp6.cpp67
-rw-r--r--src/tests/test_stream.cpp103
-rw-r--r--src/tests/test_transform.cpp49
-rw-r--r--src/tests/test_tss.cpp67
-rw-r--r--src/tests/test_utils.cpp331
-rw-r--r--src/tests/test_x509_path.cpp (renamed from src/tests/nist_x509.cpp)391
-rw-r--r--src/tests/tests.cpp915
-rw-r--r--src/tests/tests.h513
-rw-r--r--src/tests/unit_ecc.cpp1218
-rw-r--r--src/tests/unit_ecdh.cpp149
-rw-r--r--src/tests/unit_ecdsa.cpp559
-rw-r--r--src/tests/unit_tls.cpp680
-rw-r--r--src/tests/unit_x509.cpp333
112 files changed, 9231 insertions, 21869 deletions
diff --git a/src/cmd/mce.cpp b/src/cmd/mce.cpp
index 3b33df661..d179e0284 100644
--- a/src/cmd/mce.cpp
+++ b/src/cmd/mce.cpp
@@ -1,3 +1,9 @@
+/*
+* (C) 2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
#include "apps.h"
#if defined(BOTAN_HAS_MCELIECE)
diff --git a/src/lib/cert/cvc/cvc_gen_cert.h b/src/lib/cert/cvc/cvc_gen_cert.h
index 02c6f7324..6bdf116f3 100644
--- a/src/lib/cert/cvc/cvc_gen_cert.h
+++ b/src/lib/cert/cvc/cvc_gen_cert.h
@@ -77,7 +77,7 @@ class EAC1_1_gen_CVC : public EAC1_1_obj<Derived> // CRTP continuation from EAC1
const std::vector<byte>& tbs_bits,
RandomNumberGenerator& rng);
- EAC1_1_gen_CVC() { m_pk = 0; }
+ EAC1_1_gen_CVC() { m_pk = nullptr; }
virtual ~EAC1_1_gen_CVC<Derived>()
{ delete m_pk; }
diff --git a/src/lib/cert/x509/x509path.cpp b/src/lib/cert/x509/x509path.cpp
index a6c3ce6e9..b5345c272 100644
--- a/src/lib/cert/x509/x509path.cpp
+++ b/src/lib/cert/x509/x509path.cpp
@@ -338,6 +338,8 @@ const X509_Certificate& Path_Validation_Result::trust_root() const
{
if(m_cert_path.empty())
throw std::runtime_error("Path_Validation_Result::trust_root no path set");
+ if(result() != Certificate_Status_Code::VERIFIED)
+ throw std::runtime_error("Path_Validation_Result::trust_root meaningless with invalid status");
return m_cert_path[m_cert_path.size()-1];
}
diff --git a/src/lib/cert/x509/x509path.h b/src/lib/cert/x509/x509path.h
index c56aef21f..08d92915d 100644
--- a/src/lib/cert/x509/x509path.h
+++ b/src/lib/cert/x509/x509path.h
@@ -84,7 +84,8 @@ class BOTAN_DLL Path_Validation_Result
std::set<std::string> trusted_hashes() const;
/**
- * @return the trust root of the validation
+ * @return the trust root of the validation if successful
+ * throws an exception if the validation failed
*/
const X509_Certificate& trust_root() const;
diff --git a/src/lib/compression/bzip2/bzip2.h b/src/lib/compression/bzip2/bzip2.h
index 001080fd4..ca0ac529b 100644
--- a/src/lib/compression/bzip2/bzip2.h
+++ b/src/lib/compression/bzip2/bzip2.h
@@ -44,7 +44,7 @@ class BOTAN_DLL Bzip2_Decompression : public Stream_Decompression
public:
std::string name() const override { return "Bzip2_Decompression"; }
private:
- Compression_Stream* make_stream() const;
+ Compression_Stream* make_stream() const override;
};
}
diff --git a/src/lib/compression/lzma/lzma.h b/src/lib/compression/lzma/lzma.h
index ff6b45ef0..5f19c4b97 100644
--- a/src/lib/compression/lzma/lzma.h
+++ b/src/lib/compression/lzma/lzma.h
@@ -43,7 +43,7 @@ class BOTAN_DLL LZMA_Decompression : public Stream_Decompression
public:
std::string name() const override { return "LZMA_Decompression"; }
private:
- Compression_Stream* make_stream() const;
+ Compression_Stream* make_stream() const override;
};
}
diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp
index 7ed279bbd..eaf24eca6 100644
--- a/src/lib/ffi/ffi.cpp
+++ b/src/lib/ffi/ffi.cpp
@@ -876,7 +876,7 @@ int botan_privkey_destroy(botan_privkey_t key)
return 0;
}
-int botan_pubkey_destroy(botan_privkey_t key)
+int botan_pubkey_destroy(botan_pubkey_t key)
{
delete key;
return 0;
diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h
index 2def4f4d5..6cbe56743 100644
--- a/src/lib/ffi/ffi.h
+++ b/src/lib/ffi/ffi.h
@@ -351,7 +351,7 @@ BOTAN_DLL int botan_pubkey_estimated_strength(botan_pubkey_t key, size_t* estima
BOTAN_DLL int botan_pubkey_fingerprint(botan_pubkey_t key, const char* hash,
uint8_t out[], size_t* out_len);
-BOTAN_DLL int botan_pubkey_destroy(botan_privkey_t key);
+BOTAN_DLL int botan_pubkey_destroy(botan_pubkey_t key);
/*
diff --git a/src/lib/hash/sha2_64/sha2_64.h b/src/lib/hash/sha2_64/sha2_64.h
index 5aae5effe..736b33d12 100644
--- a/src/lib/hash/sha2_64/sha2_64.h
+++ b/src/lib/hash/sha2_64/sha2_64.h
@@ -60,7 +60,7 @@ class BOTAN_DLL SHA_512 : public MDx_HashFunction
class BOTAN_DLL SHA_512_256 : public MDx_HashFunction
{
public:
- std::string name() const override { return "SHA-512/256"; }
+ std::string name() const override { return "SHA-512-256"; }
size_t output_length() const override { return 32; }
HashFunction* clone() const override { return new SHA_512_256; }
diff --git a/src/lib/kdf/kdf.cpp b/src/lib/kdf/kdf.cpp
index 3eba8a5cd..cf13c4803 100644
--- a/src/lib/kdf/kdf.cpp
+++ b/src/lib/kdf/kdf.cpp
@@ -6,6 +6,7 @@
*/
#include <botan/kdf.h>
+#include <botan/exceptn.h>
#include <botan/internal/algo_registry.h>
#if defined(BOTAN_HAS_HKDF)
diff --git a/src/lib/math/ec_gfp/point_gfp.cpp b/src/lib/math/ec_gfp/point_gfp.cpp
index 705b14c52..c81c4ee5a 100644
--- a/src/lib/math/ec_gfp/point_gfp.cpp
+++ b/src/lib/math/ec_gfp/point_gfp.cpp
@@ -449,8 +449,6 @@ PointGFp Blinded_Point_Multiply::blinded_multiply(const BigInt& scalar_in,
BigInt PointGFp::get_affine_x() const
{
if(is_zero())
- abort();
- if(is_zero())
throw Illegal_Transformation("Cannot convert zero point to affine");
BigInt z2 = curve_sqr(m_coord_z);
@@ -463,8 +461,6 @@ BigInt PointGFp::get_affine_x() const
BigInt PointGFp::get_affine_y() const
{
if(is_zero())
- abort();
- if(is_zero())
throw Illegal_Transformation("Cannot convert zero point to affine");
BigInt z3 = curve_mult(m_coord_z, curve_sqr(m_coord_z));
diff --git a/src/lib/math/mp/mp_generic/mp_madd.h b/src/lib/math/mp/mp_generic/mp_madd.h
index 292c23e97..3b0487356 100644
--- a/src/lib/math/mp/mp_generic/mp_madd.h
+++ b/src/lib/math/mp/mp_generic/mp_madd.h
@@ -13,6 +13,27 @@
namespace Botan {
+#if (BOTAN_MP_WORD_BITS == 8)
+ typedef u16bit dword;
+ #define BOTAN_HAS_MP_DWORD
+#elif (BOTAN_MP_WORD_BITS == 16)
+ typedef u32bit dword;
+ #define BOTAN_HAS_MP_DWORD
+#elif (BOTAN_MP_WORD_BITS == 32)
+ typedef u64bit dword;
+ #define BOTAN_HAS_MP_DWORD
+#elif (BOTAN_MP_WORD_BITS == 64)
+
+ #include <botan/mul128.h>
+
+ #if defined(BOTAN_TARGET_HAS_NATIVE_UINT128)
+ typedef uint128_t dword;
+ #define BOTAN_HAS_MP_DWORD
+ #endif
+#else
+ #error BOTAN_MP_WORD_BITS must be 8, 16, 32, or 64
+#endif
+
/*
* Word Multiply/Add
*/
diff --git a/src/lib/math/mp/mp_types.h b/src/lib/math/mp/mp_types.h
index eab0d0c6c..69dc911fd 100644
--- a/src/lib/math/mp/mp_types.h
+++ b/src/lib/math/mp/mp_types.h
@@ -9,30 +9,17 @@
#define BOTAN_MPI_TYPES_H__
#include <botan/types.h>
-#include <botan/mul128.h>
namespace Botan {
#if (BOTAN_MP_WORD_BITS == 8)
typedef byte word;
- typedef u16bit dword;
- #define BOTAN_HAS_MP_DWORD
#elif (BOTAN_MP_WORD_BITS == 16)
typedef u16bit word;
- typedef u32bit dword;
- #define BOTAN_HAS_MP_DWORD
#elif (BOTAN_MP_WORD_BITS == 32)
typedef u32bit word;
- typedef u64bit dword;
- #define BOTAN_HAS_MP_DWORD
#elif (BOTAN_MP_WORD_BITS == 64)
typedef u64bit word;
-
- #if defined(BOTAN_TARGET_HAS_NATIVE_UINT128)
- typedef uint128_t dword;
- #define BOTAN_HAS_MP_DWORD
- #endif
-
#else
#error BOTAN_MP_WORD_BITS must be 8, 16, 32, or 64
#endif
diff --git a/src/lib/pubkey/mceies/mceies.cpp b/src/lib/pubkey/mceies/mceies.cpp
index d4d956a54..301c5dda4 100644
--- a/src/lib/pubkey/mceies/mceies.cpp
+++ b/src/lib/pubkey/mceies/mceies.cpp
@@ -99,6 +99,10 @@ mceies_decrypt(const McEliece_PrivateKey& privkey,
aead->finish(pt, 0);
return pt;
}
+ catch(Integrity_Failure)
+ {
+ throw;
+ }
catch(std::exception& e)
{
throw std::runtime_error("mce_decrypt failed: " + std::string(e.what()));
diff --git a/src/lib/rng/rng.h b/src/lib/rng/rng.h
index 261880d5d..a28a676a6 100644
--- a/src/lib/rng/rng.h
+++ b/src/lib/rng/rng.h
@@ -183,6 +183,7 @@ class BOTAN_DLL Serialized_RNG : public RandomNumberGenerator
}
Serialized_RNG() : m_rng(RandomNumberGenerator::make_rng()) {}
+ Serialized_RNG(RandomNumberGenerator* rng) : m_rng(rng) {}
private:
mutable std::mutex m_mutex;
std::unique_ptr<RandomNumberGenerator> m_rng;
diff --git a/src/lib/stream/rc4/openssl_rc4.cpp b/src/lib/stream/rc4/openssl_rc4.cpp
index e4f180a9b..84d739c91 100644
--- a/src/lib/stream/rc4/openssl_rc4.cpp
+++ b/src/lib/stream/rc4/openssl_rc4.cpp
@@ -23,7 +23,19 @@ class OpenSSL_RC4 : public StreamCipher
public:
void clear() { clear_mem(&m_rc4, 1); }
- std::string name() const { return "RC4"; }
+ std::string name() const
+ {
+ switch(m_skip)
+ {
+ case 0:
+ return "RC4";
+ case 256:
+ return "MARK-4";
+ default:
+ return "RC4_skip(" + std::to_string(m_skip) + ")";
+ }
+ }
+
StreamCipher* clone() const { return new OpenSSL_RC4; }
Key_Length_Specification key_spec() const
diff --git a/src/lib/tls/credentials_manager.cpp b/src/lib/tls/credentials_manager.cpp
index 43ba7650a..3762dc149 100644
--- a/src/lib/tls/credentials_manager.cpp
+++ b/src/lib/tls/credentials_manager.cpp
@@ -129,11 +129,14 @@ void Credentials_Manager::verify_certificate_chain(
Path_Validation_Restrictions restrictions;
- auto result = x509_path_validate(cert_chain,
- restrictions,
- trusted_CAs,
- purported_hostname,
- choose_leaf_usage(type));
+ Path_Validation_Result result = x509_path_validate(cert_chain,
+ restrictions,
+ trusted_CAs,
+ purported_hostname,
+ choose_leaf_usage(type));
+
+ if(!result.successful_validation())
+ throw std::runtime_error("Certificate validation failure: " + result.result_string());
if(!cert_in_some_store(trusted_CAs, result.trust_root()))
throw std::runtime_error("Certificate chain roots in unknown/untrusted CA");
diff --git a/src/lib/tls/msg_client_kex.cpp b/src/lib/tls/msg_client_kex.cpp
index c5b9305c7..7ce9b9df2 100644
--- a/src/lib/tls/msg_client_kex.cpp
+++ b/src/lib/tls/msg_client_kex.cpp
@@ -106,8 +106,9 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io,
DL_Group group(p, g);
- if(!group.verify_group(rng, true))
- throw Internal_Error("DH group failed validation, possible attack");
+ if(!group.verify_group(rng, false))
+ throw TLS_Exception(Alert::INSUFFICIENT_SECURITY,
+ "DH group validation failed");
DH_PublicKey counterparty_key(group, Y);
diff --git a/src/lib/tls/msg_server_kex.cpp b/src/lib/tls/msg_server_kex.cpp
index 3fcdb5ab2..0c3b5c704 100644
--- a/src/lib/tls/msg_server_kex.cpp
+++ b/src/lib/tls/msg_server_kex.cpp
@@ -1,6 +1,6 @@
/*
* Server Key Exchange Message
-* (C) 2004-2010,2012 Jack Lloyd
+* (C) 2004-2010,2012,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -145,21 +145,17 @@ Server_Key_Exchange::Server_Key_Exchange(const std::vector<byte>& buf,
Protocol_Version version) :
m_kex_key(nullptr), m_srp_params(nullptr)
{
- if(buf.size() < 6)
- throw Decoding_Error("Server_Key_Exchange: Packet corrupted");
-
TLS_Data_Reader reader("ServerKeyExchange", buf);
/*
- * We really are just serializing things back to what they were
- * before, but unfortunately to know where the signature is we need
- * to be able to parse the whole thing anyway.
+ * Here we are deserializing enough to find out what offset the
+ * signature is at. All processing is done when the Client Key Exchange
+ * is prepared.
*/
if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
{
- const std::string identity_hint = reader.get_string(2, 0, 65535);
- append_tls_length_value(m_params, identity_hint, 2);
+ reader.get_string(2, 0, 65535); // identity hint
}
if(kex_algo == "DH" || kex_algo == "DHE_PSK")
@@ -168,49 +164,29 @@ Server_Key_Exchange::Server_Key_Exchange(const std::vector<byte>& buf,
for(size_t i = 0; i != 3; ++i)
{
- BigInt v = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
- append_tls_length_value(m_params, BigInt::encode(v), 2);
+ reader.get_range<byte>(2, 1, 65535);
}
}
else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
{
- const byte curve_type = reader.get_byte();
-
- if(curve_type != 3)
- throw Decoding_Error("Server_Key_Exchange: Server sent non-named ECC curve");
-
- const u16bit curve_id = reader.get_u16bit();
-
- const std::string name = Supported_Elliptic_Curves::curve_id_to_name(curve_id);
-
- std::vector<byte> ecdh_key = reader.get_range<byte>(1, 1, 255);
-
- if(name == "")
- throw Decoding_Error("Server_Key_Exchange: Server sent unknown named curve " +
- std::to_string(curve_id));
-
- m_params.push_back(curve_type);
- m_params.push_back(get_byte(0, curve_id));
- m_params.push_back(get_byte(1, curve_id));
- append_tls_length_value(m_params, ecdh_key, 1);
+ reader.get_byte(); // curve type
+ reader.get_u16bit(); // curve id
+ reader.get_range<byte>(1, 1, 255); // public key
}
else if(kex_algo == "SRP_SHA")
{
// 2 bigints (N,g) then salt, then server B
- const BigInt N = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
- const BigInt g = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
- std::vector<byte> salt = reader.get_range<byte>(1, 1, 255);
- const BigInt B = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
-
- append_tls_length_value(m_params, BigInt::encode(N), 2);
- append_tls_length_value(m_params, BigInt::encode(g), 2);
- append_tls_length_value(m_params, salt, 1);
- append_tls_length_value(m_params, BigInt::encode(B), 2);
+ reader.get_range<byte>(2, 1, 65535);
+ reader.get_range<byte>(2, 1, 65535);
+ reader.get_range<byte>(1, 1, 255);
+ reader.get_range<byte>(2, 1, 65535);
}
else if(kex_algo != "PSK")
throw Decoding_Error("Server_Key_Exchange: Unsupported kex type " + kex_algo);
+ m_params.assign(buf.data(), buf.data() + reader.read_so_far());
+
if(sig_algo != "")
{
if(version.supports_negotiable_signature_algorithms())
diff --git a/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp b/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp
index ed207972e..9f025374e 100644
--- a/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp
+++ b/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp
@@ -16,27 +16,6 @@ namespace Botan {
namespace TLS {
-namespace {
-
-SymmetricKey derive_key(const std::string& passphrase,
- const byte salt[],
- size_t salt_len,
- size_t iterations,
- size_t& check_val)
- {
- std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(SHA-512)"));
-
- secure_vector<byte> x = pbkdf->derive_key(32 + 2,
- passphrase,
- salt, salt_len,
- iterations).bits_of();
-
- check_val = make_u16bit(x[0], x[1]);
- return SymmetricKey(&x[2], x.size() - 2);
- }
-
-}
-
Session_Manager_SQL::Session_Manager_SQL(std::shared_ptr<SQL_Database> db,
const std::string& passphrase,
RandomNumberGenerator& rng,
@@ -67,6 +46,8 @@ Session_Manager_SQL::Session_Manager_SQL(std::shared_ptr<SQL_Database> db,
const size_t salts = m_db->row_count("tls_sessions_metadata");
+ std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(SHA-512)"));
+
if(salts == 1)
{
// existing db
@@ -78,12 +59,13 @@ Session_Manager_SQL::Session_Manager_SQL(std::shared_ptr<SQL_Database> db,
const size_t iterations = stmt->get_size_t(1);
const size_t check_val_db = stmt->get_size_t(2);
- size_t check_val_created;
- m_session_key = derive_key(passphrase,
- salt.first,
- salt.second,
- iterations,
- check_val_created);
+ secure_vector<byte> x = pbkdf->pbkdf_iterations(32 + 2,
+ passphrase,
+ salt.first, salt.second,
+ iterations);
+
+ const size_t check_val_created = make_u16bit(x[0], x[1]);
+ m_session_key.assign(x.begin() + 2, x.end());
if(check_val_created != check_val_db)
throw std::runtime_error("Session database password not valid");
@@ -98,11 +80,17 @@ Session_Manager_SQL::Session_Manager_SQL(std::shared_ptr<SQL_Database> db,
// new database case
std::vector<byte> salt = unlock(rng.random_vec(16));
- const size_t iterations = 256 * 1024;
- size_t check_val = 0;
+ size_t iterations = 0;
- m_session_key = derive_key(passphrase, salt.data(), salt.size(),
- iterations, check_val);
+ secure_vector<byte> x = pbkdf->pbkdf_timed(32 + 2,
+ passphrase,
+ salt.data(), salt.size(),
+ std::chrono::milliseconds(100),
+ iterations);
+
+ printf("pbkdf iter %d\n", iterations);
+ size_t check_val = make_u16bit(x[0], x[1]);
+ m_session_key.assign(x.begin() + 2, x.end());
auto stmt = m_db->new_statement("insert into tls_sessions_metadata values(?1, ?2, ?3)");
@@ -174,6 +162,12 @@ void Session_Manager_SQL::remove_entry(const std::vector<byte>& session_id)
stmt->spin();
}
+size_t Session_Manager_SQL::remove_all()
+ {
+ auto stmt = m_db->new_statement("delete from tls_sessions");
+ return stmt->spin();
+ }
+
void Session_Manager_SQL::save(const Session& session)
{
auto stmt = m_db->new_statement("insert or replace into tls_sessions"
diff --git a/src/lib/tls/sessions_sql/tls_session_manager_sql.h b/src/lib/tls/sessions_sql/tls_session_manager_sql.h
index 081c42e74..24e2be7c3 100644
--- a/src/lib/tls/sessions_sql/tls_session_manager_sql.h
+++ b/src/lib/tls/sessions_sql/tls_session_manager_sql.h
@@ -56,6 +56,8 @@ class BOTAN_DLL Session_Manager_SQL : public Session_Manager
void remove_entry(const std::vector<byte>& session_id) override;
+ size_t remove_all() override;
+
void save(const Session& session_data) override;
std::chrono::seconds session_lifetime() const override
@@ -65,7 +67,7 @@ class BOTAN_DLL Session_Manager_SQL : public Session_Manager
void prune_session_cache();
std::shared_ptr<SQL_Database> m_db;
- SymmetricKey m_session_key;
+ secure_vector<byte> m_session_key;
RandomNumberGenerator& m_rng;
size_t m_max_sessions;
std::chrono::seconds m_session_lifetime;
diff --git a/src/lib/tls/tls_policy.cpp b/src/lib/tls/tls_policy.cpp
index d8dd2c828..7d1af71ef 100644
--- a/src/lib/tls/tls_policy.cpp
+++ b/src/lib/tls/tls_policy.cpp
@@ -1,6 +1,6 @@
/*
* Policies for TLS
-* (C) 2004-2010,2012 Jack Lloyd
+* (C) 2004-2010,2012,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -44,7 +44,7 @@ std::vector<std::string> Policy::allowed_signature_hashes() const
"SHA-512",
"SHA-384",
"SHA-256",
- "SHA-224",
+ //"SHA-224",
//"SHA-1",
//"MD5",
};
@@ -282,9 +282,6 @@ std::vector<u16bit> Policy::ciphersuite_list(Protocol_Version version,
if(!have_srp && suite.kex_algo() == "SRP_SHA")
continue;
- if(version.is_datagram_protocol() && suite.cipher_algo() == "RC4")
- continue;
-
if(!version.supports_aead_modes() && suite.mac_algo() == "AEAD")
continue;
diff --git a/src/lib/tls/tls_reader.h b/src/lib/tls/tls_reader.h
index c2aef3163..63a59625f 100644
--- a/src/lib/tls/tls_reader.h
+++ b/src/lib/tls/tls_reader.h
@@ -34,6 +34,8 @@ class TLS_Data_Reader
throw decode_error("Extra bytes at end of message");
}
+ size_t read_so_far() const { return m_offset; }
+
size_t remaining_bytes() const { return m_buf.size() - m_offset; }
bool has_remaining() const { return (remaining_bytes() > 0); }
diff --git a/src/lib/tls/tls_session.cpp b/src/lib/tls/tls_session.cpp
index 8cb1a2aa7..7089a70f0 100644
--- a/src/lib/tls/tls_session.cpp
+++ b/src/lib/tls/tls_session.cpp
@@ -11,8 +11,7 @@
#include <botan/asn1_str.h>
#include <botan/pem.h>
#include <botan/aead.h>
-#include <botan/sha2_32.h>
-#include <botan/hmac.h>
+#include <botan/mac.h>
namespace Botan {
@@ -162,10 +161,10 @@ Session::encrypt(const SymmetricKey& key, RandomNumberGenerator& rng) const
const secure_vector<byte> bits = this->DER_encode();
// Support any length key for input
- HMAC hmac(new SHA_256);
- hmac.set_key(key);
- hmac.update(nonce);
- aead->set_key(hmac.final());
+ std::unique_ptr<MessageAuthenticationCode> hmac(MessageAuthenticationCode::create("HMAC(SHA-256)"));
+ hmac->set_key(key);
+ hmac->update(nonce);
+ aead->set_key(hmac->final());
secure_vector<byte> buf = nonce;
buf += bits;
@@ -185,10 +184,10 @@ Session Session::decrypt(const byte in[], size_t in_len, const SymmetricKey& key
throw Decoding_Error("Encrypted session too short to be valid");
// Support any length key for input
- HMAC hmac(new SHA_256);
- hmac.set_key(key);
- hmac.update(in, nonce_len); // nonce bytes
- aead->set_key(hmac.final());
+ std::unique_ptr<MessageAuthenticationCode> hmac(MessageAuthenticationCode::create("HMAC(SHA-256)"));
+ hmac->set_key(key);
+ hmac->update(in, nonce_len); // nonce bytes
+ aead->set_key(hmac->final());
aead->start(in, nonce_len);
secure_vector<byte> buf(in + nonce_len, in + in_len);
diff --git a/src/lib/tls/tls_session_manager.h b/src/lib/tls/tls_session_manager.h
index c7aa1960b..5ab151c26 100644
--- a/src/lib/tls/tls_session_manager.h
+++ b/src/lib/tls/tls_session_manager.h
@@ -55,6 +55,11 @@ class BOTAN_DLL Session_Manager
virtual void remove_entry(const std::vector<byte>& session_id) = 0;
/**
+ * Remove all sessions from the cache, return number of sessions deleted
+ */
+ virtual size_t remove_all() = 0;
+
+ /**
* Save a session on a best effort basis; the manager may not in
* fact be able to save the session for whatever reason; this is
* not an error. Caller cannot assume that calling save followed
@@ -89,6 +94,8 @@ class BOTAN_DLL Session_Manager_Noop : public Session_Manager
void remove_entry(const std::vector<byte>&) override {}
+ size_t remove_all() override { return 0; }
+
void save(const Session&) override {}
std::chrono::seconds session_lifetime() const override
@@ -120,6 +127,8 @@ class BOTAN_DLL Session_Manager_In_Memory : public Session_Manager
void remove_entry(const std::vector<byte>& session_id) override;
+ size_t remove_all();
+
void save(const Session& session_data) override;
std::chrono::seconds session_lifetime() const override
@@ -136,7 +145,7 @@ class BOTAN_DLL Session_Manager_In_Memory : public Session_Manager
std::chrono::seconds m_session_lifetime;
RandomNumberGenerator& m_rng;
- SymmetricKey m_session_key;
+ secure_vector<byte> m_session_key;
std::map<std::string, std::vector<byte>> m_sessions; // hex(session_id) -> session
std::map<Server_Information, std::string> m_info_sessions;
diff --git a/src/lib/tls/tls_session_manager_memory.cpp b/src/lib/tls/tls_session_manager_memory.cpp
index 2c836290b..37019c943 100644
--- a/src/lib/tls/tls_session_manager_memory.cpp
+++ b/src/lib/tls/tls_session_manager_memory.cpp
@@ -20,7 +20,7 @@ Session_Manager_In_Memory::Session_Manager_In_Memory(
m_max_sessions(max_sessions),
m_session_lifetime(session_lifetime),
m_rng(rng),
- m_session_key(m_rng, 32)
+ m_session_key(m_rng.random_vec(32))
{}
bool Session_Manager_In_Memory::load_from_session_str(
@@ -95,6 +95,15 @@ void Session_Manager_In_Memory::remove_entry(
m_sessions.erase(i);
}
+size_t Session_Manager_In_Memory::remove_all()
+ {
+ const size_t removed = m_sessions.size();
+ m_info_sessions.clear();
+ m_sessions.clear();
+ m_session_key = m_rng.random_vec(32);
+ return removed;
+ }
+
void Session_Manager_In_Memory::save(const Session& session)
{
std::lock_guard<std::mutex> lock(m_mutex);
diff --git a/src/lib/tls/tls_suite_info.cpp b/src/lib/tls/tls_suite_info.cpp
index cb5c1d4c5..5aff035b9 100644
--- a/src/lib/tls/tls_suite_info.cpp
+++ b/src/lib/tls/tls_suite_info.cpp
@@ -2,8 +2,8 @@
* TLS cipher suite information
*
* This file was automatically generated from the IANA assignments
-* (tls-parameters.txt hash 4bc98b6f75ad5b63952b5f457fa7adbfef60f095)
-* by ./src/scripts/tls_suite_info.py on 2015-05-11
+* (tls-parameters.txt hash 6a934405ed41aa4d6113dad17f815867741430ac)
+* by ./src/scripts/tls_suite_info.py on 2015-11-13
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -57,9 +57,6 @@ Ciphersuite Ciphersuite::by_id(u16bit suite)
case 0xC081: // DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384
return Ciphersuite(0xC081, "DSA", "DH", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384");
- case 0x0066: // DHE_DSS_WITH_RC4_128_SHA
- return Ciphersuite(0x0066, "DSA", "DH", "RC4", 16, 0, 0, "SHA-1", 20);
-
case 0x0099: // DHE_DSS_WITH_SEED_CBC_SHA
return Ciphersuite(0x0099, "DSA", "DH", "SEED", 16, 16, 0, "SHA-1", 20);
diff --git a/src/lib/utils/calendar.cpp b/src/lib/utils/calendar.cpp
index f071a7328..73602d634 100644
--- a/src/lib/utils/calendar.cpp
+++ b/src/lib/utils/calendar.cpp
@@ -58,7 +58,7 @@ std::time_t boost_timegm(std::tm *tm)
using namespace boost::posix_time;
using namespace boost::gregorian;
const auto epoch = ptime(date(1970, 01, 01));
- const auto time = ptime(date(year, mon, day),
+ const auto time = ptime(date(year, mon, day),
hours(hour) + minutes(min) + seconds(sec));
const time_duration diff(time - epoch);
out = diff.ticks() / diff.ticks_per_second();
@@ -88,7 +88,7 @@ std::time_t fallback_timegm(std::tm *tm)
// Clear value of TZ
::setenv("TZ", "", 1);
::tzset();
-
+
out = ::mktime(tm);
// Restore TZ
@@ -113,10 +113,10 @@ std::time_t fallback_timegm(std::tm *tm)
}
-std::chrono::system_clock::time_point calendar_point::to_std_timepoint()
+std::chrono::system_clock::time_point calendar_point::to_std_timepoint() const
{
if (year < 1970)
- throw Invalid_Argument("calendar_point::to_std_timepoint() does not support years before 1990.");
+ throw Invalid_Argument("calendar_point::to_std_timepoint() does not support years before 1970.");
// 32 bit time_t ends at January 19, 2038
// https://msdn.microsoft.com/en-us/library/2093ets1.aspx
diff --git a/src/lib/utils/calendar.h b/src/lib/utils/calendar.h
index 0c87e62dd..a0b91f913 100644
--- a/src/lib/utils/calendar.h
+++ b/src/lib/utils/calendar.h
@@ -1,6 +1,6 @@
/*
* Calendar Functions
-* (C) 1999-2009 Jack Lloyd
+* (C) 1999-2009,2015 Jack Lloyd
* (C) 2015 Simon Warta (Kullo GmbH)
*
* Botan is released under the Simplified BSD License (see license.txt)
@@ -55,7 +55,7 @@ struct BOTAN_DLL calendar_point
/**
* Returns an STL timepoint object
*/
- std::chrono::system_clock::time_point to_std_timepoint();
+ std::chrono::system_clock::time_point to_std_timepoint() const;
/**
* Returns a human readable string of the struct's components.
diff --git a/src/lib/utils/database.h b/src/lib/utils/database.h
index 03a3174d6..bacbedd1e 100644
--- a/src/lib/utils/database.h
+++ b/src/lib/utils/database.h
@@ -36,7 +36,7 @@ class BOTAN_DLL SQL_Database
virtual size_t get_size_t(int column) = 0;
/* Run to completion */
- virtual void spin() = 0;
+ virtual size_t spin() = 0;
/* Maybe update */
virtual bool step() = 0;
diff --git a/src/lib/utils/mul128.h b/src/lib/utils/mul128.h
index 3ad7dbcdb..bcf5fa7ef 100644
--- a/src/lib/utils/mul128.h
+++ b/src/lib/utils/mul128.h
@@ -1,6 +1,6 @@
/*
* 64x64->128 bit multiply operation
-* (C) 2013 Jack Lloyd
+* (C) 2013,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -12,13 +12,13 @@
namespace Botan {
-#if defined(__SIZEOF_INT128__)
- #define BOTAN_TARGET_HAS_NATIVE_UINT128
- typedef unsigned __int128 uint128_t;
-
-#elif (BOTAN_GCC_VERSION > 440) && defined(BOTAN_TARGET_CPU_HAS_NATIVE_64BIT)
+// Prefer TI mode over __int128 as GCC rejects the latter in pendantic mode
+#if (BOTAN_GCC_VERSION > 440) && defined(BOTAN_TARGET_CPU_HAS_NATIVE_64BIT)
#define BOTAN_TARGET_HAS_NATIVE_UINT128
typedef unsigned int uint128_t __attribute__((mode(TI)));
+#elif defined(__SIZEOF_INT128__)
+ #define BOTAN_TARGET_HAS_NATIVE_UINT128
+ typedef unsigned __int128 uint128_t;
#endif
}
diff --git a/src/lib/utils/sqlite3/sqlite3.cpp b/src/lib/utils/sqlite3/sqlite3.cpp
index be3c2b227..267d7530a 100644
--- a/src/lib/utils/sqlite3/sqlite3.cpp
+++ b/src/lib/utils/sqlite3/sqlite3.cpp
@@ -125,9 +125,15 @@ size_t Sqlite3_Database::Sqlite3_Statement::get_size_t(int column)
return static_cast<size_t>(sessions_int);
}
-void Sqlite3_Database::Sqlite3_Statement::spin()
+size_t Sqlite3_Database::Sqlite3_Statement::spin()
{
- while(step()) {}
+ size_t steps = 0;
+ while(step())
+ {
+ ++steps;
+ }
+
+ return steps;
}
bool Sqlite3_Database::Sqlite3_Statement::step()
diff --git a/src/lib/utils/sqlite3/sqlite3.h b/src/lib/utils/sqlite3/sqlite3.h
index 8495a1d1b..067b94e85 100644
--- a/src/lib/utils/sqlite3/sqlite3.h
+++ b/src/lib/utils/sqlite3/sqlite3.h
@@ -39,7 +39,7 @@ class BOTAN_DLL Sqlite3_Database : public SQL_Database
std::pair<const byte*, size_t> get_blob(int column) override;
size_t get_size_t(int column) override;
- void spin() override;
+ size_t spin() override;
bool step() override;
Sqlite3_Statement(sqlite3* db, const std::string& base_sql);
diff --git a/src/scripts/tls_suite_info.py b/src/scripts/tls_suite_info.py
index 8589ddeec..dc0468c88 100755
--- a/src/scripts/tls_suite_info.py
+++ b/src/scripts/tls_suite_info.py
@@ -3,7 +3,7 @@
"""
Used to generate lib/tls/tls_suite_info.cpp from IANA params
-(C) 2011, 2012, 2013, 2014 Jack Lloyd
+(C) 2011, 2012, 2013, 2014, 2015 Jack Lloyd
Botan is released under the Simplified BSD License (see license.txt)
"""
@@ -53,7 +53,6 @@ def to_ciphersuite_info(code, name):
mac_algo = 'SHA256'
cipher_info = {
- 'RC4': ('RC4',None),
'CHACHA20': ('ChaCha',32),
'IDEA': ('IDEA',16),
'DES': ('DES',8),
@@ -72,7 +71,6 @@ def to_ciphersuite_info(code, name):
'SHA384': 'SHA-384',
'SHA512': 'SHA-512',
- 'RC4': 'RC4',
'CHACHA': 'ChaCha',
'3DES': 'TripleDES',
@@ -122,28 +120,26 @@ def to_ciphersuite_info(code, name):
return 'Ciphersuite(0x%s, "%s", "%s", "%s", %d, %d, %d, "AEAD", %d, "%s")' % (
code, sig_algo, kex_algo, "ChaCha20Poly1305", cipher_keylen, iv_len, 0, 0, mac_algo)
- stream_ciphers = ['RC4']
+ mode = cipher[-1]
+ if mode not in ['CBC', 'GCM', 'CCM(8)', 'CCM', 'OCB']:
+ print "#warning Unknown mode %s" % (' '.join(cipher))
- if cipher_algo not in stream_ciphers:
- mode = cipher[-1]
- if mode not in ['CBC', 'GCM', 'CCM(8)', 'CCM', 'OCB']:
- print "#warning Unknown mode %s" % (' '.join(cipher))
+ ivlen = 8 if cipher_algo == '3DES' else 16
- ivlen = 8 if cipher_algo == '3DES' else 16
-
- if mode != 'CBC':
- if mode == 'OCB':
- cipher_algo += '/OCB(12)'
- else:
- cipher_algo += '/' + mode
+ if mode != 'CBC':
+ if mode == 'OCB':
+ cipher_algo += '/OCB(12)'
+ else:
+ cipher_algo += '/' + mode
- if cipher_algo in stream_ciphers or mode == 'CBC':
+ if mode == 'CBC':
return 'Ciphersuite(0x%s, "%s", "%s", "%s", %d, %d, 0, "%s", %d)' % (
code, sig_algo, kex_algo, cipher_algo, cipher_keylen, ivlen, mac_algo, mac_keylen[mac_algo])
- elif mode == 'OCB':
+ elif mode == 'OCB':
return 'Ciphersuite(0x%s, "%s", "%s", "%s", %d, %d, %d, "AEAD", %d, "%s")' % (
code, sig_algo, kex_algo, cipher_algo, cipher_keylen, 4, 0, 0, mac_algo)
+
else:
iv_bytes_from_hs = 4
iv_bytes_from_rec = 8
@@ -242,9 +238,6 @@ def main(args = None):
def define_custom_ciphersuite(name, code):
suites[name] = (code, to_ciphersuite_info(code, name))
- # From http://tools.ietf.org/html/draft-ietf-tls-56-bit-ciphersuites-01
- define_custom_ciphersuite('DHE_DSS_WITH_RC4_128_SHA', '0066')
-
if options.with_chacha:
# Google servers - draft-agl-tls-chacha20poly1305-04
define_custom_ciphersuite('ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256', 'CC13')
diff --git a/src/tests/catchy/catch.hpp b/src/tests/catchy/catch.hpp
deleted file mode 100644
index de61226cf..000000000
--- a/src/tests/catchy/catch.hpp
+++ /dev/null
@@ -1,9416 +0,0 @@
-/*
- * Catch v1.2.1
- * Generated: 2015-06-30 18:23:27.961086
- * ----------------------------------------------------------
- * This file has been merged from multiple headers. Please don't edit it directly
- * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
- *
- * Distributed under the Boost Software License, Version 1.0. (See accompanying
- * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- */
-#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
-#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
-
-#define TWOBLUECUBES_CATCH_HPP_INCLUDED
-
-#ifdef __clang__
-# pragma clang system_header
-#elif defined __GNUC__
-# pragma GCC system_header
-#endif
-
-// #included from: internal/catch_suppress_warnings.h
-
-#define TWOBLUECUBES_CATCH_SUPPRESS_WARNINGS_H_INCLUDED
-
-#ifdef __clang__
-# ifdef __ICC // icpc defines the __clang__ macro
-# pragma warning(push)
-# pragma warning(disable: 161 1682)
-# else // __ICC
-# pragma clang diagnostic ignored "-Wglobal-constructors"
-# pragma clang diagnostic ignored "-Wvariadic-macros"
-# pragma clang diagnostic ignored "-Wc99-extensions"
-# pragma clang diagnostic ignored "-Wunused-variable"
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wpadded"
-# pragma clang diagnostic ignored "-Wc++98-compat"
-# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
-# pragma clang diagnostic ignored "-Wswitch-enum"
-# endif
-#elif defined __GNUC__
-# pragma GCC diagnostic ignored "-Wvariadic-macros"
-# pragma GCC diagnostic ignored "-Wunused-variable"
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wpadded"
-#endif
-
-#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
-# define CATCH_IMPL
-#endif
-
-#ifdef CATCH_IMPL
-# ifndef CLARA_CONFIG_MAIN
-# define CLARA_CONFIG_MAIN_NOT_DEFINED
-# define CLARA_CONFIG_MAIN
-# endif
-#endif
-
-// #included from: internal/catch_notimplemented_exception.h
-#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
-
-// #included from: catch_common.h
-#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
-
-#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
-#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
-#define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
-
-#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
-#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
-
-#include <sstream>
-#include <stdexcept>
-#include <algorithm>
-
-// #included from: catch_compiler_capabilities.h
-#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
-
-// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
-// The following features are defined:
-//
-// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
-// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
-// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
-// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
-// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
-
-// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
-
-// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
-
-// In general each macro has a _NO_<feature name> form
-// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
-// Many features, at point of detection, define an _INTERNAL_ macro, so they
-// can be combined, en-mass, with the _NO_ forms later.
-
-// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
-
-#ifdef __clang__
-
-# if __has_feature(cxx_nullptr)
-# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
-# endif
-
-# if __has_feature(cxx_noexcept)
-# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
-# endif
-
-#endif // __clang__
-
-////////////////////////////////////////////////////////////////////////////////
-// Borland
-#ifdef __BORLANDC__
-
-#endif // __BORLANDC__
-
-////////////////////////////////////////////////////////////////////////////////
-// EDG
-#ifdef __EDG_VERSION__
-
-#endif // __EDG_VERSION__
-
-////////////////////////////////////////////////////////////////////////////////
-// Digital Mars
-#ifdef __DMC__
-
-#endif // __DMC__
-
-////////////////////////////////////////////////////////////////////////////////
-// GCC
-#ifdef __GNUC__
-
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) )
-# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
-#endif
-
-#endif // __GNUC__
-
-////////////////////////////////////////////////////////////////////////////////
-// Visual C++
-#ifdef _MSC_VER
-
-#if (_MSC_VER >= 1600)
-# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
-#endif
-
-#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
-#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
-#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
-#endif
-
-#endif // _MSC_VER
-
-// Use variadic macros if the compiler supports them
-#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
- ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
- ( defined __GNUC__ && __GNUC__ >= 3 ) || \
- ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
-
-#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
-
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// C++ language feature support
-
-// catch all support for C++11
-#if (__cplusplus >= 201103L)
-
-# define CATCH_CPP11_OR_GREATER
-
-# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
-# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
-# endif
-
-# ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
-# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
-# endif
-
-# ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
-# define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
-# endif
-
-# ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
-# define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
-# endif
-
-# ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
-# define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
-# endif
-
-# ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
-# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
-# endif
-
-#endif // __cplusplus >= 201103L
-
-// Now set the actual defines based on the above + anything the user has configured
-#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
-# define CATCH_CONFIG_CPP11_NULLPTR
-#endif
-#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
-# define CATCH_CONFIG_CPP11_NOEXCEPT
-#endif
-#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)
-# define CATCH_CONFIG_CPP11_GENERATED_METHODS
-#endif
-#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)
-# define CATCH_CONFIG_CPP11_IS_ENUM
-#endif
-#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
-# define CATCH_CONFIG_CPP11_TUPLE
-#endif
-#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
-#define CATCH_CONFIG_VARIADIC_MACROS
-#endif
-
-// noexcept support:
-#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
-# define CATCH_NOEXCEPT noexcept
-# define CATCH_NOEXCEPT_IS(x) noexcept(x)
-#else
-# define CATCH_NOEXCEPT throw()
-# define CATCH_NOEXCEPT_IS(x)
-#endif
-
-namespace Catch {
-
- class NonCopyable {
-#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
- NonCopyable( NonCopyable const& ) = delete;
- NonCopyable( NonCopyable && ) = delete;
- NonCopyable& operator = ( NonCopyable const& ) = delete;
- NonCopyable& operator = ( NonCopyable && ) = delete;
-#else
- NonCopyable( NonCopyable const& info );
- NonCopyable& operator = ( NonCopyable const& );
-#endif
-
- protected:
- NonCopyable() {}
- virtual ~NonCopyable();
- };
-
- class SafeBool {
- public:
- typedef void (SafeBool::*type)() const;
-
- static type makeSafe( bool value ) {
- return value ? &SafeBool::trueValue : 0;
- }
- private:
- void trueValue() const {}
- };
-
- template<typename ContainerT>
- inline void deleteAll( ContainerT& container ) {
- typename ContainerT::const_iterator it = container.begin();
- typename ContainerT::const_iterator itEnd = container.end();
- for(; it != itEnd; ++it )
- delete *it;
- }
- template<typename AssociativeContainerT>
- inline void deleteAllValues( AssociativeContainerT& container ) {
- typename AssociativeContainerT::const_iterator it = container.begin();
- typename AssociativeContainerT::const_iterator itEnd = container.end();
- for(; it != itEnd; ++it )
- delete it->second;
- }
-
- bool startsWith( std::string const& s, std::string const& prefix );
- bool endsWith( std::string const& s, std::string const& suffix );
- bool contains( std::string const& s, std::string const& infix );
- void toLowerInPlace( std::string& s );
- std::string toLower( std::string const& s );
- std::string trim( std::string const& str );
- bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
-
- struct pluralise {
- pluralise( std::size_t count, std::string const& label );
-
- friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
-
- std::size_t m_count;
- std::string m_label;
- };
-
- struct SourceLineInfo {
-
- SourceLineInfo();
- SourceLineInfo( char const* _file, std::size_t _line );
- SourceLineInfo( SourceLineInfo const& other );
-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
- SourceLineInfo( SourceLineInfo && ) = default;
- SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
- SourceLineInfo& operator = ( SourceLineInfo && ) = default;
-# endif
- bool empty() const;
- bool operator == ( SourceLineInfo const& other ) const;
- bool operator < ( SourceLineInfo const& other ) const;
-
- std::string file;
- std::size_t line;
- };
-
- std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
-
- // This is just here to avoid compiler warnings with macro constants and boolean literals
- inline bool isTrue( bool value ){ return value; }
- inline bool alwaysTrue() { return true; }
- inline bool alwaysFalse() { return false; }
-
- void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
-
- // Use this in variadic streaming macros to allow
- // >> +StreamEndStop
- // as well as
- // >> stuff +StreamEndStop
- struct StreamEndStop {
- std::string operator+() {
- return std::string();
- }
- };
- template<typename T>
- T const& operator + ( T const& value, StreamEndStop ) {
- return value;
- }
-}
-
-#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
-#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
-
-#include <ostream>
-
-namespace Catch {
-
- class NotImplementedException : public std::exception
- {
- public:
- NotImplementedException( SourceLineInfo const& lineInfo );
- NotImplementedException( NotImplementedException const& ) {}
-
- virtual ~NotImplementedException() CATCH_NOEXCEPT {}
-
- virtual const char* what() const CATCH_NOEXCEPT;
-
- private:
- std::string m_what;
- SourceLineInfo m_lineInfo;
- };
-
-} // end namespace Catch
-
-///////////////////////////////////////////////////////////////////////////////
-#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
-
-// #included from: internal/catch_context.h
-#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
-
-// #included from: catch_interfaces_generators.h
-#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
-
-#include <string>
-
-namespace Catch {
-
- struct IGeneratorInfo {
- virtual ~IGeneratorInfo();
- virtual bool moveNext() = 0;
- virtual std::size_t getCurrentIndex() const = 0;
- };
-
- struct IGeneratorsForTest {
- virtual ~IGeneratorsForTest();
-
- virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
- virtual bool moveNext() = 0;
- };
-
- IGeneratorsForTest* createGeneratorsForTest();
-
-} // end namespace Catch
-
-// #included from: catch_ptr.hpp
-#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
-
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wpadded"
-#endif
-
-namespace Catch {
-
- // An intrusive reference counting smart pointer.
- // T must implement addRef() and release() methods
- // typically implementing the IShared interface
- template<typename T>
- class Ptr {
- public:
- Ptr() : m_p( NULL ){}
- Ptr( T* p ) : m_p( p ){
- if( m_p )
- m_p->addRef();
- }
- Ptr( Ptr const& other ) : m_p( other.m_p ){
- if( m_p )
- m_p->addRef();
- }
- ~Ptr(){
- if( m_p )
- m_p->release();
- }
- void reset() {
- if( m_p )
- m_p->release();
- m_p = NULL;
- }
- Ptr& operator = ( T* p ){
- Ptr temp( p );
- swap( temp );
- return *this;
- }
- Ptr& operator = ( Ptr const& other ){
- Ptr temp( other );
- swap( temp );
- return *this;
- }
- void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
- T* get() { return m_p; }
- const T* get() const{ return m_p; }
- T& operator*() const { return *m_p; }
- T* operator->() const { return m_p; }
- bool operator !() const { return m_p == NULL; }
- operator SafeBool::type() const { return SafeBool::makeSafe( m_p != NULL ); }
-
- private:
- T* m_p;
- };
-
- struct IShared : NonCopyable {
- virtual ~IShared();
- virtual void addRef() const = 0;
- virtual void release() const = 0;
- };
-
- template<typename T = IShared>
- struct SharedImpl : T {
-
- SharedImpl() : m_rc( 0 ){}
-
- virtual void addRef() const {
- ++m_rc;
- }
- virtual void release() const {
- if( --m_rc == 0 )
- delete this;
- }
-
- mutable unsigned int m_rc;
- };
-
-} // end namespace Catch
-
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
-
-#include <memory>
-#include <vector>
-#include <stdlib.h>
-
-namespace Catch {
-
- class TestCase;
- class Stream;
- struct IResultCapture;
- struct IRunner;
- struct IGeneratorsForTest;
- struct IConfig;
-
- struct IContext
- {
- virtual ~IContext();
-
- virtual IResultCapture* getResultCapture() = 0;
- virtual IRunner* getRunner() = 0;
- virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
- virtual bool advanceGeneratorsForCurrentTest() = 0;
- virtual Ptr<IConfig const> getConfig() const = 0;
- };
-
- struct IMutableContext : IContext
- {
- virtual ~IMutableContext();
- virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
- virtual void setRunner( IRunner* runner ) = 0;
- virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
- };
-
- IContext& getCurrentContext();
- IMutableContext& getCurrentMutableContext();
- void cleanUpContext();
- Stream createStream( std::string const& streamName );
-
-}
-
-// #included from: internal/catch_test_registry.hpp
-#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
-
-// #included from: catch_interfaces_testcase.h
-#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
-
-#include <vector>
-
-namespace Catch {
-
- class TestSpec;
-
- struct ITestCase : IShared {
- virtual void invoke () const = 0;
- protected:
- virtual ~ITestCase();
- };
-
- class TestCase;
- struct IConfig;
-
- struct ITestCaseRegistry {
- virtual ~ITestCaseRegistry();
- virtual std::vector<TestCase> const& getAllTests() const = 0;
- virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases, bool negated = false ) const = 0;
-
- };
-}
-
-namespace Catch {
-
-template<typename C>
-class MethodTestCase : public SharedImpl<ITestCase> {
-
-public:
- MethodTestCase( void (C::*method)() ) : m_method( method ) {}
-
- virtual void invoke() const {
- C obj;
- (obj.*m_method)();
- }
-
-private:
- virtual ~MethodTestCase() {}
-
- void (C::*m_method)();
-};
-
-typedef void(*TestFunction)();
-
-struct NameAndDesc {
- NameAndDesc( const char* _name = "", const char* _description= "" )
- : name( _name ), description( _description )
- {}
-
- const char* name;
- const char* description;
-};
-
-struct AutoReg {
-
- AutoReg( TestFunction function,
- SourceLineInfo const& lineInfo,
- NameAndDesc const& nameAndDesc );
-
- template<typename C>
- AutoReg( void (C::*method)(),
- char const* className,
- NameAndDesc const& nameAndDesc,
- SourceLineInfo const& lineInfo ) {
- registerTestCase( new MethodTestCase<C>( method ),
- className,
- nameAndDesc,
- lineInfo );
- }
-
- void registerTestCase( ITestCase* testCase,
- char const* className,
- NameAndDesc const& nameAndDesc,
- SourceLineInfo const& lineInfo );
-
- ~AutoReg();
-
-private:
- AutoReg( AutoReg const& );
- void operator= ( AutoReg const& );
-};
-
-} // end namespace Catch
-
-#ifdef CATCH_CONFIG_VARIADIC_MACROS
- ///////////////////////////////////////////////////////////////////////////////
- #define INTERNAL_CATCH_TESTCASE( ... ) \
- static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
- static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
-
- ///////////////////////////////////////////////////////////////////////////////
- #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
-
- ///////////////////////////////////////////////////////////////////////////////
- #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\
- namespace{ \
- struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
- void test(); \
- }; \
- Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
- } \
- void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
-
-#else
- ///////////////////////////////////////////////////////////////////////////////
- #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
- static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
- static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
-
- ///////////////////////////////////////////////////////////////////////////////
- #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
-
- ///////////////////////////////////////////////////////////////////////////////
- #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
- namespace{ \
- struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
- void test(); \
- }; \
- Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
- } \
- void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
-
-#endif
-
-// #included from: internal/catch_capture.hpp
-#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
-
-// #included from: catch_result_builder.h
-#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
-
-// #included from: catch_result_type.h
-#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
-
-namespace Catch {
-
- // ResultWas::OfType enum
- struct ResultWas { enum OfType {
- Unknown = -1,
- Ok = 0,
- Info = 1,
- Warning = 2,
-
- FailureBit = 0x10,
-
- ExpressionFailed = FailureBit | 1,
- ExplicitFailure = FailureBit | 2,
-
- Exception = 0x100 | FailureBit,
-
- ThrewException = Exception | 1,
- DidntThrowException = Exception | 2,
-
- FatalErrorCondition = 0x200 | FailureBit
-
- }; };
-
- inline bool isOk( ResultWas::OfType resultType ) {
- return ( resultType & ResultWas::FailureBit ) == 0;
- }
- inline bool isJustInfo( int flags ) {
- return flags == ResultWas::Info;
- }
-
- // ResultDisposition::Flags enum
- struct ResultDisposition { enum Flags {
- Normal = 0x01,
-
- ContinueOnFailure = 0x02, // Failures fail test, but execution continues
- FalseTest = 0x04, // Prefix expression with !
- SuppressFail = 0x08 // Failures are reported but do not fail the test
- }; };
-
- inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
- return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
- }
-
- inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
- inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
- inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
-
-} // end namespace Catch
-
-// #included from: catch_assertionresult.h
-#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
-
-#include <string>
-
-namespace Catch {
-
- struct AssertionInfo
- {
- AssertionInfo() {}
- AssertionInfo( std::string const& _macroName,
- SourceLineInfo const& _lineInfo,
- std::string const& _capturedExpression,
- ResultDisposition::Flags _resultDisposition );
-
- std::string macroName;
- SourceLineInfo lineInfo;
- std::string capturedExpression;
- ResultDisposition::Flags resultDisposition;
- };
-
- struct AssertionResultData
- {
- AssertionResultData() : resultType( ResultWas::Unknown ) {}
-
- std::string reconstructedExpression;
- std::string message;
- ResultWas::OfType resultType;
- };
-
- class AssertionResult {
- public:
- AssertionResult();
- AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
- ~AssertionResult();
-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
- AssertionResult( AssertionResult const& ) = default;
- AssertionResult( AssertionResult && ) = default;
- AssertionResult& operator = ( AssertionResult const& ) = default;
- AssertionResult& operator = ( AssertionResult && ) = default;
-# endif
-
- bool isOk() const;
- bool succeeded() const;
- ResultWas::OfType getResultType() const;
- bool hasExpression() const;
- bool hasMessage() const;
- std::string getExpression() const;
- std::string getExpressionInMacro() const;
- bool hasExpandedExpression() const;
- std::string getExpandedExpression() const;
- std::string getMessage() const;
- SourceLineInfo getSourceInfo() const;
- std::string getTestMacroName() const;
-
- protected:
- AssertionInfo m_info;
- AssertionResultData m_resultData;
- };
-
-} // end namespace Catch
-
-namespace Catch {
-
- struct TestFailureException{};
-
- template<typename T> class ExpressionLhs;
-
- struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
-
- struct CopyableStream {
- CopyableStream() {}
- CopyableStream( CopyableStream const& other ) {
- oss << other.oss.str();
- }
- CopyableStream& operator=( CopyableStream const& other ) {
- oss.str("");
- oss << other.oss.str();
- return *this;
- }
- std::ostringstream oss;
- };
-
- class ResultBuilder {
- public:
- ResultBuilder( char const* macroName,
- SourceLineInfo const& lineInfo,
- char const* capturedExpression,
- ResultDisposition::Flags resultDisposition );
-
- template<typename T>
- ExpressionLhs<T const&> operator <= ( T const& operand );
- ExpressionLhs<bool> operator <= ( bool value );
-
- template<typename T>
- ResultBuilder& operator << ( T const& value ) {
- m_stream.oss << value;
- return *this;
- }
-
- template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
- template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
-
- ResultBuilder& setResultType( ResultWas::OfType result );
- ResultBuilder& setResultType( bool result );
- ResultBuilder& setLhs( std::string const& lhs );
- ResultBuilder& setRhs( std::string const& rhs );
- ResultBuilder& setOp( std::string const& op );
-
- void endExpression();
-
- std::string reconstructExpression() const;
- AssertionResult build() const;
-
- void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
- void captureResult( ResultWas::OfType resultType );
- void captureExpression();
- void react();
- bool shouldDebugBreak() const;
- bool allowThrows() const;
-
- private:
- AssertionInfo m_assertionInfo;
- AssertionResultData m_data;
- struct ExprComponents {
- ExprComponents() : testFalse( false ) {}
- bool testFalse;
- std::string lhs, rhs, op;
- } m_exprComponents;
- CopyableStream m_stream;
-
- bool m_shouldDebugBreak;
- bool m_shouldThrow;
- };
-
-} // namespace Catch
-
-// Include after due to circular dependency:
-// #included from: catch_expression_lhs.hpp
-#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
-
-// #included from: catch_evaluate.hpp
-#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
-#endif
-
-#include <cstddef>
-
-namespace Catch {
-namespace Internal {
-
- enum Operator {
- IsEqualTo,
- IsNotEqualTo,
- IsLessThan,
- IsGreaterThan,
- IsLessThanOrEqualTo,
- IsGreaterThanOrEqualTo
- };
-
- template<Operator Op> struct OperatorTraits { static const char* getName(){ return "*error*"; } };
- template<> struct OperatorTraits<IsEqualTo> { static const char* getName(){ return "=="; } };
- template<> struct OperatorTraits<IsNotEqualTo> { static const char* getName(){ return "!="; } };
- template<> struct OperatorTraits<IsLessThan> { static const char* getName(){ return "<"; } };
- template<> struct OperatorTraits<IsGreaterThan> { static const char* getName(){ return ">"; } };
- template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } };
- template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
-
- template<typename T>
- inline T& opCast(T const& t) { return const_cast<T&>(t); }
-
-// nullptr_t support based on pull request #154 from Konstantin Baumann
-#ifdef CATCH_CONFIG_CPP11_NULLPTR
- inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
-#endif // CATCH_CONFIG_CPP11_NULLPTR
-
- // So the compare overloads can be operator agnostic we convey the operator as a template
- // enum, which is used to specialise an Evaluator for doing the comparison.
- template<typename T1, typename T2, Operator Op>
- class Evaluator{};
-
- template<typename T1, typename T2>
- struct Evaluator<T1, T2, IsEqualTo> {
- static bool evaluate( T1 const& lhs, T2 const& rhs) {
- return opCast( lhs ) == opCast( rhs );
- }
- };
- template<typename T1, typename T2>
- struct Evaluator<T1, T2, IsNotEqualTo> {
- static bool evaluate( T1 const& lhs, T2 const& rhs ) {
- return opCast( lhs ) != opCast( rhs );
- }
- };
- template<typename T1, typename T2>
- struct Evaluator<T1, T2, IsLessThan> {
- static bool evaluate( T1 const& lhs, T2 const& rhs ) {
- return opCast( lhs ) < opCast( rhs );
- }
- };
- template<typename T1, typename T2>
- struct Evaluator<T1, T2, IsGreaterThan> {
- static bool evaluate( T1 const& lhs, T2 const& rhs ) {
- return opCast( lhs ) > opCast( rhs );
- }
- };
- template<typename T1, typename T2>
- struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
- static bool evaluate( T1 const& lhs, T2 const& rhs ) {
- return opCast( lhs ) >= opCast( rhs );
- }
- };
- template<typename T1, typename T2>
- struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
- static bool evaluate( T1 const& lhs, T2 const& rhs ) {
- return opCast( lhs ) <= opCast( rhs );
- }
- };
-
- template<Operator Op, typename T1, typename T2>
- bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
- return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
- }
-
- // This level of indirection allows us to specialise for integer types
- // to avoid signed/ unsigned warnings
-
- // "base" overload
- template<Operator Op, typename T1, typename T2>
- bool compare( T1 const& lhs, T2 const& rhs ) {
- return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
- }
-
- // unsigned X to int
- template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
- return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
- }
- template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
- return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
- }
- template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
- return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
- }
-
- // unsigned X to long
- template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
- return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
- }
- template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
- return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
- }
- template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
- return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
- }
-
- // int to unsigned X
- template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
- return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
- }
- template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
- return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
- }
- template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
- return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
- }
-
- // long to unsigned X
- template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
- return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
- }
- template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
- return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
- }
- template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
- return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
- }
-
- // pointer to long (when comparing against NULL)
- template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
- return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
- }
- template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
- return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
- }
-
- // pointer to int (when comparing against NULL)
- template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
- return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
- }
- template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
- return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
- }
-
-#ifdef CATCH_CONFIG_CPP11_NULLPTR
- // pointer to nullptr_t (when comparing against nullptr)
- template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
- return Evaluator<T*, T*, Op>::evaluate( NULL, rhs );
- }
- template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
- return Evaluator<T*, T*, Op>::evaluate( lhs, NULL );
- }
-#endif // CATCH_CONFIG_CPP11_NULLPTR
-
-} // end of namespace Internal
-} // end of namespace Catch
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-// #included from: catch_tostring.h
-#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
-
-#include <sstream>
-#include <iomanip>
-#include <limits>
-#include <vector>
-#include <cstddef>
-
-#ifdef __OBJC__
-// #included from: catch_objc_arc.hpp
-#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
-
-#import <Foundation/Foundation.h>
-
-#ifdef __has_feature
-#define CATCH_ARC_ENABLED __has_feature(objc_arc)
-#else
-#define CATCH_ARC_ENABLED 0
-#endif
-
-void arcSafeRelease( NSObject* obj );
-id performOptionalSelector( id obj, SEL sel );
-
-#if !CATCH_ARC_ENABLED
-inline void arcSafeRelease( NSObject* obj ) {
- [obj release];
-}
-inline id performOptionalSelector( id obj, SEL sel ) {
- if( [obj respondsToSelector: sel] )
- return [obj performSelector: sel];
- return nil;
-}
-#define CATCH_UNSAFE_UNRETAINED
-#define CATCH_ARC_STRONG
-#else
-inline void arcSafeRelease( NSObject* ){}
-inline id performOptionalSelector( id obj, SEL sel ) {
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
-#endif
- if( [obj respondsToSelector: sel] )
- return [obj performSelector: sel];
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
- return nil;
-}
-#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
-#define CATCH_ARC_STRONG __strong
-#endif
-
-#endif
-
-#ifdef CATCH_CONFIG_CPP11_TUPLE
-#include <tuple>
-#endif
-
-#ifdef CATCH_CONFIG_CPP11_IS_ENUM
-#include <type_traits>
-#endif
-
-namespace Catch {
-
-// Why we're here.
-template<typename T>
-std::string toString( T const& value );
-
-// Built in overloads
-
-std::string toString( std::string const& value );
-std::string toString( std::wstring const& value );
-std::string toString( const char* const value );
-std::string toString( char* const value );
-std::string toString( const wchar_t* const value );
-std::string toString( wchar_t* const value );
-std::string toString( int value );
-std::string toString( unsigned long value );
-std::string toString( unsigned int value );
-std::string toString( const double value );
-std::string toString( const float value );
-std::string toString( bool value );
-std::string toString( char value );
-std::string toString( signed char value );
-std::string toString( unsigned char value );
-
-#ifdef CATCH_CONFIG_CPP11_NULLPTR
-std::string toString( std::nullptr_t );
-#endif
-
-#ifdef __OBJC__
- std::string toString( NSString const * const& nsstring );
- std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
- std::string toString( NSObject* const& nsObject );
-#endif
-
-namespace Detail {
-
- extern std::string unprintableString;
-
- struct BorgType {
- template<typename T> BorgType( T const& );
- };
-
- struct TrueType { char sizer[1]; };
- struct FalseType { char sizer[2]; };
-
- TrueType& testStreamable( std::ostream& );
- FalseType testStreamable( FalseType );
-
- FalseType operator<<( std::ostream const&, BorgType const& );
-
- template<typename T>
- struct IsStreamInsertable {
- static std::ostream &s;
- static T const&t;
- enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
- };
-
-#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
- template<typename T,
- bool IsEnum = std::is_enum<T>::value
- >
- struct EnumStringMaker
- {
- static std::string convert( T const& ) { return unprintableString; }
- };
-
- template<typename T>
- struct EnumStringMaker<T,true>
- {
- static std::string convert( T const& v )
- {
- return ::Catch::toString(
- static_cast<typename std::underlying_type<T>::type>(v)
- );
- }
- };
-#endif
- template<bool C>
- struct StringMakerBase {
-#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
- template<typename T>
- static std::string convert( T const& v )
- {
- return EnumStringMaker<T>::convert( v );
- }
-#else
- template<typename T>
- static std::string convert( T const& ) { return unprintableString; }
-#endif
- };
-
- template<>
- struct StringMakerBase<true> {
- template<typename T>
- static std::string convert( T const& _value ) {
- std::ostringstream oss;
- oss << _value;
- return oss.str();
- }
- };
-
- std::string rawMemoryToString( const void *object, std::size_t size );
-
- template<typename T>
- inline std::string rawMemoryToString( const T& object ) {
- return rawMemoryToString( &object, sizeof(object) );
- }
-
-} // end namespace Detail
-
-template<typename T>
-struct StringMaker :
- Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
-
-template<typename T>
-struct StringMaker<T*> {
- template<typename U>
- static std::string convert( U* p ) {
- if( !p )
- return INTERNAL_CATCH_STRINGIFY( NULL );
- else
- return Detail::rawMemoryToString( p );
- }
-};
-
-template<typename R, typename C>
-struct StringMaker<R C::*> {
- static std::string convert( R C::* p ) {
- if( !p )
- return INTERNAL_CATCH_STRINGIFY( NULL );
- else
- return Detail::rawMemoryToString( p );
- }
-};
-
-namespace Detail {
- template<typename InputIterator>
- std::string rangeToString( InputIterator first, InputIterator last );
-}
-
-//template<typename T, typename Allocator>
-//struct StringMaker<std::vector<T, Allocator> > {
-// static std::string convert( std::vector<T,Allocator> const& v ) {
-// return Detail::rangeToString( v.begin(), v.end() );
-// }
-//};
-
-template<typename T, typename Allocator>
-std::string toString( std::vector<T,Allocator> const& v ) {
- return Detail::rangeToString( v.begin(), v.end() );
-}
-
-#ifdef CATCH_CONFIG_CPP11_TUPLE
-
-// toString for tuples
-namespace TupleDetail {
- template<
- typename Tuple,
- std::size_t N = 0,
- bool = (N < std::tuple_size<Tuple>::value)
- >
- struct ElementPrinter {
- static void print( const Tuple& tuple, std::ostream& os )
- {
- os << ( N ? ", " : " " )
- << Catch::toString(std::get<N>(tuple));
- ElementPrinter<Tuple,N+1>::print(tuple,os);
- }
- };
-
- template<
- typename Tuple,
- std::size_t N
- >
- struct ElementPrinter<Tuple,N,false> {
- static void print( const Tuple&, std::ostream& ) {}
- };
-
-}
-
-template<typename ...Types>
-struct StringMaker<std::tuple<Types...>> {
-
- static std::string convert( const std::tuple<Types...>& tuple )
- {
- std::ostringstream os;
- os << '{';
- TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
- os << " }";
- return os.str();
- }
-};
-#endif // CATCH_CONFIG_CPP11_TUPLE
-
-namespace Detail {
- template<typename T>
- std::string makeString( T const& value ) {
- return StringMaker<T>::convert( value );
- }
-} // end namespace Detail
-
-/// \brief converts any type to a string
-///
-/// The default template forwards on to ostringstream - except when an
-/// ostringstream overload does not exist - in which case it attempts to detect
-/// that and writes {?}.
-/// Overload (not specialise) this template for custom typs that you don't want
-/// to provide an ostream overload for.
-template<typename T>
-std::string toString( T const& value ) {
- return StringMaker<T>::convert( value );
-}
-
- namespace Detail {
- template<typename InputIterator>
- std::string rangeToString( InputIterator first, InputIterator last ) {
- std::ostringstream oss;
- oss << "{ ";
- if( first != last ) {
- oss << Catch::toString( *first );
- for( ++first ; first != last ; ++first )
- oss << ", " << Catch::toString( *first );
- }
- oss << " }";
- return oss.str();
- }
-}
-
-} // end namespace Catch
-
-namespace Catch {
-
-// Wraps the LHS of an expression and captures the operator and RHS (if any) -
-// wrapping them all in a ResultBuilder object
-template<typename T>
-class ExpressionLhs {
- ExpressionLhs& operator = ( ExpressionLhs const& );
-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
- ExpressionLhs& operator = ( ExpressionLhs && ) = delete;
-# endif
-
-public:
- ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
- ExpressionLhs( ExpressionLhs const& ) = default;
- ExpressionLhs( ExpressionLhs && ) = default;
-# endif
-
- template<typename RhsT>
- ResultBuilder& operator == ( RhsT const& rhs ) {
- return captureExpression<Internal::IsEqualTo>( rhs );
- }
-
- template<typename RhsT>
- ResultBuilder& operator != ( RhsT const& rhs ) {
- return captureExpression<Internal::IsNotEqualTo>( rhs );
- }
-
- template<typename RhsT>
- ResultBuilder& operator < ( RhsT const& rhs ) {
- return captureExpression<Internal::IsLessThan>( rhs );
- }
-
- template<typename RhsT>
- ResultBuilder& operator > ( RhsT const& rhs ) {
- return captureExpression<Internal::IsGreaterThan>( rhs );
- }
-
- template<typename RhsT>
- ResultBuilder& operator <= ( RhsT const& rhs ) {
- return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
- }
-
- template<typename RhsT>
- ResultBuilder& operator >= ( RhsT const& rhs ) {
- return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
- }
-
- ResultBuilder& operator == ( bool rhs ) {
- return captureExpression<Internal::IsEqualTo>( rhs );
- }
-
- ResultBuilder& operator != ( bool rhs ) {
- return captureExpression<Internal::IsNotEqualTo>( rhs );
- }
-
- void endExpression() {
- bool value = m_lhs ? true : false;
- m_rb
- .setLhs( Catch::toString( value ) )
- .setResultType( value )
- .endExpression();
- }
-
- // Only simple binary expressions are allowed on the LHS.
- // If more complex compositions are required then place the sub expression in parentheses
- template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
- template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
- template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
- template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
- template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
- template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
-
-private:
- template<Internal::Operator Op, typename RhsT>
- ResultBuilder& captureExpression( RhsT const& rhs ) {
- return m_rb
- .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
- .setLhs( Catch::toString( m_lhs ) )
- .setRhs( Catch::toString( rhs ) )
- .setOp( Internal::OperatorTraits<Op>::getName() );
- }
-
-private:
- ResultBuilder& m_rb;
- T m_lhs;
-};
-
-} // end namespace Catch
-
-
-namespace Catch {
-
- template<typename T>
- inline ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
- return ExpressionLhs<T const&>( *this, operand );
- }
-
- inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {
- return ExpressionLhs<bool>( *this, value );
- }
-
-} // namespace Catch
-
-// #included from: catch_message.h
-#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
-
-#include <string>
-
-namespace Catch {
-
- struct MessageInfo {
- MessageInfo( std::string const& _macroName,
- SourceLineInfo const& _lineInfo,
- ResultWas::OfType _type );
-
- std::string macroName;
- SourceLineInfo lineInfo;
- ResultWas::OfType type;
- std::string message;
- unsigned int sequence;
-
- bool operator == ( MessageInfo const& other ) const {
- return sequence == other.sequence;
- }
- bool operator < ( MessageInfo const& other ) const {
- return sequence < other.sequence;
- }
- private:
- static unsigned int globalCount;
- };
-
- struct MessageBuilder {
- MessageBuilder( std::string const& macroName,
- SourceLineInfo const& lineInfo,
- ResultWas::OfType type )
- : m_info( macroName, lineInfo, type )
- {}
-
- template<typename T>
- MessageBuilder& operator << ( T const& value ) {
- m_stream << value;
- return *this;
- }
-
- MessageInfo m_info;
- std::ostringstream m_stream;
- };
-
- class ScopedMessage {
- public:
- ScopedMessage( MessageBuilder const& builder );
- ScopedMessage( ScopedMessage const& other );
- ~ScopedMessage();
-
- MessageInfo m_info;
- };
-
-} // end namespace Catch
-
-// #included from: catch_interfaces_capture.h
-#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
-
-#include <string>
-
-namespace Catch {
-
- class TestCase;
- class AssertionResult;
- struct AssertionInfo;
- struct SectionInfo;
- struct MessageInfo;
- class ScopedMessageBuilder;
- struct Counts;
-
- struct IResultCapture {
-
- virtual ~IResultCapture();
-
- virtual void assertionEnded( AssertionResult const& result ) = 0;
- virtual bool sectionStarted( SectionInfo const& sectionInfo,
- Counts& assertions ) = 0;
- virtual void sectionEnded( SectionInfo const& name, Counts const& assertions, double _durationInSeconds ) = 0;
- virtual void pushScopedMessage( MessageInfo const& message ) = 0;
- virtual void popScopedMessage( MessageInfo const& message ) = 0;
-
- virtual std::string getCurrentTestName() const = 0;
- virtual const AssertionResult* getLastResult() const = 0;
-
- virtual void handleFatalErrorCondition( std::string const& message ) = 0;
- };
-
- IResultCapture& getResultCapture();
-}
-
-// #included from: catch_debugger.h
-#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
-
-// #included from: catch_platform.h
-#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
-
-#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
-#define CATCH_PLATFORM_MAC
-#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
-#define CATCH_PLATFORM_IPHONE
-#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
-#define CATCH_PLATFORM_WINDOWS
-#endif
-
-#include <string>
-
-namespace Catch{
-
- bool isDebuggerActive();
- void writeToDebugConsole( std::string const& text );
-}
-
-#ifdef CATCH_PLATFORM_MAC
-
- // The following code snippet based on:
- // http://cocoawithlove.com/2008/03/break-into-debugger.html
- #ifdef DEBUG
- #if defined(__ppc64__) || defined(__ppc__)
- #define CATCH_BREAK_INTO_DEBUGGER() \
- if( Catch::isDebuggerActive() ) { \
- __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
- : : : "memory","r0","r3","r4" ); \
- }
- #else
- #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
- #endif
- #endif
-
-#elif defined(_MSC_VER)
- #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
-#elif defined(__MINGW32__)
- extern "C" __declspec(dllimport) void __stdcall DebugBreak();
- #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
-#endif
-
-#ifndef CATCH_BREAK_INTO_DEBUGGER
-#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
-#endif
-
-// #included from: catch_interfaces_runner.h
-#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
-
-namespace Catch {
- class TestCase;
-
- struct IRunner {
- virtual ~IRunner();
- virtual bool aborting() const = 0;
- };
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// In the event of a failure works out if the debugger needs to be invoked
-// and/or an exception thrown and takes appropriate action.
-// This needs to be done as a macro so the debugger will stop in the user
-// source code rather than in Catch library code
-#define INTERNAL_CATCH_REACT( resultBuilder ) \
- if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
- resultBuilder.react();
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
- do { \
- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
- try { \
- ( __catchResult <= expr ).endExpression(); \
- } \
- catch( ... ) { \
- __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
- } \
- INTERNAL_CATCH_REACT( __catchResult ) \
- } while( Catch::isTrue( false && (expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
- INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
- if( Catch::getResultCapture().getLastResult()->succeeded() )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
- INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
- if( !Catch::getResultCapture().getLastResult()->succeeded() )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
- do { \
- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
- try { \
- expr; \
- __catchResult.captureResult( Catch::ResultWas::Ok ); \
- } \
- catch( ... ) { \
- __catchResult.useActiveException( resultDisposition ); \
- } \
- INTERNAL_CATCH_REACT( __catchResult ) \
- } while( Catch::alwaysFalse() )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_THROWS( expr, resultDisposition, macroName ) \
- do { \
- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
- if( __catchResult.allowThrows() ) \
- try { \
- expr; \
- __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
- } \
- catch( ... ) { \
- __catchResult.captureResult( Catch::ResultWas::Ok ); \
- } \
- else \
- __catchResult.captureResult( Catch::ResultWas::Ok ); \
- INTERNAL_CATCH_REACT( __catchResult ) \
- } while( Catch::alwaysFalse() )
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
- do { \
- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
- if( __catchResult.allowThrows() ) \
- try { \
- expr; \
- __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
- } \
- catch( exceptionType ) { \
- __catchResult.captureResult( Catch::ResultWas::Ok ); \
- } \
- catch( ... ) { \
- __catchResult.useActiveException( resultDisposition ); \
- } \
- else \
- __catchResult.captureResult( Catch::ResultWas::Ok ); \
- INTERNAL_CATCH_REACT( __catchResult ) \
- } while( Catch::alwaysFalse() )
-
-///////////////////////////////////////////////////////////////////////////////
-#ifdef CATCH_CONFIG_VARIADIC_MACROS
- #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
- do { \
- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
- __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
- __catchResult.captureResult( messageType ); \
- INTERNAL_CATCH_REACT( __catchResult ) \
- } while( Catch::alwaysFalse() )
-#else
- #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
- do { \
- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
- __catchResult << log + ::Catch::StreamEndStop(); \
- __catchResult.captureResult( messageType ); \
- INTERNAL_CATCH_REACT( __catchResult ) \
- } while( Catch::alwaysFalse() )
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_INFO( log, macroName ) \
- Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
- do { \
- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg " " #matcher, resultDisposition ); \
- try { \
- std::string matcherAsString = ::Catch::Matchers::matcher.toString(); \
- __catchResult \
- .setLhs( Catch::toString( arg ) ) \
- .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
- .setOp( "matches" ) \
- .setResultType( ::Catch::Matchers::matcher.match( arg ) ); \
- __catchResult.captureExpression(); \
- } catch( ... ) { \
- __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
- } \
- INTERNAL_CATCH_REACT( __catchResult ) \
- } while( Catch::alwaysFalse() )
-
-// #included from: internal/catch_section.h
-#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
-
-// #included from: catch_section_info.h
-#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
-
-namespace Catch {
-
- struct SectionInfo {
- SectionInfo
- ( SourceLineInfo const& _lineInfo,
- std::string const& _name,
- std::string const& _description = std::string() );
-
- std::string name;
- std::string description;
- SourceLineInfo lineInfo;
- };
-
-} // end namespace Catch
-
-// #included from: catch_totals.hpp
-#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
-
-#include <cstddef>
-
-namespace Catch {
-
- struct Counts {
- Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
-
- Counts operator - ( Counts const& other ) const {
- Counts diff;
- diff.passed = passed - other.passed;
- diff.failed = failed - other.failed;
- diff.failedButOk = failedButOk - other.failedButOk;
- return diff;
- }
- Counts& operator += ( Counts const& other ) {
- passed += other.passed;
- failed += other.failed;
- failedButOk += other.failedButOk;
- return *this;
- }
-
- std::size_t total() const {
- return passed + failed + failedButOk;
- }
- bool allPassed() const {
- return failed == 0 && failedButOk == 0;
- }
- bool allOk() const {
- return failed == 0;
- }
-
- std::size_t passed;
- std::size_t failed;
- std::size_t failedButOk;
- };
-
- struct Totals {
-
- Totals operator - ( Totals const& other ) const {
- Totals diff;
- diff.assertions = assertions - other.assertions;
- diff.testCases = testCases - other.testCases;
- return diff;
- }
-
- Totals delta( Totals const& prevTotals ) const {
- Totals diff = *this - prevTotals;
- if( diff.assertions.failed > 0 )
- ++diff.testCases.failed;
- else if( diff.assertions.failedButOk > 0 )
- ++diff.testCases.failedButOk;
- else
- ++diff.testCases.passed;
- return diff;
- }
-
- Totals& operator += ( Totals const& other ) {
- assertions += other.assertions;
- testCases += other.testCases;
- return *this;
- }
-
- Counts assertions;
- Counts testCases;
- };
-}
-
-// #included from: catch_timer.h
-#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
-
-#ifdef CATCH_PLATFORM_WINDOWS
-typedef unsigned long long uint64_t;
-#else
-#include <stdint.h>
-#endif
-
-namespace Catch {
-
- class Timer {
- public:
- Timer() : m_ticks( 0 ) {}
- void start();
- unsigned int getElapsedMicroseconds() const;
- unsigned int getElapsedMilliseconds() const;
- double getElapsedSeconds() const;
-
- private:
- uint64_t m_ticks;
- };
-
-} // namespace Catch
-
-#include <string>
-
-namespace Catch {
-
- class Section : NonCopyable {
- public:
- Section( SectionInfo const& info );
- ~Section();
-
- // This indicates whether the section should be executed or not
- operator bool() const;
-
- private:
- SectionInfo m_info;
-
- std::string m_name;
- Counts m_assertions;
- bool m_sectionIncluded;
- Timer m_timer;
- };
-
-} // end namespace Catch
-
-#ifdef CATCH_CONFIG_VARIADIC_MACROS
- #define INTERNAL_CATCH_SECTION( ... ) \
- if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
-#else
- #define INTERNAL_CATCH_SECTION( name, desc ) \
- if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
-#endif
-
-// #included from: internal/catch_generators.hpp
-#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
-
-#include <iterator>
-#include <vector>
-#include <string>
-#include <stdlib.h>
-
-namespace Catch {
-
-template<typename T>
-struct IGenerator {
- virtual ~IGenerator() {}
- virtual T getValue( std::size_t index ) const = 0;
- virtual std::size_t size () const = 0;
-};
-
-template<typename T>
-class BetweenGenerator : public IGenerator<T> {
-public:
- BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
-
- virtual T getValue( std::size_t index ) const {
- return m_from+static_cast<int>( index );
- }
-
- virtual std::size_t size() const {
- return static_cast<std::size_t>( 1+m_to-m_from );
- }
-
-private:
-
- T m_from;
- T m_to;
-};
-
-template<typename T>
-class ValuesGenerator : public IGenerator<T> {
-public:
- ValuesGenerator(){}
-
- void add( T value ) {
- m_values.push_back( value );
- }
-
- virtual T getValue( std::size_t index ) const {
- return m_values[index];
- }
-
- virtual std::size_t size() const {
- return m_values.size();
- }
-
-private:
- std::vector<T> m_values;
-};
-
-template<typename T>
-class CompositeGenerator {
-public:
- CompositeGenerator() : m_totalSize( 0 ) {}
-
- // *** Move semantics, similar to auto_ptr ***
- CompositeGenerator( CompositeGenerator& other )
- : m_fileInfo( other.m_fileInfo ),
- m_totalSize( 0 )
- {
- move( other );
- }
-
- CompositeGenerator& setFileInfo( const char* fileInfo ) {
- m_fileInfo = fileInfo;
- return *this;
- }
-
- ~CompositeGenerator() {
- deleteAll( m_composed );
- }
-
- operator T () const {
- size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
-
- typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
- typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
- for( size_t index = 0; it != itEnd; ++it )
- {
- const IGenerator<T>* generator = *it;
- if( overallIndex >= index && overallIndex < index + generator->size() )
- {
- return generator->getValue( overallIndex-index );
- }
- index += generator->size();
- }
- CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
- return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so
- }
-
- void add( const IGenerator<T>* generator ) {
- m_totalSize += generator->size();
- m_composed.push_back( generator );
- }
-
- CompositeGenerator& then( CompositeGenerator& other ) {
- move( other );
- return *this;
- }
-
- CompositeGenerator& then( T value ) {
- ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
- valuesGen->add( value );
- add( valuesGen );
- return *this;
- }
-
-private:
-
- void move( CompositeGenerator& other ) {
- std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
- m_totalSize += other.m_totalSize;
- other.m_composed.clear();
- }
-
- std::vector<const IGenerator<T>*> m_composed;
- std::string m_fileInfo;
- size_t m_totalSize;
-};
-
-namespace Generators
-{
- template<typename T>
- CompositeGenerator<T> between( T from, T to ) {
- CompositeGenerator<T> generators;
- generators.add( new BetweenGenerator<T>( from, to ) );
- return generators;
- }
-
- template<typename T>
- CompositeGenerator<T> values( T val1, T val2 ) {
- CompositeGenerator<T> generators;
- ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
- valuesGen->add( val1 );
- valuesGen->add( val2 );
- generators.add( valuesGen );
- return generators;
- }
-
- template<typename T>
- CompositeGenerator<T> values( T val1, T val2, T val3 ){
- CompositeGenerator<T> generators;
- ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
- valuesGen->add( val1 );
- valuesGen->add( val2 );
- valuesGen->add( val3 );
- generators.add( valuesGen );
- return generators;
- }
-
- template<typename T>
- CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
- CompositeGenerator<T> generators;
- ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
- valuesGen->add( val1 );
- valuesGen->add( val2 );
- valuesGen->add( val3 );
- valuesGen->add( val4 );
- generators.add( valuesGen );
- return generators;
- }
-
-} // end namespace Generators
-
-using namespace Generators;
-
-} // end namespace Catch
-
-#define INTERNAL_CATCH_LINESTR2( line ) #line
-#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
-
-#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
-
-// #included from: internal/catch_interfaces_exception.h
-#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
-
-#include <string>
-// #included from: catch_interfaces_registry_hub.h
-#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
-
-#include <string>
-
-namespace Catch {
-
- class TestCase;
- struct ITestCaseRegistry;
- struct IExceptionTranslatorRegistry;
- struct IExceptionTranslator;
- struct IReporterRegistry;
- struct IReporterFactory;
-
- struct IRegistryHub {
- virtual ~IRegistryHub();
-
- virtual IReporterRegistry const& getReporterRegistry() const = 0;
- virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
- virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
- };
-
- struct IMutableRegistryHub {
- virtual ~IMutableRegistryHub();
- virtual void registerReporter( std::string const& name, IReporterFactory* factory ) = 0;
- virtual void registerTest( TestCase const& testInfo ) = 0;
- virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
- };
-
- IRegistryHub& getRegistryHub();
- IMutableRegistryHub& getMutableRegistryHub();
- void cleanUp();
- std::string translateActiveException();
-
-}
-
-
-namespace Catch {
-
- typedef std::string(*exceptionTranslateFunction)();
-
- struct IExceptionTranslator {
- virtual ~IExceptionTranslator();
- virtual std::string translate() const = 0;
- };
-
- struct IExceptionTranslatorRegistry {
- virtual ~IExceptionTranslatorRegistry();
-
- virtual std::string translateActiveException() const = 0;
- };
-
- class ExceptionTranslatorRegistrar {
- template<typename T>
- class ExceptionTranslator : public IExceptionTranslator {
- public:
-
- ExceptionTranslator( std::string(*translateFunction)( T& ) )
- : m_translateFunction( translateFunction )
- {}
-
- virtual std::string translate() const {
- try {
- throw;
- }
- catch( T& ex ) {
- return m_translateFunction( ex );
- }
- }
-
- protected:
- std::string(*m_translateFunction)( T& );
- };
-
- public:
- template<typename T>
- ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
- getMutableRegistryHub().registerTranslator
- ( new ExceptionTranslator<T>( translateFunction ) );
- }
- };
-}
-
-///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \
- static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \
- namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\
- static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature )
-
-// #included from: internal/catch_approx.hpp
-#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
-
-#include <cmath>
-#include <limits>
-
-namespace Catch {
-namespace Detail {
-
- class Approx {
- public:
- explicit Approx ( double value )
- : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
- m_scale( 1.0 ),
- m_value( value )
- {}
-
- Approx( Approx const& other )
- : m_epsilon( other.m_epsilon ),
- m_scale( other.m_scale ),
- m_value( other.m_value )
- {}
-
- static Approx custom() {
- return Approx( 0 );
- }
-
- Approx operator()( double value ) {
- Approx approx( value );
- approx.epsilon( m_epsilon );
- approx.scale( m_scale );
- return approx;
- }
-
- friend bool operator == ( double lhs, Approx const& rhs ) {
- // Thanks to Richard Harris for his help refining this formula
- return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
- }
-
- friend bool operator == ( Approx const& lhs, double rhs ) {
- return operator==( rhs, lhs );
- }
-
- friend bool operator != ( double lhs, Approx const& rhs ) {
- return !operator==( lhs, rhs );
- }
-
- friend bool operator != ( Approx const& lhs, double rhs ) {
- return !operator==( rhs, lhs );
- }
-
- Approx& epsilon( double newEpsilon ) {
- m_epsilon = newEpsilon;
- return *this;
- }
-
- Approx& scale( double newScale ) {
- m_scale = newScale;
- return *this;
- }
-
- std::string toString() const {
- std::ostringstream oss;
- oss << "Approx( " << Catch::toString( m_value ) << " )";
- return oss.str();
- }
-
- private:
- double m_epsilon;
- double m_scale;
- double m_value;
- };
-}
-
-template<>
-inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
- return value.toString();
-}
-
-} // end namespace Catch
-
-// #included from: internal/catch_matchers.hpp
-#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
-
-namespace Catch {
-namespace Matchers {
- namespace Impl {
-
- template<typename ExpressionT>
- struct Matcher : SharedImpl<IShared>
- {
- typedef ExpressionT ExpressionType;
-
- virtual ~Matcher() {}
- virtual Ptr<Matcher> clone() const = 0;
- virtual bool match( ExpressionT const& expr ) const = 0;
- virtual std::string toString() const = 0;
- };
-
- template<typename DerivedT, typename ExpressionT>
- struct MatcherImpl : Matcher<ExpressionT> {
-
- virtual Ptr<Matcher<ExpressionT> > clone() const {
- return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
- }
- };
-
- namespace Generic {
-
- template<typename ExpressionT>
- class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
- public:
-
- AllOf() {}
- AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
-
- AllOf& add( Matcher<ExpressionT> const& matcher ) {
- m_matchers.push_back( matcher.clone() );
- return *this;
- }
- virtual bool match( ExpressionT const& expr ) const
- {
- for( std::size_t i = 0; i < m_matchers.size(); ++i )
- if( !m_matchers[i]->match( expr ) )
- return false;
- return true;
- }
- virtual std::string toString() const {
- std::ostringstream oss;
- oss << "( ";
- for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
- if( i != 0 )
- oss << " and ";
- oss << m_matchers[i]->toString();
- }
- oss << " )";
- return oss.str();
- }
-
- private:
- std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
- };
-
- template<typename ExpressionT>
- class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
- public:
-
- AnyOf() {}
- AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
-
- AnyOf& add( Matcher<ExpressionT> const& matcher ) {
- m_matchers.push_back( matcher.clone() );
- return *this;
- }
- virtual bool match( ExpressionT const& expr ) const
- {
- for( std::size_t i = 0; i < m_matchers.size(); ++i )
- if( m_matchers[i]->match( expr ) )
- return true;
- return false;
- }
- virtual std::string toString() const {
- std::ostringstream oss;
- oss << "( ";
- for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
- if( i != 0 )
- oss << " or ";
- oss << m_matchers[i]->toString();
- }
- oss << " )";
- return oss.str();
- }
-
- private:
- std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
- };
-
- }
-
- namespace StdString {
-
- inline std::string makeString( std::string const& str ) { return str; }
- inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
-
- struct Equals : MatcherImpl<Equals, std::string> {
- Equals( std::string const& str ) : m_str( str ){}
- Equals( Equals const& other ) : m_str( other.m_str ){}
-
- virtual ~Equals();
-
- virtual bool match( std::string const& expr ) const {
- return m_str == expr;
- }
- virtual std::string toString() const {
- return "equals: \"" + m_str + "\"";
- }
-
- std::string m_str;
- };
-
- struct Contains : MatcherImpl<Contains, std::string> {
- Contains( std::string const& substr ) : m_substr( substr ){}
- Contains( Contains const& other ) : m_substr( other.m_substr ){}
-
- virtual ~Contains();
-
- virtual bool match( std::string const& expr ) const {
- return expr.find( m_substr ) != std::string::npos;
- }
- virtual std::string toString() const {
- return "contains: \"" + m_substr + "\"";
- }
-
- std::string m_substr;
- };
-
- struct StartsWith : MatcherImpl<StartsWith, std::string> {
- StartsWith( std::string const& substr ) : m_substr( substr ){}
- StartsWith( StartsWith const& other ) : m_substr( other.m_substr ){}
-
- virtual ~StartsWith();
-
- virtual bool match( std::string const& expr ) const {
- return expr.find( m_substr ) == 0;
- }
- virtual std::string toString() const {
- return "starts with: \"" + m_substr + "\"";
- }
-
- std::string m_substr;
- };
-
- struct EndsWith : MatcherImpl<EndsWith, std::string> {
- EndsWith( std::string const& substr ) : m_substr( substr ){}
- EndsWith( EndsWith const& other ) : m_substr( other.m_substr ){}
-
- virtual ~EndsWith();
-
- virtual bool match( std::string const& expr ) const {
- return expr.find( m_substr ) == expr.size() - m_substr.size();
- }
- virtual std::string toString() const {
- return "ends with: \"" + m_substr + "\"";
- }
-
- std::string m_substr;
- };
- } // namespace StdString
- } // namespace Impl
-
- // The following functions create the actual matcher objects.
- // This allows the types to be inferred
- template<typename ExpressionT>
- inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
- Impl::Matcher<ExpressionT> const& m2 ) {
- return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
- }
- template<typename ExpressionT>
- inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
- Impl::Matcher<ExpressionT> const& m2,
- Impl::Matcher<ExpressionT> const& m3 ) {
- return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
- }
- template<typename ExpressionT>
- inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
- Impl::Matcher<ExpressionT> const& m2 ) {
- return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
- }
- template<typename ExpressionT>
- inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
- Impl::Matcher<ExpressionT> const& m2,
- Impl::Matcher<ExpressionT> const& m3 ) {
- return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
- }
-
- inline Impl::StdString::Equals Equals( std::string const& str ) {
- return Impl::StdString::Equals( str );
- }
- inline Impl::StdString::Equals Equals( const char* str ) {
- return Impl::StdString::Equals( Impl::StdString::makeString( str ) );
- }
- inline Impl::StdString::Contains Contains( std::string const& substr ) {
- return Impl::StdString::Contains( substr );
- }
- inline Impl::StdString::Contains Contains( const char* substr ) {
- return Impl::StdString::Contains( Impl::StdString::makeString( substr ) );
- }
- inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) {
- return Impl::StdString::StartsWith( substr );
- }
- inline Impl::StdString::StartsWith StartsWith( const char* substr ) {
- return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );
- }
- inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) {
- return Impl::StdString::EndsWith( substr );
- }
- inline Impl::StdString::EndsWith EndsWith( const char* substr ) {
- return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );
- }
-
-} // namespace Matchers
-
-using namespace Matchers;
-
-} // namespace Catch
-
-// #included from: internal/catch_interfaces_tag_alias_registry.h
-#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
-
-// #included from: catch_tag_alias.h
-#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
-
-#include <string>
-
-namespace Catch {
-
- struct TagAlias {
- TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
-
- std::string tag;
- SourceLineInfo lineInfo;
- };
-
- struct RegistrarForTagAliases {
- RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
- };
-
-} // end namespace Catch
-
-#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
-// #included from: catch_option.hpp
-#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
-
-namespace Catch {
-
- // An optional type
- template<typename T>
- class Option {
- public:
- Option() : nullableValue( NULL ) {}
- Option( T const& _value )
- : nullableValue( new( storage ) T( _value ) )
- {}
- Option( Option const& _other )
- : nullableValue( _other ? new( storage ) T( *_other ) : NULL )
- {}
-
- ~Option() {
- reset();
- }
-
- Option& operator= ( Option const& _other ) {
- if( &_other != this ) {
- reset();
- if( _other )
- nullableValue = new( storage ) T( *_other );
- }
- return *this;
- }
- Option& operator = ( T const& _value ) {
- reset();
- nullableValue = new( storage ) T( _value );
- return *this;
- }
-
- void reset() {
- if( nullableValue )
- nullableValue->~T();
- nullableValue = NULL;
- }
-
- T& operator*() { return *nullableValue; }
- T const& operator*() const { return *nullableValue; }
- T* operator->() { return nullableValue; }
- const T* operator->() const { return nullableValue; }
-
- T valueOr( T const& defaultValue ) const {
- return nullableValue ? *nullableValue : defaultValue;
- }
-
- bool some() const { return nullableValue != NULL; }
- bool none() const { return nullableValue == NULL; }
-
- bool operator !() const { return nullableValue == NULL; }
- operator SafeBool::type() const {
- return SafeBool::makeSafe( some() );
- }
-
- private:
- T* nullableValue;
- char storage[sizeof(T)];
- };
-
-} // end namespace Catch
-
-namespace Catch {
-
- struct ITagAliasRegistry {
- virtual ~ITagAliasRegistry();
- virtual Option<TagAlias> find( std::string const& alias ) const = 0;
- virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
-
- static ITagAliasRegistry const& get();
- };
-
-} // end namespace Catch
-
-// These files are included here so the single_include script doesn't put them
-// in the conditionally compiled sections
-// #included from: internal/catch_test_case_info.h
-#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
-
-#include <string>
-#include <set>
-
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wpadded"
-#endif
-
-namespace Catch {
-
- struct ITestCase;
-
- struct TestCaseInfo {
- enum SpecialProperties{
- None = 0,
- IsHidden = 1 << 1,
- ShouldFail = 1 << 2,
- MayFail = 1 << 3,
- Throws = 1 << 4
- };
-
- TestCaseInfo( std::string const& _name,
- std::string const& _className,
- std::string const& _description,
- std::set<std::string> const& _tags,
- SourceLineInfo const& _lineInfo );
-
- TestCaseInfo( TestCaseInfo const& other );
-
- bool isHidden() const;
- bool throws() const;
- bool okToFail() const;
- bool expectedToFail() const;
-
- std::string name;
- std::string className;
- std::string description;
- std::set<std::string> tags;
- std::set<std::string> lcaseTags;
- std::string tagsAsString;
- SourceLineInfo lineInfo;
- SpecialProperties properties;
- };
-
- class TestCase : public TestCaseInfo {
- public:
-
- TestCase( ITestCase* testCase, TestCaseInfo const& info );
- TestCase( TestCase const& other );
-
- TestCase withName( std::string const& _newName ) const;
-
- void invoke() const;
-
- TestCaseInfo const& getTestCaseInfo() const;
-
- void swap( TestCase& other );
- bool operator == ( TestCase const& other ) const;
- bool operator < ( TestCase const& other ) const;
- TestCase& operator = ( TestCase const& other );
-
- private:
- Ptr<ITestCase> test;
- };
-
- TestCase makeTestCase( ITestCase* testCase,
- std::string const& className,
- std::string const& name,
- std::string const& description,
- SourceLineInfo const& lineInfo );
-}
-
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
-
-
-#ifdef __OBJC__
-// #included from: internal/catch_objc.hpp
-#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
-
-#import <objc/runtime.h>
-
-#include <string>
-
-// NB. Any general catch headers included here must be included
-// in catch.hpp first to make sure they are included by the single
-// header for non obj-usage
-
-///////////////////////////////////////////////////////////////////////////////
-// This protocol is really only here for (self) documenting purposes, since
-// all its methods are optional.
-@protocol OcFixture
-
-@optional
-
--(void) setUp;
--(void) tearDown;
-
-@end
-
-namespace Catch {
-
- class OcMethod : public SharedImpl<ITestCase> {
-
- public:
- OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
-
- virtual void invoke() const {
- id obj = [[m_cls alloc] init];
-
- performOptionalSelector( obj, @selector(setUp) );
- performOptionalSelector( obj, m_sel );
- performOptionalSelector( obj, @selector(tearDown) );
-
- arcSafeRelease( obj );
- }
- private:
- virtual ~OcMethod() {}
-
- Class m_cls;
- SEL m_sel;
- };
-
- namespace Detail{
-
- inline std::string getAnnotation( Class cls,
- std::string const& annotationName,
- std::string const& testCaseName ) {
- NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
- SEL sel = NSSelectorFromString( selStr );
- arcSafeRelease( selStr );
- id value = performOptionalSelector( cls, sel );
- if( value )
- return [(NSString*)value UTF8String];
- return "";
- }
- }
-
- inline size_t registerTestMethods() {
- size_t noTestMethods = 0;
- int noClasses = objc_getClassList( NULL, 0 );
-
- Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
- objc_getClassList( classes, noClasses );
-
- for( int c = 0; c < noClasses; c++ ) {
- Class cls = classes[c];
- {
- u_int count;
- Method* methods = class_copyMethodList( cls, &count );
- for( u_int m = 0; m < count ; m++ ) {
- SEL selector = method_getName(methods[m]);
- std::string methodName = sel_getName(selector);
- if( startsWith( methodName, "Catch_TestCase_" ) ) {
- std::string testCaseName = methodName.substr( 15 );
- std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
- std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
- const char* className = class_getName( cls );
-
- getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
- noTestMethods++;
- }
- }
- free(methods);
- }
- }
- return noTestMethods;
- }
-
- namespace Matchers {
- namespace Impl {
- namespace NSStringMatchers {
-
- template<typename MatcherT>
- struct StringHolder : MatcherImpl<MatcherT, NSString*>{
- StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
- StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
- StringHolder() {
- arcSafeRelease( m_substr );
- }
-
- NSString* m_substr;
- };
-
- struct Equals : StringHolder<Equals> {
- Equals( NSString* substr ) : StringHolder( substr ){}
-
- virtual bool match( ExpressionType const& str ) const {
- return (str != nil || m_substr == nil ) &&
- [str isEqualToString:m_substr];
- }
-
- virtual std::string toString() const {
- return "equals string: " + Catch::toString( m_substr );
- }
- };
-
- struct Contains : StringHolder<Contains> {
- Contains( NSString* substr ) : StringHolder( substr ){}
-
- virtual bool match( ExpressionType const& str ) const {
- return (str != nil || m_substr == nil ) &&
- [str rangeOfString:m_substr].location != NSNotFound;
- }
-
- virtual std::string toString() const {
- return "contains string: " + Catch::toString( m_substr );
- }
- };
-
- struct StartsWith : StringHolder<StartsWith> {
- StartsWith( NSString* substr ) : StringHolder( substr ){}
-
- virtual bool match( ExpressionType const& str ) const {
- return (str != nil || m_substr == nil ) &&
- [str rangeOfString:m_substr].location == 0;
- }
-
- virtual std::string toString() const {
- return "starts with: " + Catch::toString( m_substr );
- }
- };
- struct EndsWith : StringHolder<EndsWith> {
- EndsWith( NSString* substr ) : StringHolder( substr ){}
-
- virtual bool match( ExpressionType const& str ) const {
- return (str != nil || m_substr == nil ) &&
- [str rangeOfString:m_substr].location == [str length] - [m_substr length];
- }
-
- virtual std::string toString() const {
- return "ends with: " + Catch::toString( m_substr );
- }
- };
-
- } // namespace NSStringMatchers
- } // namespace Impl
-
- inline Impl::NSStringMatchers::Equals
- Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
-
- inline Impl::NSStringMatchers::Contains
- Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
-
- inline Impl::NSStringMatchers::StartsWith
- StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
-
- inline Impl::NSStringMatchers::EndsWith
- EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
-
- } // namespace Matchers
-
- using namespace Matchers;
-
-} // namespace Catch
-
-///////////////////////////////////////////////////////////////////////////////
-#define OC_TEST_CASE( name, desc )\
-+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
-{\
-return @ name; \
-}\
-+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
-{ \
-return @ desc; \
-} \
--(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
-
-#endif
-
-#ifdef CATCH_IMPL
-// #included from: internal/catch_impl.hpp
-#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
-
-// Collect all the implementation files together here
-// These are the equivalent of what would usually be cpp files
-
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wweak-vtables"
-#endif
-
-// #included from: ../catch_runner.hpp
-#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
-
-// #included from: internal/catch_commandline.hpp
-#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
-
-// #included from: catch_config.hpp
-#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
-
-// #included from: catch_test_spec_parser.hpp
-#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
-
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wpadded"
-#endif
-
-// #included from: catch_test_spec.hpp
-#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
-
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wpadded"
-#endif
-
-#include <string>
-#include <vector>
-
-namespace Catch {
-
- class TestSpec {
- struct Pattern : SharedImpl<> {
- virtual ~Pattern();
- virtual bool matches( TestCaseInfo const& testCase ) const = 0;
- };
- class NamePattern : public Pattern {
- enum WildcardPosition {
- NoWildcard = 0,
- WildcardAtStart = 1,
- WildcardAtEnd = 2,
- WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
- };
-
- public:
- NamePattern( std::string const& name ) : m_name( toLower( name ) ), m_wildcard( NoWildcard ) {
- if( startsWith( m_name, "*" ) ) {
- m_name = m_name.substr( 1 );
- m_wildcard = WildcardAtStart;
- }
- if( endsWith( m_name, "*" ) ) {
- m_name = m_name.substr( 0, m_name.size()-1 );
- m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
- }
- }
- virtual ~NamePattern();
- virtual bool matches( TestCaseInfo const& testCase ) const {
- switch( m_wildcard ) {
- case NoWildcard:
- return m_name == toLower( testCase.name );
- case WildcardAtStart:
- return endsWith( toLower( testCase.name ), m_name );
- case WildcardAtEnd:
- return startsWith( toLower( testCase.name ), m_name );
- case WildcardAtBothEnds:
- return contains( toLower( testCase.name ), m_name );
- }
-
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunreachable-code"
-#endif
- throw std::logic_error( "Unknown enum" );
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
- }
- private:
- std::string m_name;
- WildcardPosition m_wildcard;
- };
- class TagPattern : public Pattern {
- public:
- TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
- virtual ~TagPattern();
- virtual bool matches( TestCaseInfo const& testCase ) const {
- return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
- }
- private:
- std::string m_tag;
- };
- class ExcludedPattern : public Pattern {
- public:
- ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
- virtual ~ExcludedPattern();
- virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
- private:
- Ptr<Pattern> m_underlyingPattern;
- };
-
- struct Filter {
- std::vector<Ptr<Pattern> > m_patterns;
-
- bool matches( TestCaseInfo const& testCase ) const {
- // All patterns in a filter must match for the filter to be a match
- for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
- if( !(*it)->matches( testCase ) )
- return false;
- return true;
- }
- };
-
- public:
- bool hasFilters() const {
- return !m_filters.empty();
- }
- bool matches( TestCaseInfo const& testCase ) const {
- // A TestSpec matches if any filter matches
- for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
- if( it->matches( testCase ) )
- return true;
- return false;
- }
-
- private:
- std::vector<Filter> m_filters;
-
- friend class TestSpecParser;
- };
-}
-
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
-
-namespace Catch {
-
- class TestSpecParser {
- enum Mode{ None, Name, QuotedName, Tag };
- Mode m_mode;
- bool m_exclusion;
- std::size_t m_start, m_pos;
- std::string m_arg;
- TestSpec::Filter m_currentFilter;
- TestSpec m_testSpec;
- ITagAliasRegistry const* m_tagAliases;
-
- public:
- TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
-
- TestSpecParser& parse( std::string const& arg ) {
- m_mode = None;
- m_exclusion = false;
- m_start = std::string::npos;
- m_arg = m_tagAliases->expandAliases( arg );
- for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
- visitChar( m_arg[m_pos] );
- if( m_mode == Name )
- addPattern<TestSpec::NamePattern>();
- return *this;
- }
- TestSpec testSpec() {
- addFilter();
- return m_testSpec;
- }
- private:
- void visitChar( char c ) {
- if( m_mode == None ) {
- switch( c ) {
- case ' ': return;
- case '~': m_exclusion = true; return;
- case '[': return startNewMode( Tag, ++m_pos );
- case '"': return startNewMode( QuotedName, ++m_pos );
- default: startNewMode( Name, m_pos ); break;
- }
- }
- if( m_mode == Name ) {
- if( c == ',' ) {
- addPattern<TestSpec::NamePattern>();
- addFilter();
- }
- else if( c == '[' ) {
- if( subString() == "exclude:" )
- m_exclusion = true;
- else
- addPattern<TestSpec::NamePattern>();
- startNewMode( Tag, ++m_pos );
- }
- }
- else if( m_mode == QuotedName && c == '"' )
- addPattern<TestSpec::NamePattern>();
- else if( m_mode == Tag && c == ']' )
- addPattern<TestSpec::TagPattern>();
- }
- void startNewMode( Mode mode, std::size_t start ) {
- m_mode = mode;
- m_start = start;
- }
- std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
- template<typename T>
- void addPattern() {
- std::string token = subString();
- if( startsWith( token, "exclude:" ) ) {
- m_exclusion = true;
- token = token.substr( 8 );
- }
- if( !token.empty() ) {
- Ptr<TestSpec::Pattern> pattern = new T( token );
- if( m_exclusion )
- pattern = new TestSpec::ExcludedPattern( pattern );
- m_currentFilter.m_patterns.push_back( pattern );
- }
- m_exclusion = false;
- m_mode = None;
- }
- void addFilter() {
- if( !m_currentFilter.m_patterns.empty() ) {
- m_testSpec.m_filters.push_back( m_currentFilter );
- m_currentFilter = TestSpec::Filter();
- }
- }
- };
- inline TestSpec parseTestSpec( std::string const& arg ) {
- return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
- }
-
-} // namespace Catch
-
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
-
-// #included from: catch_interfaces_config.h
-#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
-
-#include <iostream>
-#include <string>
-#include <vector>
-
-namespace Catch {
-
- struct Verbosity { enum Level {
- NoOutput = 0,
- Quiet,
- Normal
- }; };
-
- struct WarnAbout { enum What {
- Nothing = 0x00,
- NoAssertions = 0x01
- }; };
-
- struct ShowDurations { enum OrNot {
- DefaultForReporter,
- Always,
- Never
- }; };
- struct RunTests { enum InWhatOrder {
- InDeclarationOrder,
- InLexicographicalOrder,
- InRandomOrder
- }; };
-
- class TestSpec;
-
- struct IConfig : IShared {
-
- virtual ~IConfig();
-
- virtual bool allowThrows() const = 0;
- virtual std::ostream& stream() const = 0;
- virtual std::string name() const = 0;
- virtual bool includeSuccessfulResults() const = 0;
- virtual bool shouldDebugBreak() const = 0;
- virtual bool warnAboutMissingAssertions() const = 0;
- virtual int abortAfter() const = 0;
- virtual bool showInvisibles() const = 0;
- virtual ShowDurations::OrNot showDurations() const = 0;
- virtual TestSpec const& testSpec() const = 0;
- virtual RunTests::InWhatOrder runOrder() const = 0;
- virtual unsigned int rngSeed() const = 0;
- virtual bool forceColour() const = 0;
- };
-}
-
-// #included from: catch_stream.h
-#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
-
-#include <streambuf>
-
-#ifdef __clang__
-#pragma clang diagnostic ignored "-Wpadded"
-#endif
-
-namespace Catch {
-
- class Stream {
- public:
- Stream();
- Stream( std::streambuf* _streamBuf, bool _isOwned );
- void release();
-
- std::streambuf* streamBuf;
-
- private:
- bool isOwned;
- };
-
- std::ostream& cout();
- std::ostream& cerr();
-}
-
-#include <memory>
-#include <vector>
-#include <string>
-#include <iostream>
-#include <ctime>
-
-#ifndef CATCH_CONFIG_CONSOLE_WIDTH
-#define CATCH_CONFIG_CONSOLE_WIDTH 80
-#endif
-
-namespace Catch {
-
- struct ConfigData {
-
- ConfigData()
- : listTests( false ),
- listTags( false ),
- listReporters( false ),
- listTestNamesOnly( false ),
- showSuccessfulTests( false ),
- shouldDebugBreak( false ),
- noThrow( false ),
- showHelp( false ),
- showInvisibles( false ),
- forceColour( false ),
- abortAfter( -1 ),
- rngSeed( 0 ),
- verbosity( Verbosity::Normal ),
- warnings( WarnAbout::Nothing ),
- showDurations( ShowDurations::DefaultForReporter ),
- runOrder( RunTests::InDeclarationOrder )
- {}
-
- bool listTests;
- bool listTags;
- bool listReporters;
- bool listTestNamesOnly;
-
- bool showSuccessfulTests;
- bool shouldDebugBreak;
- bool noThrow;
- bool showHelp;
- bool showInvisibles;
- bool forceColour;
-
- int abortAfter;
- unsigned int rngSeed;
-
- Verbosity::Level verbosity;
- WarnAbout::What warnings;
- ShowDurations::OrNot showDurations;
- RunTests::InWhatOrder runOrder;
-
- std::string reporterName;
- std::string outputFilename;
- std::string name;
- std::string processName;
-
- std::vector<std::string> testsOrTags;
- };
-
- class Config : public SharedImpl<IConfig> {
- private:
- Config( Config const& other );
- Config& operator = ( Config const& other );
- virtual void dummy();
- public:
-
- Config()
- : m_os( Catch::cout().rdbuf() )
- {}
-
- Config( ConfigData const& data )
- : m_data( data ),
- m_os( Catch::cout().rdbuf() )
- {
- if( !data.testsOrTags.empty() ) {
- TestSpecParser parser( ITagAliasRegistry::get() );
- for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
- parser.parse( data.testsOrTags[i] );
- m_testSpec = parser.testSpec();
- }
- }
-
- virtual ~Config() {
- m_os.rdbuf( Catch::cout().rdbuf() );
- m_stream.release();
- }
-
- void setFilename( std::string const& filename ) {
- m_data.outputFilename = filename;
- }
-
- std::string const& getFilename() const {
- return m_data.outputFilename ;
- }
-
- bool listTests() const { return m_data.listTests; }
- bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
- bool listTags() const { return m_data.listTags; }
- bool listReporters() const { return m_data.listReporters; }
-
- std::string getProcessName() const { return m_data.processName; }
-
- bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
-
- void setStreamBuf( std::streambuf* buf ) {
- m_os.rdbuf( buf ? buf : Catch::cout().rdbuf() );
- }
-
- void useStream( std::string const& streamName ) {
- Stream stream = createStream( streamName );
- setStreamBuf( stream.streamBuf );
- m_stream.release();
- m_stream = stream;
- }
-
- std::string getReporterName() const { return m_data.reporterName; }
-
- int abortAfter() const { return m_data.abortAfter; }
-
- TestSpec const& testSpec() const { return m_testSpec; }
-
- bool showHelp() const { return m_data.showHelp; }
- bool showInvisibles() const { return m_data.showInvisibles; }
-
- // IConfig interface
- virtual bool allowThrows() const { return !m_data.noThrow; }
- virtual std::ostream& stream() const { return m_os; }
- virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
- virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
- virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
- virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
- virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; }
- virtual unsigned int rngSeed() const { return m_data.rngSeed; }
- virtual bool forceColour() const { return m_data.forceColour; }
-
- private:
- ConfigData m_data;
-
- Stream m_stream;
- mutable std::ostream m_os;
- TestSpec m_testSpec;
- };
-
-} // end namespace Catch
-
-// #included from: catch_clara.h
-#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
-
-// Use Catch's value for console width (store Clara's off to the side, if present)
-#ifdef CLARA_CONFIG_CONSOLE_WIDTH
-#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
-#undef CLARA_CONFIG_CONSOLE_WIDTH
-#endif
-#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
-
-// Declare Clara inside the Catch namespace
-#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
-// #included from: ../external/clara.h
-
-// Only use header guard if we are not using an outer namespace
-#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
-
-#ifndef STITCH_CLARA_OPEN_NAMESPACE
-#define TWOBLUECUBES_CLARA_H_INCLUDED
-#define STITCH_CLARA_OPEN_NAMESPACE
-#define STITCH_CLARA_CLOSE_NAMESPACE
-#else
-#define STITCH_CLARA_CLOSE_NAMESPACE }
-#endif
-
-#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
-
-// ----------- #included from tbc_text_format.h -----------
-
-// Only use header guard if we are not using an outer namespace
-#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
-#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
-#define TBC_TEXT_FORMAT_H_INCLUDED
-#endif
-
-#include <string>
-#include <vector>
-#include <sstream>
-
-// Use optional outer namespace
-#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
-namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
-#endif
-
-namespace Tbc {
-
-#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
- const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
-#else
- const unsigned int consoleWidth = 80;
-#endif
-
- struct TextAttributes {
- TextAttributes()
- : initialIndent( std::string::npos ),
- indent( 0 ),
- width( consoleWidth-1 ),
- tabChar( '\t' )
- {}
-
- TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
- TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
- TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
- TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
-
- std::size_t initialIndent; // indent of first line, or npos
- std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
- std::size_t width; // maximum width of text, including indent. Longer text will wrap
- char tabChar; // If this char is seen the indent is changed to current pos
- };
-
- class Text {
- public:
- Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
- : attr( _attr )
- {
- std::string wrappableChars = " [({.,/|\\-";
- std::size_t indent = _attr.initialIndent != std::string::npos
- ? _attr.initialIndent
- : _attr.indent;
- std::string remainder = _str;
-
- while( !remainder.empty() ) {
- if( lines.size() >= 1000 ) {
- lines.push_back( "... message truncated due to excessive size" );
- return;
- }
- std::size_t tabPos = std::string::npos;
- std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
- std::size_t pos = remainder.find_first_of( '\n' );
- if( pos <= width ) {
- width = pos;
- }
- pos = remainder.find_last_of( _attr.tabChar, width );
- if( pos != std::string::npos ) {
- tabPos = pos;
- if( remainder[width] == '\n' )
- width--;
- remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
- }
-
- if( width == remainder.size() ) {
- spliceLine( indent, remainder, width );
- }
- else if( remainder[width] == '\n' ) {
- spliceLine( indent, remainder, width );
- if( width <= 1 || remainder.size() != 1 )
- remainder = remainder.substr( 1 );
- indent = _attr.indent;
- }
- else {
- pos = remainder.find_last_of( wrappableChars, width );
- if( pos != std::string::npos && pos > 0 ) {
- spliceLine( indent, remainder, pos );
- if( remainder[0] == ' ' )
- remainder = remainder.substr( 1 );
- }
- else {
- spliceLine( indent, remainder, width-1 );
- lines.back() += "-";
- }
- if( lines.size() == 1 )
- indent = _attr.indent;
- if( tabPos != std::string::npos )
- indent += tabPos;
- }
- }
- }
-
- void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
- lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
- _remainder = _remainder.substr( _pos );
- }
-
- typedef std::vector<std::string>::const_iterator const_iterator;
-
- const_iterator begin() const { return lines.begin(); }
- const_iterator end() const { return lines.end(); }
- std::string const& last() const { return lines.back(); }
- std::size_t size() const { return lines.size(); }
- std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
- std::string toString() const {
- std::ostringstream oss;
- oss << *this;
- return oss.str();
- }
-
- inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
- for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
- it != itEnd; ++it ) {
- if( it != _text.begin() )
- _stream << "\n";
- _stream << *it;
- }
- return _stream;
- }
-
- private:
- std::string str;
- TextAttributes attr;
- std::vector<std::string> lines;
- };
-
-} // end namespace Tbc
-
-#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
-} // end outer namespace
-#endif
-
-#endif // TBC_TEXT_FORMAT_H_INCLUDED
-
-// ----------- end of #include from tbc_text_format.h -----------
-// ........... back in /Users/philnash/Dev/OSS/Clara/srcs/clara.h
-
-#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
-
-#include <map>
-#include <algorithm>
-#include <stdexcept>
-#include <memory>
-
-// Use optional outer namespace
-#ifdef STITCH_CLARA_OPEN_NAMESPACE
-STITCH_CLARA_OPEN_NAMESPACE
-#endif
-
-namespace Clara {
-
- struct UnpositionalTag {};
-
- extern UnpositionalTag _;
-
-#ifdef CLARA_CONFIG_MAIN
- UnpositionalTag _;
-#endif
-
- namespace Detail {
-
-#ifdef CLARA_CONSOLE_WIDTH
- const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
-#else
- const unsigned int consoleWidth = 80;
-#endif
-
- using namespace Tbc;
-
- inline bool startsWith( std::string const& str, std::string const& prefix ) {
- return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
- }
-
- template<typename T> struct RemoveConstRef{ typedef T type; };
- template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
- template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
- template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
-
- template<typename T> struct IsBool { static const bool value = false; };
- template<> struct IsBool<bool> { static const bool value = true; };
-
- template<typename T>
- void convertInto( std::string const& _source, T& _dest ) {
- std::stringstream ss;
- ss << _source;
- ss >> _dest;
- if( ss.fail() )
- throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
- }
- inline void convertInto( std::string const& _source, std::string& _dest ) {
- _dest = _source;
- }
- inline void convertInto( std::string const& _source, bool& _dest ) {
- std::string sourceLC = _source;
- std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
- if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
- _dest = true;
- else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
- _dest = false;
- else
- throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" );
- }
- inline void convertInto( bool _source, bool& _dest ) {
- _dest = _source;
- }
- template<typename T>
- inline void convertInto( bool, T& ) {
- throw std::runtime_error( "Invalid conversion" );
- }
-
- template<typename ConfigT>
- struct IArgFunction {
- virtual ~IArgFunction() {}
-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
- IArgFunction() = default;
- IArgFunction( IArgFunction const& ) = default;
-# endif
- virtual void set( ConfigT& config, std::string const& value ) const = 0;
- virtual void setFlag( ConfigT& config ) const = 0;
- virtual bool takesArg() const = 0;
- virtual IArgFunction* clone() const = 0;
- };
-
- template<typename ConfigT>
- class BoundArgFunction {
- public:
- BoundArgFunction() : functionObj( NULL ) {}
- BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
- BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : NULL ) {}
- BoundArgFunction& operator = ( BoundArgFunction const& other ) {
- IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : NULL;
- delete functionObj;
- functionObj = newFunctionObj;
- return *this;
- }
- ~BoundArgFunction() { delete functionObj; }
-
- void set( ConfigT& config, std::string const& value ) const {
- functionObj->set( config, value );
- }
- void setFlag( ConfigT& config ) const {
- functionObj->setFlag( config );
- }
- bool takesArg() const { return functionObj->takesArg(); }
-
- bool isSet() const {
- return functionObj != NULL;
- }
- private:
- IArgFunction<ConfigT>* functionObj;
- };
-
- template<typename C>
- struct NullBinder : IArgFunction<C>{
- virtual void set( C&, std::string const& ) const {}
- virtual void setFlag( C& ) const {}
- virtual bool takesArg() const { return true; }
- virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
- };
-
- template<typename C, typename M>
- struct BoundDataMember : IArgFunction<C>{
- BoundDataMember( M C::* _member ) : member( _member ) {}
- virtual void set( C& p, std::string const& stringValue ) const {
- convertInto( stringValue, p.*member );
- }
- virtual void setFlag( C& p ) const {
- convertInto( true, p.*member );
- }
- virtual bool takesArg() const { return !IsBool<M>::value; }
- virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
- M C::* member;
- };
- template<typename C, typename M>
- struct BoundUnaryMethod : IArgFunction<C>{
- BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
- virtual void set( C& p, std::string const& stringValue ) const {
- typename RemoveConstRef<M>::type value;
- convertInto( stringValue, value );
- (p.*member)( value );
- }
- virtual void setFlag( C& p ) const {
- typename RemoveConstRef<M>::type value;
- convertInto( true, value );
- (p.*member)( value );
- }
- virtual bool takesArg() const { return !IsBool<M>::value; }
- virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
- void (C::*member)( M );
- };
- template<typename C>
- struct BoundNullaryMethod : IArgFunction<C>{
- BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
- virtual void set( C& p, std::string const& stringValue ) const {
- bool value;
- convertInto( stringValue, value );
- if( value )
- (p.*member)();
- }
- virtual void setFlag( C& p ) const {
- (p.*member)();
- }
- virtual bool takesArg() const { return false; }
- virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
- void (C::*member)();
- };
-
- template<typename C>
- struct BoundUnaryFunction : IArgFunction<C>{
- BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
- virtual void set( C& obj, std::string const& stringValue ) const {
- bool value;
- convertInto( stringValue, value );
- if( value )
- function( obj );
- }
- virtual void setFlag( C& p ) const {
- function( p );
- }
- virtual bool takesArg() const { return false; }
- virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
- void (*function)( C& );
- };
-
- template<typename C, typename T>
- struct BoundBinaryFunction : IArgFunction<C>{
- BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
- virtual void set( C& obj, std::string const& stringValue ) const {
- typename RemoveConstRef<T>::type value;
- convertInto( stringValue, value );
- function( obj, value );
- }
- virtual void setFlag( C& obj ) const {
- typename RemoveConstRef<T>::type value;
- convertInto( true, value );
- function( obj, value );
- }
- virtual bool takesArg() const { return !IsBool<T>::value; }
- virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
- void (*function)( C&, T );
- };
-
- } // namespace Detail
-
- struct Parser {
- Parser() : separators( " \t=:" ) {}
-
- struct Token {
- enum Type { Positional, ShortOpt, LongOpt };
- Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
- Type type;
- std::string data;
- };
-
- void parseIntoTokens( int argc, char const * const * argv, std::vector<Parser::Token>& tokens ) const {
- const std::string doubleDash = "--";
- for( int i = 1; i < argc && argv[i] != doubleDash; ++i )
- parseIntoTokens( argv[i] , tokens);
- }
- void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const {
- while( !arg.empty() ) {
- Parser::Token token( Parser::Token::Positional, arg );
- arg = "";
- if( token.data[0] == '-' ) {
- if( token.data.size() > 1 && token.data[1] == '-' ) {
- token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
- }
- else {
- token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
- if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
- arg = "-" + token.data.substr( 1 );
- token.data = token.data.substr( 0, 1 );
- }
- }
- }
- if( token.type != Parser::Token::Positional ) {
- std::size_t pos = token.data.find_first_of( separators );
- if( pos != std::string::npos ) {
- arg = token.data.substr( pos+1 );
- token.data = token.data.substr( 0, pos );
- }
- }
- tokens.push_back( token );
- }
- }
- std::string separators;
- };
-
- template<typename ConfigT>
- struct CommonArgProperties {
- CommonArgProperties() {}
- CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
-
- Detail::BoundArgFunction<ConfigT> boundField;
- std::string description;
- std::string detail;
- std::string placeholder; // Only value if boundField takes an arg
-
- bool takesArg() const {
- return !placeholder.empty();
- }
- void validate() const {
- if( !boundField.isSet() )
- throw std::logic_error( "option not bound" );
- }
- };
- struct OptionArgProperties {
- std::vector<std::string> shortNames;
- std::string longName;
-
- bool hasShortName( std::string const& shortName ) const {
- return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
- }
- bool hasLongName( std::string const& _longName ) const {
- return _longName == longName;
- }
- };
- struct PositionalArgProperties {
- PositionalArgProperties() : position( -1 ) {}
- int position; // -1 means non-positional (floating)
-
- bool isFixedPositional() const {
- return position != -1;
- }
- };
-
- template<typename ConfigT>
- class CommandLine {
-
- struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
- Arg() {}
- Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
-
- using CommonArgProperties<ConfigT>::placeholder; // !TBD
-
- std::string dbgName() const {
- if( !longName.empty() )
- return "--" + longName;
- if( !shortNames.empty() )
- return "-" + shortNames[0];
- return "positional args";
- }
- std::string commands() const {
- std::ostringstream oss;
- bool first = true;
- std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
- for(; it != itEnd; ++it ) {
- if( first )
- first = false;
- else
- oss << ", ";
- oss << "-" << *it;
- }
- if( !longName.empty() ) {
- if( !first )
- oss << ", ";
- oss << "--" << longName;
- }
- if( !placeholder.empty() )
- oss << " <" << placeholder << ">";
- return oss.str();
- }
- };
-
- // NOTE: std::auto_ptr is deprecated in c++11/c++0x
-#if defined(__cplusplus) && __cplusplus > 199711L
- typedef std::unique_ptr<Arg> ArgAutoPtr;
-#else
- typedef std::auto_ptr<Arg> ArgAutoPtr;
-#endif
-
- friend void addOptName( Arg& arg, std::string const& optName )
- {
- if( optName.empty() )
- return;
- if( Detail::startsWith( optName, "--" ) ) {
- if( !arg.longName.empty() )
- throw std::logic_error( "Only one long opt may be specified. '"
- + arg.longName
- + "' already specified, now attempting to add '"
- + optName + "'" );
- arg.longName = optName.substr( 2 );
- }
- else if( Detail::startsWith( optName, "-" ) )
- arg.shortNames.push_back( optName.substr( 1 ) );
- else
- throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
- }
- friend void setPositionalArg( Arg& arg, int position )
- {
- arg.position = position;
- }
-
- class ArgBuilder {
- public:
- ArgBuilder( Arg* arg ) : m_arg( arg ) {}
-
- // Bind a non-boolean data member (requires placeholder string)
- template<typename C, typename M>
- void bind( M C::* field, std::string const& placeholder ) {
- m_arg->boundField = new Detail::BoundDataMember<C,M>( field );
- m_arg->placeholder = placeholder;
- }
- // Bind a boolean data member (no placeholder required)
- template<typename C>
- void bind( bool C::* field ) {
- m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );
- }
-
- // Bind a method taking a single, non-boolean argument (requires a placeholder string)
- template<typename C, typename M>
- void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {
- m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );
- m_arg->placeholder = placeholder;
- }
-
- // Bind a method taking a single, boolean argument (no placeholder string required)
- template<typename C>
- void bind( void (C::* unaryMethod)( bool ) ) {
- m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
- }
-
- // Bind a method that takes no arguments (will be called if opt is present)
- template<typename C>
- void bind( void (C::* nullaryMethod)() ) {
- m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );
- }
-
- // Bind a free function taking a single argument - the object to operate on (no placeholder string required)
- template<typename C>
- void bind( void (* unaryFunction)( C& ) ) {
- m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );
- }
-
- // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)
- template<typename C, typename T>
- void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {
- m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );
- m_arg->placeholder = placeholder;
- }
-
- ArgBuilder& describe( std::string const& description ) {
- m_arg->description = description;
- return *this;
- }
- ArgBuilder& detail( std::string const& detail ) {
- m_arg->detail = detail;
- return *this;
- }
-
- protected:
- Arg* m_arg;
- };
-
- class OptBuilder : public ArgBuilder {
- public:
- OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
- OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
-
- OptBuilder& operator[]( std::string const& optName ) {
- addOptName( *ArgBuilder::m_arg, optName );
- return *this;
- }
- };
-
- public:
-
- CommandLine()
- : m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
- m_highestSpecifiedArgPosition( 0 ),
- m_throwOnUnrecognisedTokens( false )
- {}
- CommandLine( CommandLine const& other )
- : m_boundProcessName( other.m_boundProcessName ),
- m_options ( other.m_options ),
- m_positionalArgs( other.m_positionalArgs ),
- m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
- m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
- {
- if( other.m_floatingArg.get() )
- m_floatingArg.reset( new Arg( *other.m_floatingArg ) );
- }
-
- CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
- m_throwOnUnrecognisedTokens = shouldThrow;
- return *this;
- }
-
- OptBuilder operator[]( std::string const& optName ) {
- m_options.push_back( Arg() );
- addOptName( m_options.back(), optName );
- OptBuilder builder( &m_options.back() );
- return builder;
- }
-
- ArgBuilder operator[]( int position ) {
- m_positionalArgs.insert( std::make_pair( position, Arg() ) );
- if( position > m_highestSpecifiedArgPosition )
- m_highestSpecifiedArgPosition = position;
- setPositionalArg( m_positionalArgs[position], position );
- ArgBuilder builder( &m_positionalArgs[position] );
- return builder;
- }
-
- // Invoke this with the _ instance
- ArgBuilder operator[]( UnpositionalTag ) {
- if( m_floatingArg.get() )
- throw std::logic_error( "Only one unpositional argument can be added" );
- m_floatingArg.reset( new Arg() );
- ArgBuilder builder( m_floatingArg.get() );
- return builder;
- }
-
- template<typename C, typename M>
- void bindProcessName( M C::* field ) {
- m_boundProcessName = new Detail::BoundDataMember<C,M>( field );
- }
- template<typename C, typename M>
- void bindProcessName( void (C::*_unaryMethod)( M ) ) {
- m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
- }
-
- void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {
- typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
- std::size_t maxWidth = 0;
- for( it = itBegin; it != itEnd; ++it )
- maxWidth = (std::max)( maxWidth, it->commands().size() );
-
- for( it = itBegin; it != itEnd; ++it ) {
- Detail::Text usage( it->commands(), Detail::TextAttributes()
- .setWidth( maxWidth+indent )
- .setIndent( indent ) );
- Detail::Text desc( it->description, Detail::TextAttributes()
- .setWidth( width - maxWidth - 3 ) );
-
- for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
- std::string usageCol = i < usage.size() ? usage[i] : "";
- os << usageCol;
-
- if( i < desc.size() && !desc[i].empty() )
- os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
- << desc[i];
- os << "\n";
- }
- }
- }
- std::string optUsage() const {
- std::ostringstream oss;
- optUsage( oss );
- return oss.str();
- }
-
- void argSynopsis( std::ostream& os ) const {
- for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
- if( i > 1 )
- os << " ";
- typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
- if( it != m_positionalArgs.end() )
- os << "<" << it->second.placeholder << ">";
- else if( m_floatingArg.get() )
- os << "<" << m_floatingArg->placeholder << ">";
- else
- throw std::logic_error( "non consecutive positional arguments with no floating args" );
- }
- // !TBD No indication of mandatory args
- if( m_floatingArg.get() ) {
- if( m_highestSpecifiedArgPosition > 1 )
- os << " ";
- os << "[<" << m_floatingArg->placeholder << "> ...]";
- }
- }
- std::string argSynopsis() const {
- std::ostringstream oss;
- argSynopsis( oss );
- return oss.str();
- }
-
- void usage( std::ostream& os, std::string const& procName ) const {
- validate();
- os << "usage:\n " << procName << " ";
- argSynopsis( os );
- if( !m_options.empty() ) {
- os << " [options]\n\nwhere options are: \n";
- optUsage( os, 2 );
- }
- os << "\n";
- }
- std::string usage( std::string const& procName ) const {
- std::ostringstream oss;
- usage( oss, procName );
- return oss.str();
- }
-
- ConfigT parse( int argc, char const * const * argv ) const {
- ConfigT config;
- parseInto( argc, argv, config );
- return config;
- }
-
- std::vector<Parser::Token> parseInto( int argc, char const * const * argv, ConfigT& config ) const {
- std::string processName = argv[0];
- std::size_t lastSlash = processName.find_last_of( "/\\" );
- if( lastSlash != std::string::npos )
- processName = processName.substr( lastSlash+1 );
- m_boundProcessName.set( config, processName );
- std::vector<Parser::Token> tokens;
- Parser parser;
- parser.parseIntoTokens( argc, argv, tokens );
- return populate( tokens, config );
- }
-
- std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
- validate();
- std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
- unusedTokens = populateFixedArgs( unusedTokens, config );
- unusedTokens = populateFloatingArgs( unusedTokens, config );
- return unusedTokens;
- }
-
- std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
- std::vector<Parser::Token> unusedTokens;
- std::vector<std::string> errors;
- for( std::size_t i = 0; i < tokens.size(); ++i ) {
- Parser::Token const& token = tokens[i];
- typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
- for(; it != itEnd; ++it ) {
- Arg const& arg = *it;
-
- try {
- if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
- ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
- if( arg.takesArg() ) {
- if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
- errors.push_back( "Expected argument to option: " + token.data );
- else
- arg.boundField.set( config, tokens[++i].data );
- }
- else {
- arg.boundField.setFlag( config );
- }
- break;
- }
- }
- catch( std::exception& ex ) {
- errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
- }
- }
- if( it == itEnd ) {
- if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
- unusedTokens.push_back( token );
- else if( errors.empty() && m_throwOnUnrecognisedTokens )
- errors.push_back( "unrecognised option: " + token.data );
- }
- }
- if( !errors.empty() ) {
- std::ostringstream oss;
- for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
- it != itEnd;
- ++it ) {
- if( it != errors.begin() )
- oss << "\n";
- oss << *it;
- }
- throw std::runtime_error( oss.str() );
- }
- return unusedTokens;
- }
- std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
- std::vector<Parser::Token> unusedTokens;
- int position = 1;
- for( std::size_t i = 0; i < tokens.size(); ++i ) {
- Parser::Token const& token = tokens[i];
- typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
- if( it != m_positionalArgs.end() )
- it->second.boundField.set( config, token.data );
- else
- unusedTokens.push_back( token );
- if( token.type == Parser::Token::Positional )
- position++;
- }
- return unusedTokens;
- }
- std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
- if( !m_floatingArg.get() )
- return tokens;
- std::vector<Parser::Token> unusedTokens;
- for( std::size_t i = 0; i < tokens.size(); ++i ) {
- Parser::Token const& token = tokens[i];
- if( token.type == Parser::Token::Positional )
- m_floatingArg->boundField.set( config, token.data );
- else
- unusedTokens.push_back( token );
- }
- return unusedTokens;
- }
-
- void validate() const
- {
- if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
- throw std::logic_error( "No options or arguments specified" );
-
- for( typename std::vector<Arg>::const_iterator it = m_options.begin(),
- itEnd = m_options.end();
- it != itEnd; ++it )
- it->validate();
- }
-
- private:
- Detail::BoundArgFunction<ConfigT> m_boundProcessName;
- std::vector<Arg> m_options;
- std::map<int, Arg> m_positionalArgs;
- ArgAutoPtr m_floatingArg;
- int m_highestSpecifiedArgPosition;
- bool m_throwOnUnrecognisedTokens;
- };
-
-} // end namespace Clara
-
-STITCH_CLARA_CLOSE_NAMESPACE
-#undef STITCH_CLARA_OPEN_NAMESPACE
-#undef STITCH_CLARA_CLOSE_NAMESPACE
-
-#endif // TWOBLUECUBES_CLARA_H_INCLUDED
-#undef STITCH_CLARA_OPEN_NAMESPACE
-
-// Restore Clara's value for console width, if present
-#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
-#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
-#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
-#endif
-
-#include <fstream>
-
-namespace Catch {
-
- inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
- inline void abortAfterX( ConfigData& config, int x ) {
- if( x < 1 )
- throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
- config.abortAfter = x;
- }
- inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
-
- inline void addWarning( ConfigData& config, std::string const& _warning ) {
- if( _warning == "NoAssertions" )
- config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
- else
- throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" );
- }
- inline void setOrder( ConfigData& config, std::string const& order ) {
- if( startsWith( "declared", order ) )
- config.runOrder = RunTests::InDeclarationOrder;
- else if( startsWith( "lexical", order ) )
- config.runOrder = RunTests::InLexicographicalOrder;
- else if( startsWith( "random", order ) )
- config.runOrder = RunTests::InRandomOrder;
- else
- throw std::runtime_error( "Unrecognised ordering: '" + order + "'" );
- }
- inline void setRngSeed( ConfigData& config, std::string const& seed ) {
- if( seed == "time" ) {
- config.rngSeed = static_cast<unsigned int>( std::time(0) );
- }
- else {
- std::stringstream ss;
- ss << seed;
- ss >> config.rngSeed;
- if( ss.fail() )
- throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" );
- }
- }
- inline void setVerbosity( ConfigData& config, int level ) {
- // !TBD: accept strings?
- config.verbosity = static_cast<Verbosity::Level>( level );
- }
- inline void setShowDurations( ConfigData& config, bool _showDurations ) {
- config.showDurations = _showDurations
- ? ShowDurations::Always
- : ShowDurations::Never;
- }
- inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
- std::ifstream f( _filename.c_str() );
- if( !f.is_open() )
- throw std::domain_error( "Unable to load input file: " + _filename );
-
- std::string line;
- while( std::getline( f, line ) ) {
- line = trim(line);
- if( !line.empty() && !startsWith( line, "#" ) )
- addTestOrTags( config, "\"" + line + "\"," );
- }
- }
-
- inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
-
- using namespace Clara;
- CommandLine<ConfigData> cli;
-
- cli.bindProcessName( &ConfigData::processName );
-
- cli["-?"]["-h"]["--help"]
- .describe( "display usage information" )
- .bind( &ConfigData::showHelp );
-
- cli["-l"]["--list-tests"]
- .describe( "list all/matching test cases" )
- .bind( &ConfigData::listTests );
-
- cli["-t"]["--list-tags"]
- .describe( "list all/matching tags" )
- .bind( &ConfigData::listTags );
-
- cli["-s"]["--success"]
- .describe( "include successful tests in output" )
- .bind( &ConfigData::showSuccessfulTests );
-
- cli["-b"]["--break"]
- .describe( "break into debugger on failure" )
- .bind( &ConfigData::shouldDebugBreak );
-
- cli["-e"]["--nothrow"]
- .describe( "skip exception tests" )
- .bind( &ConfigData::noThrow );
-
- cli["-i"]["--invisibles"]
- .describe( "show invisibles (tabs, newlines)" )
- .bind( &ConfigData::showInvisibles );
-
- cli["-o"]["--out"]
- .describe( "output filename" )
- .bind( &ConfigData::outputFilename, "filename" );
-
- cli["-r"]["--reporter"]
-// .placeholder( "name[:filename]" )
- .describe( "reporter to use (defaults to console)" )
- .bind( &ConfigData::reporterName, "name" );
-
- cli["-n"]["--name"]
- .describe( "suite name" )
- .bind( &ConfigData::name, "name" );
-
- cli["-a"]["--abort"]
- .describe( "abort at first failure" )
- .bind( &abortAfterFirst );
-
- cli["-x"]["--abortx"]
- .describe( "abort after x failures" )
- .bind( &abortAfterX, "no. failures" );
-
- cli["-w"]["--warn"]
- .describe( "enable warnings" )
- .bind( &addWarning, "warning name" );
-
-// - needs updating if reinstated
-// cli.into( &setVerbosity )
-// .describe( "level of verbosity (0=no output)" )
-// .shortOpt( "v")
-// .longOpt( "verbosity" )
-// .placeholder( "level" );
-
- cli[_]
- .describe( "which test or tests to use" )
- .bind( &addTestOrTags, "test name, pattern or tags" );
-
- cli["-d"]["--durations"]
- .describe( "show test durations" )
- .bind( &setShowDurations, "yes/no" );
-
- cli["-f"]["--input-file"]
- .describe( "load test names to run from a file" )
- .bind( &loadTestNamesFromFile, "filename" );
-
- // Less common commands which don't have a short form
- cli["--list-test-names-only"]
- .describe( "list all/matching test cases names only" )
- .bind( &ConfigData::listTestNamesOnly );
-
- cli["--list-reporters"]
- .describe( "list all reporters" )
- .bind( &ConfigData::listReporters );
-
- cli["--order"]
- .describe( "test case order (defaults to decl)" )
- .bind( &setOrder, "decl|lex|rand" );
-
- cli["--rng-seed"]
- .describe( "set a specific seed for random numbers" )
- .bind( &setRngSeed, "'time'|number" );
-
- cli["--force-colour"]
- .describe( "force colourised output" )
- .bind( &ConfigData::forceColour );
-
- return cli;
- }
-
-} // end namespace Catch
-
-// #included from: internal/catch_list.hpp
-#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
-
-// #included from: catch_text.h
-#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
-
-#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
-
-#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
-// #included from: ../external/tbc_text_format.h
-// Only use header guard if we are not using an outer namespace
-#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
-# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
-# ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
-# define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
-# endif
-# else
-# define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
-# endif
-#endif
-#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
-#include <string>
-#include <vector>
-#include <sstream>
-
-// Use optional outer namespace
-#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
-namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
-#endif
-
-namespace Tbc {
-
-#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
- const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
-#else
- const unsigned int consoleWidth = 80;
-#endif
-
- struct TextAttributes {
- TextAttributes()
- : initialIndent( std::string::npos ),
- indent( 0 ),
- width( consoleWidth-1 ),
- tabChar( '\t' )
- {}
-
- TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
- TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
- TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
- TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
-
- std::size_t initialIndent; // indent of first line, or npos
- std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
- std::size_t width; // maximum width of text, including indent. Longer text will wrap
- char tabChar; // If this char is seen the indent is changed to current pos
- };
-
- class Text {
- public:
- Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
- : attr( _attr )
- {
- std::string wrappableChars = " [({.,/|\\-";
- std::size_t indent = _attr.initialIndent != std::string::npos
- ? _attr.initialIndent
- : _attr.indent;
- std::string remainder = _str;
-
- while( !remainder.empty() ) {
- if( lines.size() >= 1000 ) {
- lines.push_back( "... message truncated due to excessive size" );
- return;
- }
- std::size_t tabPos = std::string::npos;
- std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
- std::size_t pos = remainder.find_first_of( '\n' );
- if( pos <= width ) {
- width = pos;
- }
- pos = remainder.find_last_of( _attr.tabChar, width );
- if( pos != std::string::npos ) {
- tabPos = pos;
- if( remainder[width] == '\n' )
- width--;
- remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
- }
-
- if( width == remainder.size() ) {
- spliceLine( indent, remainder, width );
- }
- else if( remainder[width] == '\n' ) {
- spliceLine( indent, remainder, width );
- if( width <= 1 || remainder.size() != 1 )
- remainder = remainder.substr( 1 );
- indent = _attr.indent;
- }
- else {
- pos = remainder.find_last_of( wrappableChars, width );
- if( pos != std::string::npos && pos > 0 ) {
- spliceLine( indent, remainder, pos );
- if( remainder[0] == ' ' )
- remainder = remainder.substr( 1 );
- }
- else {
- spliceLine( indent, remainder, width-1 );
- lines.back() += "-";
- }
- if( lines.size() == 1 )
- indent = _attr.indent;
- if( tabPos != std::string::npos )
- indent += tabPos;
- }
- }
- }
-
- void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
- lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
- _remainder = _remainder.substr( _pos );
- }
-
- typedef std::vector<std::string>::const_iterator const_iterator;
-
- const_iterator begin() const { return lines.begin(); }
- const_iterator end() const { return lines.end(); }
- std::string const& last() const { return lines.back(); }
- std::size_t size() const { return lines.size(); }
- std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
- std::string toString() const {
- std::ostringstream oss;
- oss << *this;
- return oss.str();
- }
-
- inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
- for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
- it != itEnd; ++it ) {
- if( it != _text.begin() )
- _stream << "\n";
- _stream << *it;
- }
- return _stream;
- }
-
- private:
- std::string str;
- TextAttributes attr;
- std::vector<std::string> lines;
- };
-
-} // end namespace Tbc
-
-#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
-} // end outer namespace
-#endif
-
-#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
-#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
-
-namespace Catch {
- using Tbc::Text;
- using Tbc::TextAttributes;
-}
-
-// #included from: catch_console_colour.hpp
-#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
-
-namespace Catch {
-
- struct Colour {
- enum Code {
- None = 0,
-
- White,
- Red,
- Green,
- Blue,
- Cyan,
- Yellow,
- Grey,
-
- Bright = 0x10,
-
- BrightRed = Bright | Red,
- BrightGreen = Bright | Green,
- LightGrey = Bright | Grey,
- BrightWhite = Bright | White,
-
- // By intention
- FileName = LightGrey,
- Warning = Yellow,
- ResultError = BrightRed,
- ResultSuccess = BrightGreen,
- ResultExpectedFailure = Warning,
-
- Error = BrightRed,
- Success = Green,
-
- OriginalExpression = Cyan,
- ReconstructedExpression = Yellow,
-
- SecondaryText = LightGrey,
- Headers = White
- };
-
- // Use constructed object for RAII guard
- Colour( Code _colourCode );
- Colour( Colour const& other );
- ~Colour();
-
- // Use static method for one-shot changes
- static void use( Code _colourCode );
-
- private:
- bool m_moved;
- };
-
- inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
-
-} // end namespace Catch
-
-// #included from: catch_interfaces_reporter.h
-#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
-
-#include <string>
-#include <ostream>
-#include <map>
-#include <assert.h>
-
-namespace Catch
-{
- struct ReporterConfig {
- explicit ReporterConfig( Ptr<IConfig> const& _fullConfig )
- : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
-
- ReporterConfig( Ptr<IConfig> const& _fullConfig, std::ostream& _stream )
- : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
-
- std::ostream& stream() const { return *m_stream; }
- Ptr<IConfig> fullConfig() const { return m_fullConfig; }
-
- private:
- std::ostream* m_stream;
- Ptr<IConfig> m_fullConfig;
- };
-
- struct ReporterPreferences {
- ReporterPreferences()
- : shouldRedirectStdOut( false )
- {}
-
- bool shouldRedirectStdOut;
- };
-
- template<typename T>
- struct LazyStat : Option<T> {
- LazyStat() : used( false ) {}
- LazyStat& operator=( T const& _value ) {
- Option<T>::operator=( _value );
- used = false;
- return *this;
- }
- void reset() {
- Option<T>::reset();
- used = false;
- }
- bool used;
- };
-
- struct TestRunInfo {
- TestRunInfo( std::string const& _name ) : name( _name ) {}
- std::string name;
- };
- struct GroupInfo {
- GroupInfo( std::string const& _name,
- std::size_t _groupIndex,
- std::size_t _groupsCount )
- : name( _name ),
- groupIndex( _groupIndex ),
- groupsCounts( _groupsCount )
- {}
-
- std::string name;
- std::size_t groupIndex;
- std::size_t groupsCounts;
- };
-
- struct AssertionStats {
- AssertionStats( AssertionResult const& _assertionResult,
- std::vector<MessageInfo> const& _infoMessages,
- Totals const& _totals )
- : assertionResult( _assertionResult ),
- infoMessages( _infoMessages ),
- totals( _totals )
- {
- if( assertionResult.hasMessage() ) {
- // Copy message into messages list.
- // !TBD This should have been done earlier, somewhere
- MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
- builder << assertionResult.getMessage();
- builder.m_info.message = builder.m_stream.str();
-
- infoMessages.push_back( builder.m_info );
- }
- }
- virtual ~AssertionStats();
-
-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
- AssertionStats( AssertionStats const& ) = default;
- AssertionStats( AssertionStats && ) = default;
- AssertionStats& operator = ( AssertionStats const& ) = default;
- AssertionStats& operator = ( AssertionStats && ) = default;
-# endif
-
- AssertionResult assertionResult;
- std::vector<MessageInfo> infoMessages;
- Totals totals;
- };
-
- struct SectionStats {
- SectionStats( SectionInfo const& _sectionInfo,
- Counts const& _assertions,
- double _durationInSeconds,
- bool _missingAssertions )
- : sectionInfo( _sectionInfo ),
- assertions( _assertions ),
- durationInSeconds( _durationInSeconds ),
- missingAssertions( _missingAssertions )
- {}
- virtual ~SectionStats();
-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
- SectionStats( SectionStats const& ) = default;
- SectionStats( SectionStats && ) = default;
- SectionStats& operator = ( SectionStats const& ) = default;
- SectionStats& operator = ( SectionStats && ) = default;
-# endif
-
- SectionInfo sectionInfo;
- Counts assertions;
- double durationInSeconds;
- bool missingAssertions;
- };
-
- struct TestCaseStats {
- TestCaseStats( TestCaseInfo const& _testInfo,
- Totals const& _totals,
- std::string const& _stdOut,
- std::string const& _stdErr,
- bool _aborting )
- : testInfo( _testInfo ),
- totals( _totals ),
- stdOut( _stdOut ),
- stdErr( _stdErr ),
- aborting( _aborting )
- {}
- virtual ~TestCaseStats();
-
-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
- TestCaseStats( TestCaseStats const& ) = default;
- TestCaseStats( TestCaseStats && ) = default;
- TestCaseStats& operator = ( TestCaseStats const& ) = default;
- TestCaseStats& operator = ( TestCaseStats && ) = default;
-# endif
-
- TestCaseInfo testInfo;
- Totals totals;
- std::string stdOut;
- std::string stdErr;
- bool aborting;
- };
-
- struct TestGroupStats {
- TestGroupStats( GroupInfo const& _groupInfo,
- Totals const& _totals,
- bool _aborting )
- : groupInfo( _groupInfo ),
- totals( _totals ),
- aborting( _aborting )
- {}
- TestGroupStats( GroupInfo const& _groupInfo )
- : groupInfo( _groupInfo ),
- aborting( false )
- {}
- virtual ~TestGroupStats();
-
-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
- TestGroupStats( TestGroupStats const& ) = default;
- TestGroupStats( TestGroupStats && ) = default;
- TestGroupStats& operator = ( TestGroupStats const& ) = default;
- TestGroupStats& operator = ( TestGroupStats && ) = default;
-# endif
-
- GroupInfo groupInfo;
- Totals totals;
- bool aborting;
- };
-
- struct TestRunStats {
- TestRunStats( TestRunInfo const& _runInfo,
- Totals const& _totals,
- bool _aborting )
- : runInfo( _runInfo ),
- totals( _totals ),
- aborting( _aborting )
- {}
- virtual ~TestRunStats();
-
-# ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
- TestRunStats( TestRunStats const& _other )
- : runInfo( _other.runInfo ),
- totals( _other.totals ),
- aborting( _other.aborting )
- {}
-# else
- TestRunStats( TestRunStats const& ) = default;
- TestRunStats( TestRunStats && ) = default;
- TestRunStats& operator = ( TestRunStats const& ) = default;
- TestRunStats& operator = ( TestRunStats && ) = default;
-# endif
-
- TestRunInfo runInfo;
- Totals totals;
- bool aborting;
- };
-
- struct IStreamingReporter : IShared {
- virtual ~IStreamingReporter();
-
- // Implementing class must also provide the following static method:
- // static std::string getDescription();
-
- virtual ReporterPreferences getPreferences() const = 0;
-
- virtual void noMatchingTestCases( std::string const& spec ) = 0;
-
- virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
- virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
-
- virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
- virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
-
- virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
-
- // The return value indicates if the messages buffer should be cleared:
- virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
- virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
- virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
- virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
- virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
-
- virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
- };
-
- struct IReporterFactory {
- virtual ~IReporterFactory();
- virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
- virtual std::string getDescription() const = 0;
- };
-
- struct IReporterRegistry {
- typedef std::map<std::string, IReporterFactory*> FactoryMap;
-
- virtual ~IReporterRegistry();
- virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const = 0;
- virtual FactoryMap const& getFactories() const = 0;
- };
-
-}
-
-#include <limits>
-#include <algorithm>
-
-namespace Catch {
-
- inline std::size_t listTests( Config const& config ) {
-
- TestSpec testSpec = config.testSpec();
- if( config.testSpec().hasFilters() )
- Catch::cout() << "Matching test cases:\n";
- else {
- Catch::cout() << "All available test cases:\n";
- testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
- }
-
- std::size_t matchedTests = 0;
- TextAttributes nameAttr, tagsAttr;
- nameAttr.setInitialIndent( 2 ).setIndent( 4 );
- tagsAttr.setIndent( 6 );
-
- std::vector<TestCase> matchedTestCases;
- getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
- for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
- it != itEnd;
- ++it ) {
- matchedTests++;
- TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
- Colour::Code colour = testCaseInfo.isHidden()
- ? Colour::SecondaryText
- : Colour::None;
- Colour colourGuard( colour );
-
- Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
- if( !testCaseInfo.tags.empty() )
- Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
- }
-
- if( !config.testSpec().hasFilters() )
- Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl;
- else
- Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl;
- return matchedTests;
- }
-
- inline std::size_t listTestsNamesOnly( Config const& config ) {
- TestSpec testSpec = config.testSpec();
- if( !config.testSpec().hasFilters() )
- testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
- std::size_t matchedTests = 0;
- std::vector<TestCase> matchedTestCases;
- getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
- for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
- it != itEnd;
- ++it ) {
- matchedTests++;
- TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
- Catch::cout() << testCaseInfo.name << std::endl;
- }
- return matchedTests;
- }
-
- struct TagInfo {
- TagInfo() : count ( 0 ) {}
- void add( std::string const& spelling ) {
- ++count;
- spellings.insert( spelling );
- }
- std::string all() const {
- std::string out;
- for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
- it != itEnd;
- ++it )
- out += "[" + *it + "]";
- return out;
- }
- std::set<std::string> spellings;
- std::size_t count;
- };
-
- inline std::size_t listTags( Config const& config ) {
- TestSpec testSpec = config.testSpec();
- if( config.testSpec().hasFilters() )
- Catch::cout() << "Tags for matching test cases:\n";
- else {
- Catch::cout() << "All available tags:\n";
- testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
- }
-
- std::map<std::string, TagInfo> tagCounts;
-
- std::vector<TestCase> matchedTestCases;
- getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
- for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
- it != itEnd;
- ++it ) {
- for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
- tagItEnd = it->getTestCaseInfo().tags.end();
- tagIt != tagItEnd;
- ++tagIt ) {
- std::string tagName = *tagIt;
- std::string lcaseTagName = toLower( tagName );
- std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
- if( countIt == tagCounts.end() )
- countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
- countIt->second.add( tagName );
- }
- }
-
- for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
- countItEnd = tagCounts.end();
- countIt != countItEnd;
- ++countIt ) {
- std::ostringstream oss;
- oss << " " << std::setw(2) << countIt->second.count << " ";
- Text wrapper( countIt->second.all(), TextAttributes()
- .setInitialIndent( 0 )
- .setIndent( oss.str().size() )
- .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
- Catch::cout() << oss.str() << wrapper << "\n";
- }
- Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl;
- return tagCounts.size();
- }
-
- inline std::size_t listReporters( Config const& /*config*/ ) {
- Catch::cout() << "Available reporters:\n";
- IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
- IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
- std::size_t maxNameLen = 0;
- for(it = itBegin; it != itEnd; ++it )
- maxNameLen = (std::max)( maxNameLen, it->first.size() );
-
- for(it = itBegin; it != itEnd; ++it ) {
- Text wrapper( it->second->getDescription(), TextAttributes()
- .setInitialIndent( 0 )
- .setIndent( 7+maxNameLen )
- .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
- Catch::cout() << " "
- << it->first
- << ":"
- << std::string( maxNameLen - it->first.size() + 2, ' ' )
- << wrapper << "\n";
- }
- Catch::cout() << std::endl;
- return factories.size();
- }
-
- inline Option<std::size_t> list( Config const& config ) {
- Option<std::size_t> listedCount;
- if( config.listTests() )
- listedCount = listedCount.valueOr(0) + listTests( config );
- if( config.listTestNamesOnly() )
- listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
- if( config.listTags() )
- listedCount = listedCount.valueOr(0) + listTags( config );
- if( config.listReporters() )
- listedCount = listedCount.valueOr(0) + listReporters( config );
- return listedCount;
- }
-
-} // end namespace Catch
-
-// #included from: internal/catch_runner_impl.hpp
-#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
-
-// #included from: catch_test_case_tracker.hpp
-#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
-
-#include <map>
-#include <string>
-#include <assert.h>
-
-namespace Catch {
-namespace SectionTracking {
-
- class TrackedSection {
-
- typedef std::map<std::string, TrackedSection> TrackedSections;
-
- public:
- enum RunState {
- NotStarted,
- Executing,
- ExecutingChildren,
- Completed
- };
-
- TrackedSection( std::string const& name, TrackedSection* parent )
- : m_name( name ), m_runState( NotStarted ), m_parent( parent )
- {}
-
- RunState runState() const { return m_runState; }
-
- TrackedSection* findChild( std::string const& childName );
- TrackedSection* acquireChild( std::string const& childName );
-
- void enter() {
- if( m_runState == NotStarted )
- m_runState = Executing;
- }
- void leave();
-
- TrackedSection* getParent() {
- return m_parent;
- }
- bool hasChildren() const {
- return !m_children.empty();
- }
-
- private:
- std::string m_name;
- RunState m_runState;
- TrackedSections m_children;
- TrackedSection* m_parent;
- };
-
- inline TrackedSection* TrackedSection::findChild( std::string const& childName ) {
- TrackedSections::iterator it = m_children.find( childName );
- return it != m_children.end()
- ? &it->second
- : NULL;
- }
- inline TrackedSection* TrackedSection::acquireChild( std::string const& childName ) {
- if( TrackedSection* child = findChild( childName ) )
- return child;
- m_children.insert( std::make_pair( childName, TrackedSection( childName, this ) ) );
- return findChild( childName );
- }
- inline void TrackedSection::leave() {
- for( TrackedSections::const_iterator it = m_children.begin(), itEnd = m_children.end();
- it != itEnd;
- ++it )
- if( it->second.runState() != Completed ) {
- m_runState = ExecutingChildren;
- return;
- }
- m_runState = Completed;
- }
-
- class TestCaseTracker {
- public:
- TestCaseTracker( std::string const& testCaseName )
- : m_testCase( testCaseName, NULL ),
- m_currentSection( &m_testCase ),
- m_completedASectionThisRun( false )
- {}
-
- bool enterSection( std::string const& name ) {
- TrackedSection* child = m_currentSection->acquireChild( name );
- if( m_completedASectionThisRun || child->runState() == TrackedSection::Completed )
- return false;
-
- m_currentSection = child;
- m_currentSection->enter();
- return true;
- }
- void leaveSection() {
- m_currentSection->leave();
- m_currentSection = m_currentSection->getParent();
- assert( m_currentSection != NULL );
- m_completedASectionThisRun = true;
- }
-
- bool currentSectionHasChildren() const {
- return m_currentSection->hasChildren();
- }
- bool isCompleted() const {
- return m_testCase.runState() == TrackedSection::Completed;
- }
-
- class Guard {
- public:
- Guard( TestCaseTracker& tracker ) : m_tracker( tracker ) {
- m_tracker.enterTestCase();
- }
- ~Guard() {
- m_tracker.leaveTestCase();
- }
- private:
- Guard( Guard const& );
- void operator = ( Guard const& );
- TestCaseTracker& m_tracker;
- };
-
- private:
- void enterTestCase() {
- m_currentSection = &m_testCase;
- m_completedASectionThisRun = false;
- m_testCase.enter();
- }
- void leaveTestCase() {
- m_testCase.leave();
- }
-
- TrackedSection m_testCase;
- TrackedSection* m_currentSection;
- bool m_completedASectionThisRun;
- };
-
-} // namespace SectionTracking
-
-using SectionTracking::TestCaseTracker;
-
-} // namespace Catch
-
-// #included from: catch_fatal_condition.hpp
-#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
-
-namespace Catch {
-
- // Report the error condition then exit the process
- inline void fatal( std::string const& message, int exitCode ) {
- IContext& context = Catch::getCurrentContext();
- IResultCapture* resultCapture = context.getResultCapture();
- resultCapture->handleFatalErrorCondition( message );
-
- if( Catch::alwaysTrue() ) // avoids "no return" warnings
- exit( exitCode );
- }
-
-} // namespace Catch
-
-#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
-
-namespace Catch {
-
- struct FatalConditionHandler {
- void reset() {}
- };
-
-} // namespace Catch
-
-#else // Not Windows - assumed to be POSIX compatible //////////////////////////
-
-#include <signal.h>
-
-namespace Catch {
-
- struct SignalDefs { int id; const char* name; };
- extern SignalDefs signalDefs[];
- SignalDefs signalDefs[] = {
- { SIGINT, "SIGINT - Terminal interrupt signal" },
- { SIGILL, "SIGILL - Illegal instruction signal" },
- { SIGFPE, "SIGFPE - Floating point error signal" },
- { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
- { SIGTERM, "SIGTERM - Termination request signal" },
- { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
- };
-
- struct FatalConditionHandler {
-
- static void handleSignal( int sig ) {
- for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
- if( sig == signalDefs[i].id )
- fatal( signalDefs[i].name, -sig );
- fatal( "<unknown signal>", -sig );
- }
-
- FatalConditionHandler() : m_isSet( true ) {
- for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
- signal( signalDefs[i].id, handleSignal );
- }
- ~FatalConditionHandler() {
- reset();
- }
- void reset() {
- if( m_isSet ) {
- for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
- signal( signalDefs[i].id, SIG_DFL );
- m_isSet = false;
- }
- }
-
- bool m_isSet;
- };
-
-} // namespace Catch
-
-#endif // not Windows
-
-#include <set>
-#include <string>
-
-namespace Catch {
-
- class StreamRedirect {
-
- public:
- StreamRedirect( std::ostream& stream, std::string& targetString )
- : m_stream( stream ),
- m_prevBuf( stream.rdbuf() ),
- m_targetString( targetString )
- {
- stream.rdbuf( m_oss.rdbuf() );
- }
-
- ~StreamRedirect() {
- m_targetString += m_oss.str();
- m_stream.rdbuf( m_prevBuf );
- }
-
- private:
- std::ostream& m_stream;
- std::streambuf* m_prevBuf;
- std::ostringstream m_oss;
- std::string& m_targetString;
- };
-
- ///////////////////////////////////////////////////////////////////////////
-
- class RunContext : public IResultCapture, public IRunner {
-
- RunContext( RunContext const& );
- void operator =( RunContext const& );
-
- public:
-
- explicit RunContext( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> const& reporter )
- : m_runInfo( config->name() ),
- m_context( getCurrentMutableContext() ),
- m_activeTestCase( NULL ),
- m_config( config ),
- m_reporter( reporter ),
- m_prevRunner( m_context.getRunner() ),
- m_prevResultCapture( m_context.getResultCapture() ),
- m_prevConfig( m_context.getConfig() )
- {
- m_context.setRunner( this );
- m_context.setConfig( m_config );
- m_context.setResultCapture( this );
- m_reporter->testRunStarting( m_runInfo );
- }
-
- virtual ~RunContext() {
- m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
- m_context.setRunner( m_prevRunner );
- m_context.setConfig( NULL );
- m_context.setResultCapture( m_prevResultCapture );
- m_context.setConfig( m_prevConfig );
- }
-
- void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
- m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
- }
- void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
- m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
- }
-
- Totals runTest( TestCase const& testCase ) {
- Totals prevTotals = m_totals;
-
- std::string redirectedCout;
- std::string redirectedCerr;
-
- TestCaseInfo testInfo = testCase.getTestCaseInfo();
-
- m_reporter->testCaseStarting( testInfo );
-
- m_activeTestCase = &testCase;
- m_testCaseTracker = TestCaseTracker( testInfo.name );
-
- do {
- do {
- runCurrentTest( redirectedCout, redirectedCerr );
- }
- while( !m_testCaseTracker->isCompleted() && !aborting() );
- }
- while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
-
- Totals deltaTotals = m_totals.delta( prevTotals );
- m_totals.testCases += deltaTotals.testCases;
- m_reporter->testCaseEnded( TestCaseStats( testInfo,
- deltaTotals,
- redirectedCout,
- redirectedCerr,
- aborting() ) );
-
- m_activeTestCase = NULL;
- m_testCaseTracker.reset();
-
- return deltaTotals;
- }
-
- Ptr<IConfig const> config() const {
- return m_config;
- }
-
- private: // IResultCapture
-
- virtual void assertionEnded( AssertionResult const& result ) {
- if( result.getResultType() == ResultWas::Ok ) {
- m_totals.assertions.passed++;
- }
- else if( !result.isOk() ) {
- m_totals.assertions.failed++;
- }
-
- if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
- m_messages.clear();
-
- // Reset working state
- m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
- m_lastResult = result;
- }
-
- virtual bool sectionStarted (
- SectionInfo const& sectionInfo,
- Counts& assertions
- )
- {
- std::ostringstream oss;
- oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
-
- if( !m_testCaseTracker->enterSection( oss.str() ) )
- return false;
-
- m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
-
- m_reporter->sectionStarting( sectionInfo );
-
- assertions = m_totals.assertions;
-
- return true;
- }
- bool testForMissingAssertions( Counts& assertions ) {
- if( assertions.total() != 0 ||
- !m_config->warnAboutMissingAssertions() ||
- m_testCaseTracker->currentSectionHasChildren() )
- return false;
- m_totals.assertions.failed++;
- assertions.failed++;
- return true;
- }
-
- virtual void sectionEnded( SectionInfo const& info, Counts const& prevAssertions, double _durationInSeconds ) {
- if( std::uncaught_exception() ) {
- m_unfinishedSections.push_back( UnfinishedSections( info, prevAssertions, _durationInSeconds ) );
- return;
- }
-
- Counts assertions = m_totals.assertions - prevAssertions;
- bool missingAssertions = testForMissingAssertions( assertions );
-
- m_testCaseTracker->leaveSection();
-
- m_reporter->sectionEnded( SectionStats( info, assertions, _durationInSeconds, missingAssertions ) );
- m_messages.clear();
- }
-
- virtual void pushScopedMessage( MessageInfo const& message ) {
- m_messages.push_back( message );
- }
-
- virtual void popScopedMessage( MessageInfo const& message ) {
- m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
- }
-
- virtual std::string getCurrentTestName() const {
- return m_activeTestCase
- ? m_activeTestCase->getTestCaseInfo().name
- : "";
- }
-
- virtual const AssertionResult* getLastResult() const {
- return &m_lastResult;
- }
-
- virtual void handleFatalErrorCondition( std::string const& message ) {
- ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
- resultBuilder.setResultType( ResultWas::FatalErrorCondition );
- resultBuilder << message;
- resultBuilder.captureExpression();
-
- handleUnfinishedSections();
-
- // Recreate section for test case (as we will lose the one that was in scope)
- TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
- SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
-
- Counts assertions;
- assertions.failed = 1;
- SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );
- m_reporter->sectionEnded( testCaseSectionStats );
-
- TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
-
- Totals deltaTotals;
- deltaTotals.testCases.failed = 1;
- m_reporter->testCaseEnded( TestCaseStats( testInfo,
- deltaTotals,
- "",
- "",
- false ) );
- m_totals.testCases.failed++;
- testGroupEnded( "", m_totals, 1, 1 );
- m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
- }
-
- public:
- // !TBD We need to do this another way!
- bool aborting() const {
- return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
- }
-
- private:
-
- void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
- TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
- SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
- m_reporter->sectionStarting( testCaseSection );
- Counts prevAssertions = m_totals.assertions;
- double duration = 0;
- try {
- m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
- TestCaseTracker::Guard guard( *m_testCaseTracker );
-
- Timer timer;
- timer.start();
- if( m_reporter->getPreferences().shouldRedirectStdOut ) {
- StreamRedirect coutRedir( Catch::cout(), redirectedCout );
- StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );
- invokeActiveTestCase();
- }
- else {
- invokeActiveTestCase();
- }
- duration = timer.getElapsedSeconds();
- }
- catch( TestFailureException& ) {
- // This just means the test was aborted due to failure
- }
- catch(...) {
- makeUnexpectedResultBuilder().useActiveException();
- }
- handleUnfinishedSections();
- m_messages.clear();
-
- Counts assertions = m_totals.assertions - prevAssertions;
- bool missingAssertions = testForMissingAssertions( assertions );
-
- if( testCaseInfo.okToFail() ) {
- std::swap( assertions.failedButOk, assertions.failed );
- m_totals.assertions.failed -= assertions.failedButOk;
- m_totals.assertions.failedButOk += assertions.failedButOk;
- }
-
- SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
- m_reporter->sectionEnded( testCaseSectionStats );
- }
-
- void invokeActiveTestCase() {
- FatalConditionHandler fatalConditionHandler; // Handle signals
- m_activeTestCase->invoke();
- fatalConditionHandler.reset();
- }
-
- private:
-
- ResultBuilder makeUnexpectedResultBuilder() const {
- return ResultBuilder( m_lastAssertionInfo.macroName.c_str(),
- m_lastAssertionInfo.lineInfo,
- m_lastAssertionInfo.capturedExpression.c_str(),
- m_lastAssertionInfo.resultDisposition );
- }
-
- void handleUnfinishedSections() {
- // If sections ended prematurely due to an exception we stored their
- // infos here so we can tear them down outside the unwind process.
- for( std::vector<UnfinishedSections>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
- itEnd = m_unfinishedSections.rend();
- it != itEnd;
- ++it )
- sectionEnded( it->info, it->prevAssertions, it->durationInSeconds );
- m_unfinishedSections.clear();
- }
-
- struct UnfinishedSections {
- UnfinishedSections( SectionInfo const& _info, Counts const& _prevAssertions, double _durationInSeconds )
- : info( _info ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
- {}
-
- SectionInfo info;
- Counts prevAssertions;
- double durationInSeconds;
- };
-
- TestRunInfo m_runInfo;
- IMutableContext& m_context;
- TestCase const* m_activeTestCase;
- Option<TestCaseTracker> m_testCaseTracker;
- AssertionResult m_lastResult;
-
- Ptr<IConfig const> m_config;
- Totals m_totals;
- Ptr<IStreamingReporter> m_reporter;
- std::vector<MessageInfo> m_messages;
- IRunner* m_prevRunner;
- IResultCapture* m_prevResultCapture;
- Ptr<IConfig const> m_prevConfig;
- AssertionInfo m_lastAssertionInfo;
- std::vector<UnfinishedSections> m_unfinishedSections;
- };
-
- IResultCapture& getResultCapture() {
- if( IResultCapture* capture = getCurrentContext().getResultCapture() )
- return *capture;
- else
- throw std::logic_error( "No result capture instance" );
- }
-
-} // end namespace Catch
-
-// #included from: internal/catch_version.h
-#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
-
-namespace Catch {
-
- // Versioning information
- struct Version {
- Version( unsigned int _majorVersion,
- unsigned int _minorVersion,
- unsigned int _patchNumber,
- std::string const& _branchName,
- unsigned int _buildNumber );
-
- unsigned int const majorVersion;
- unsigned int const minorVersion;
- unsigned int const patchNumber;
-
- // buildNumber is only used if branchName is not null
- std::string const branchName;
- unsigned int const buildNumber;
-
- friend std::ostream& operator << ( std::ostream& os, Version const& version );
-
- private:
- void operator=( Version const& );
- };
-
- extern Version libraryVersion;
-}
-
-#include <fstream>
-#include <stdlib.h>
-#include <limits>
-
-namespace Catch {
-
- class Runner {
-
- public:
- Runner( Ptr<Config> const& config )
- : m_config( config )
- {
- openStream();
- makeReporter();
- }
-
- Totals runTests() {
-
- RunContext context( m_config.get(), m_reporter );
-
- Totals totals;
-
- context.testGroupStarting( "all tests", 1, 1 ); // deprecated?
-
- TestSpec testSpec = m_config->testSpec();
- if( !testSpec.hasFilters() )
- testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
-
- std::vector<TestCase> testCases;
- getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, testCases );
-
- int testsRunForGroup = 0;
- for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
- it != itEnd;
- ++it ) {
- testsRunForGroup++;
- if( m_testsAlreadyRun.find( *it ) == m_testsAlreadyRun.end() ) {
-
- if( context.aborting() )
- break;
-
- totals += context.runTest( *it );
- m_testsAlreadyRun.insert( *it );
- }
- }
- std::vector<TestCase> skippedTestCases;
- getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, skippedTestCases, true );
-
- for( std::vector<TestCase>::const_iterator it = skippedTestCases.begin(), itEnd = skippedTestCases.end();
- it != itEnd;
- ++it )
- m_reporter->skipTest( *it );
-
- context.testGroupEnded( "all tests", totals, 1, 1 );
- return totals;
- }
-
- private:
- void openStream() {
- // Open output file, if specified
- if( !m_config->getFilename().empty() ) {
- m_ofs.open( m_config->getFilename().c_str() );
- if( m_ofs.fail() ) {
- std::ostringstream oss;
- oss << "Unable to open file: '" << m_config->getFilename() << "'";
- throw std::domain_error( oss.str() );
- }
- m_config->setStreamBuf( m_ofs.rdbuf() );
- }
- }
- void makeReporter() {
- std::string reporterName = m_config->getReporterName().empty()
- ? "console"
- : m_config->getReporterName();
-
- m_reporter = getRegistryHub().getReporterRegistry().create( reporterName, m_config.get() );
- if( !m_reporter ) {
- std::ostringstream oss;
- oss << "No reporter registered with name: '" << reporterName << "'";
- throw std::domain_error( oss.str() );
- }
- }
-
- private:
- Ptr<Config> m_config;
- std::ofstream m_ofs;
- Ptr<IStreamingReporter> m_reporter;
- std::set<TestCase> m_testsAlreadyRun;
- };
-
- class Session : NonCopyable {
- static bool alreadyInstantiated;
-
- public:
-
- struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
-
- Session()
- : m_cli( makeCommandLineParser() ) {
- if( alreadyInstantiated ) {
- std::string msg = "Only one instance of Catch::Session can ever be used";
- Catch::cerr() << msg << std::endl;
- throw std::logic_error( msg );
- }
- alreadyInstantiated = true;
- }
- ~Session() {
- Catch::cleanUp();
- }
-
- void showHelp( std::string const& processName ) {
- Catch::cout() << "\nCatch v" << libraryVersion << "\n";
-
- m_cli.usage( Catch::cout(), processName );
- Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
- }
-
- int applyCommandLine( int argc, char* const argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
- try {
- m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
- m_unusedTokens = m_cli.parseInto( argc, argv, m_configData );
- if( m_configData.showHelp )
- showHelp( m_configData.processName );
- m_config.reset();
- }
- catch( std::exception& ex ) {
- {
- Colour colourGuard( Colour::Red );
- Catch::cerr()
- << "\nError(s) in input:\n"
- << Text( ex.what(), TextAttributes().setIndent(2) )
- << "\n\n";
- }
- m_cli.usage( Catch::cout(), m_configData.processName );
- return (std::numeric_limits<int>::max)();
- }
- return 0;
- }
-
- void useConfigData( ConfigData const& _configData ) {
- m_configData = _configData;
- m_config.reset();
- }
-
- int run( int argc, char* const argv[] ) {
-
- int returnCode = applyCommandLine( argc, argv );
- if( returnCode == 0 )
- returnCode = run();
- return returnCode;
- }
-
- int run() {
- if( m_configData.showHelp )
- return 0;
-
- try
- {
- config(); // Force config to be constructed
-
- std::srand( m_configData.rngSeed );
-
- Runner runner( m_config );
-
- // Handle list request
- if( Option<std::size_t> listed = list( config() ) )
- return static_cast<int>( *listed );
-
- return static_cast<int>( runner.runTests().assertions.failed );
- }
- catch( std::exception& ex ) {
- Catch::cerr() << ex.what() << std::endl;
- return (std::numeric_limits<int>::max)();
- }
- }
-
- Clara::CommandLine<ConfigData> const& cli() const {
- return m_cli;
- }
- std::vector<Clara::Parser::Token> const& unusedTokens() const {
- return m_unusedTokens;
- }
- ConfigData& configData() {
- return m_configData;
- }
- Config& config() {
- if( !m_config )
- m_config = new Config( m_configData );
- return *m_config;
- }
-
- private:
- Clara::CommandLine<ConfigData> m_cli;
- std::vector<Clara::Parser::Token> m_unusedTokens;
- ConfigData m_configData;
- Ptr<Config> m_config;
- };
-
- bool Session::alreadyInstantiated = false;
-
-} // end namespace Catch
-
-// #included from: catch_registry_hub.hpp
-#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
-
-// #included from: catch_test_case_registry_impl.hpp
-#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
-
-#include <vector>
-#include <set>
-#include <sstream>
-#include <iostream>
-#include <algorithm>
-
-namespace Catch {
-
- class TestRegistry : public ITestCaseRegistry {
- struct LexSort {
- bool operator() (TestCase i,TestCase j) const { return (i<j);}
- };
- struct RandomNumberGenerator {
- int operator()( int n ) const { return std::rand() % n; }
- };
-
- public:
- TestRegistry() : m_unnamedCount( 0 ) {}
- virtual ~TestRegistry();
-
- virtual void registerTest( TestCase const& testCase ) {
- std::string name = testCase.getTestCaseInfo().name;
- if( name == "" ) {
- std::ostringstream oss;
- oss << "Anonymous test case " << ++m_unnamedCount;
- return registerTest( testCase.withName( oss.str() ) );
- }
-
- if( m_functions.find( testCase ) == m_functions.end() ) {
- m_functions.insert( testCase );
- m_functionsInOrder.push_back( testCase );
- if( !testCase.isHidden() )
- m_nonHiddenFunctions.push_back( testCase );
- }
- else {
- TestCase const& prev = *m_functions.find( testCase );
- {
- Colour colourGuard( Colour::Red );
- Catch::cerr() << "error: TEST_CASE( \"" << name << "\" ) already defined.\n"
- << "\tFirst seen at " << prev.getTestCaseInfo().lineInfo << "\n"
- << "\tRedefined at " << testCase.getTestCaseInfo().lineInfo << std::endl;
- }
- exit(1);
- }
- }
-
- virtual std::vector<TestCase> const& getAllTests() const {
- return m_functionsInOrder;
- }
-
- virtual std::vector<TestCase> const& getAllNonHiddenTests() const {
- return m_nonHiddenFunctions;
- }
-
- virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases, bool negated = false ) const {
-
- for( std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin(),
- itEnd = m_functionsInOrder.end();
- it != itEnd;
- ++it ) {
- bool includeTest = testSpec.matches( *it ) && ( config.allowThrows() || !it->throws() );
- if( includeTest != negated )
- matchingTestCases.push_back( *it );
- }
- sortTests( config, matchingTestCases );
- }
-
- private:
-
- static void sortTests( IConfig const& config, std::vector<TestCase>& matchingTestCases ) {
-
- switch( config.runOrder() ) {
- case RunTests::InLexicographicalOrder:
- std::sort( matchingTestCases.begin(), matchingTestCases.end(), LexSort() );
- break;
- case RunTests::InRandomOrder:
- {
- RandomNumberGenerator rng;
- std::random_shuffle( matchingTestCases.begin(), matchingTestCases.end(), rng );
- }
- break;
- case RunTests::InDeclarationOrder:
- // already in declaration order
- break;
- }
- }
- std::set<TestCase> m_functions;
- std::vector<TestCase> m_functionsInOrder;
- std::vector<TestCase> m_nonHiddenFunctions;
- size_t m_unnamedCount;
- };
-
- ///////////////////////////////////////////////////////////////////////////
-
- class FreeFunctionTestCase : public SharedImpl<ITestCase> {
- public:
-
- FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
-
- virtual void invoke() const {
- m_fun();
- }
-
- private:
- virtual ~FreeFunctionTestCase();
-
- TestFunction m_fun;
- };
-
- inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
- std::string className = classOrQualifiedMethodName;
- if( startsWith( className, "&" ) )
- {
- std::size_t lastColons = className.rfind( "::" );
- std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
- if( penultimateColons == std::string::npos )
- penultimateColons = 1;
- className = className.substr( penultimateColons, lastColons-penultimateColons );
- }
- return className;
- }
-
- ///////////////////////////////////////////////////////////////////////////
-
- AutoReg::AutoReg( TestFunction function,
- SourceLineInfo const& lineInfo,
- NameAndDesc const& nameAndDesc ) {
- registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
- }
-
- AutoReg::~AutoReg() {}
-
- void AutoReg::registerTestCase( ITestCase* testCase,
- char const* classOrQualifiedMethodName,
- NameAndDesc const& nameAndDesc,
- SourceLineInfo const& lineInfo ) {
-
- getMutableRegistryHub().registerTest
- ( makeTestCase( testCase,
- extractClassName( classOrQualifiedMethodName ),
- nameAndDesc.name,
- nameAndDesc.description,
- lineInfo ) );
- }
-
-} // end namespace Catch
-
-// #included from: catch_reporter_registry.hpp
-#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
-
-#include <map>
-
-namespace Catch {
-
- class ReporterRegistry : public IReporterRegistry {
-
- public:
-
- virtual ~ReporterRegistry() {
- deleteAllValues( m_factories );
- }
-
- virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const {
- FactoryMap::const_iterator it = m_factories.find( name );
- if( it == m_factories.end() )
- return NULL;
- return it->second->create( ReporterConfig( config ) );
- }
-
- void registerReporter( std::string const& name, IReporterFactory* factory ) {
- m_factories.insert( std::make_pair( name, factory ) );
- }
-
- FactoryMap const& getFactories() const {
- return m_factories;
- }
-
- private:
- FactoryMap m_factories;
- };
-}
-
-// #included from: catch_exception_translator_registry.hpp
-#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
-
-#ifdef __OBJC__
-#import "Foundation/Foundation.h"
-#endif
-
-namespace Catch {
-
- class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
- public:
- ~ExceptionTranslatorRegistry() {
- deleteAll( m_translators );
- }
-
- virtual void registerTranslator( const IExceptionTranslator* translator ) {
- m_translators.push_back( translator );
- }
-
- virtual std::string translateActiveException() const {
- try {
-#ifdef __OBJC__
- // In Objective-C try objective-c exceptions first
- @try {
- throw;
- }
- @catch (NSException *exception) {
- return Catch::toString( [exception description] );
- }
-#else
- throw;
-#endif
- }
- catch( TestFailureException& ) {
- throw;
- }
- catch( std::exception& ex ) {
- return ex.what();
- }
- catch( std::string& msg ) {
- return msg;
- }
- catch( const char* msg ) {
- return msg;
- }
- catch(...) {
- return tryTranslators( m_translators.begin() );
- }
- }
-
- std::string tryTranslators( std::vector<const IExceptionTranslator*>::const_iterator it ) const {
- if( it == m_translators.end() )
- return "Unknown exception";
-
- try {
- return (*it)->translate();
- }
- catch(...) {
- return tryTranslators( it+1 );
- }
- }
-
- private:
- std::vector<const IExceptionTranslator*> m_translators;
- };
-}
-
-namespace Catch {
-
- namespace {
-
- class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
-
- RegistryHub( RegistryHub const& );
- void operator=( RegistryHub const& );
-
- public: // IRegistryHub
- RegistryHub() {
- }
- virtual IReporterRegistry const& getReporterRegistry() const {
- return m_reporterRegistry;
- }
- virtual ITestCaseRegistry const& getTestCaseRegistry() const {
- return m_testCaseRegistry;
- }
- virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() {
- return m_exceptionTranslatorRegistry;
- }
-
- public: // IMutableRegistryHub
- virtual void registerReporter( std::string const& name, IReporterFactory* factory ) {
- m_reporterRegistry.registerReporter( name, factory );
- }
- virtual void registerTest( TestCase const& testInfo ) {
- m_testCaseRegistry.registerTest( testInfo );
- }
- virtual void registerTranslator( const IExceptionTranslator* translator ) {
- m_exceptionTranslatorRegistry.registerTranslator( translator );
- }
-
- private:
- TestRegistry m_testCaseRegistry;
- ReporterRegistry m_reporterRegistry;
- ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
- };
-
- // Single, global, instance
- inline RegistryHub*& getTheRegistryHub() {
- static RegistryHub* theRegistryHub = NULL;
- if( !theRegistryHub )
- theRegistryHub = new RegistryHub();
- return theRegistryHub;
- }
- }
-
- IRegistryHub& getRegistryHub() {
- return *getTheRegistryHub();
- }
- IMutableRegistryHub& getMutableRegistryHub() {
- return *getTheRegistryHub();
- }
- void cleanUp() {
- delete getTheRegistryHub();
- getTheRegistryHub() = NULL;
- cleanUpContext();
- }
- std::string translateActiveException() {
- return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
- }
-
-} // end namespace Catch
-
-// #included from: catch_notimplemented_exception.hpp
-#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
-
-#include <ostream>
-
-namespace Catch {
-
- NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
- : m_lineInfo( lineInfo ) {
- std::ostringstream oss;
- oss << lineInfo << ": function ";
- oss << "not implemented";
- m_what = oss.str();
- }
-
- const char* NotImplementedException::what() const CATCH_NOEXCEPT {
- return m_what.c_str();
- }
-
-} // end namespace Catch
-
-// #included from: catch_context_impl.hpp
-#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
-
-// #included from: catch_stream.hpp
-#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
-
-// #included from: catch_streambuf.h
-#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
-
-#include <streambuf>
-
-namespace Catch {
-
- class StreamBufBase : public std::streambuf {
- public:
- virtual ~StreamBufBase() CATCH_NOEXCEPT;
- };
-}
-
-#include <stdexcept>
-#include <cstdio>
-#include <iostream>
-
-namespace Catch {
-
- template<typename WriterF, size_t bufferSize=256>
- class StreamBufImpl : public StreamBufBase {
- char data[bufferSize];
- WriterF m_writer;
-
- public:
- StreamBufImpl() {
- setp( data, data + sizeof(data) );
- }
-
- ~StreamBufImpl() CATCH_NOEXCEPT {
- sync();
- }
-
- private:
- int overflow( int c ) {
- sync();
-
- if( c != EOF ) {
- if( pbase() == epptr() )
- m_writer( std::string( 1, static_cast<char>( c ) ) );
- else
- sputc( static_cast<char>( c ) );
- }
- return 0;
- }
-
- int sync() {
- if( pbase() != pptr() ) {
- m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
- setp( pbase(), epptr() );
- }
- return 0;
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
-
- struct OutputDebugWriter {
-
- void operator()( std::string const&str ) {
- writeToDebugConsole( str );
- }
- };
-
- Stream::Stream()
- : streamBuf( NULL ), isOwned( false )
- {}
-
- Stream::Stream( std::streambuf* _streamBuf, bool _isOwned )
- : streamBuf( _streamBuf ), isOwned( _isOwned )
- {}
-
- void Stream::release() {
- if( isOwned ) {
- delete streamBuf;
- streamBuf = NULL;
- isOwned = false;
- }
- }
-
-#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement this functions
- std::ostream& cout() {
- return std::cout;
- }
- std::ostream& cerr() {
- return std::cerr;
- }
-#endif
-}
-
-namespace Catch {
-
- class Context : public IMutableContext {
-
- Context() : m_config( NULL ), m_runner( NULL ), m_resultCapture( NULL ) {}
- Context( Context const& );
- void operator=( Context const& );
-
- public: // IContext
- virtual IResultCapture* getResultCapture() {
- return m_resultCapture;
- }
- virtual IRunner* getRunner() {
- return m_runner;
- }
- virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
- return getGeneratorsForCurrentTest()
- .getGeneratorInfo( fileInfo, totalSize )
- .getCurrentIndex();
- }
- virtual bool advanceGeneratorsForCurrentTest() {
- IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
- return generators && generators->moveNext();
- }
-
- virtual Ptr<IConfig const> getConfig() const {
- return m_config;
- }
-
- public: // IMutableContext
- virtual void setResultCapture( IResultCapture* resultCapture ) {
- m_resultCapture = resultCapture;
- }
- virtual void setRunner( IRunner* runner ) {
- m_runner = runner;
- }
- virtual void setConfig( Ptr<IConfig const> const& config ) {
- m_config = config;
- }
-
- friend IMutableContext& getCurrentMutableContext();
-
- private:
- IGeneratorsForTest* findGeneratorsForCurrentTest() {
- std::string testName = getResultCapture()->getCurrentTestName();
-
- std::map<std::string, IGeneratorsForTest*>::const_iterator it =
- m_generatorsByTestName.find( testName );
- return it != m_generatorsByTestName.end()
- ? it->second
- : NULL;
- }
-
- IGeneratorsForTest& getGeneratorsForCurrentTest() {
- IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
- if( !generators ) {
- std::string testName = getResultCapture()->getCurrentTestName();
- generators = createGeneratorsForTest();
- m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
- }
- return *generators;
- }
-
- private:
- Ptr<IConfig const> m_config;
- IRunner* m_runner;
- IResultCapture* m_resultCapture;
- std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
- };
-
- namespace {
- Context* currentContext = NULL;
- }
- IMutableContext& getCurrentMutableContext() {
- if( !currentContext )
- currentContext = new Context();
- return *currentContext;
- }
- IContext& getCurrentContext() {
- return getCurrentMutableContext();
- }
-
- Stream createStream( std::string const& streamName ) {
- if( streamName == "stdout" ) return Stream( Catch::cout().rdbuf(), false );
- if( streamName == "stderr" ) return Stream( Catch::cerr().rdbuf(), false );
- if( streamName == "debug" ) return Stream( new StreamBufImpl<OutputDebugWriter>, true );
-
- throw std::domain_error( "Unknown stream: " + streamName );
- }
-
- void cleanUpContext() {
- delete currentContext;
- currentContext = NULL;
- }
-}
-
-// #included from: catch_console_colour_impl.hpp
-#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
-
-namespace Catch {
- namespace {
-
- struct IColourImpl {
- virtual ~IColourImpl() {}
- virtual void use( Colour::Code _colourCode ) = 0;
- };
-
- struct NoColourImpl : IColourImpl {
- void use( Colour::Code ) {}
-
- static IColourImpl* instance() {
- static NoColourImpl s_instance;
- return &s_instance;
- }
- };
-
- } // anon namespace
-} // namespace Catch
-
-#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
-# ifdef CATCH_PLATFORM_WINDOWS
-# define CATCH_CONFIG_COLOUR_WINDOWS
-# else
-# define CATCH_CONFIG_COLOUR_ANSI
-# endif
-#endif
-
-#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
-
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
-
-#ifdef __AFXDLL
-#include <AfxWin.h>
-#else
-#include <windows.h>
-#endif
-
-namespace Catch {
-namespace {
-
- class Win32ColourImpl : public IColourImpl {
- public:
- Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
- {
- CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
- GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
- originalAttributes = csbiInfo.wAttributes;
- }
-
- virtual void use( Colour::Code _colourCode ) {
- switch( _colourCode ) {
- case Colour::None: return setTextAttribute( originalAttributes );
- case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
- case Colour::Red: return setTextAttribute( FOREGROUND_RED );
- case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
- case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
- case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
- case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
- case Colour::Grey: return setTextAttribute( 0 );
-
- case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
- case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
- case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
- case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
-
- case Colour::Bright: throw std::logic_error( "not a colour" );
- }
- }
-
- private:
- void setTextAttribute( WORD _textAttribute ) {
- SetConsoleTextAttribute( stdoutHandle, _textAttribute );
- }
- HANDLE stdoutHandle;
- WORD originalAttributes;
- };
-
- IColourImpl* platformColourInstance() {
- static Win32ColourImpl s_instance;
- return &s_instance;
- }
-
-} // end anon namespace
-} // end namespace Catch
-
-#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
-
-#include <unistd.h>
-
-namespace Catch {
-namespace {
-
- // use POSIX/ ANSI console terminal codes
- // Thanks to Adam Strzelecki for original contribution
- // (http://github.com/nanoant)
- // https://github.com/philsquared/Catch/pull/131
- class PosixColourImpl : public IColourImpl {
- public:
- virtual void use( Colour::Code _colourCode ) {
- switch( _colourCode ) {
- case Colour::None:
- case Colour::White: return setColour( "[0m" );
- case Colour::Red: return setColour( "[0;31m" );
- case Colour::Green: return setColour( "[0;32m" );
- case Colour::Blue: return setColour( "[0:34m" );
- case Colour::Cyan: return setColour( "[0;36m" );
- case Colour::Yellow: return setColour( "[0;33m" );
- case Colour::Grey: return setColour( "[1;30m" );
-
- case Colour::LightGrey: return setColour( "[0;37m" );
- case Colour::BrightRed: return setColour( "[1;31m" );
- case Colour::BrightGreen: return setColour( "[1;32m" );
- case Colour::BrightWhite: return setColour( "[1;37m" );
-
- case Colour::Bright: throw std::logic_error( "not a colour" );
- }
- }
- static IColourImpl* instance() {
- static PosixColourImpl s_instance;
- return &s_instance;
- }
-
- private:
- void setColour( const char* _escapeCode ) {
- Catch::cout() << '\033' << _escapeCode;
- }
- };
-
- IColourImpl* platformColourInstance() {
- Ptr<IConfig const> config = getCurrentContext().getConfig();
- return (config && config->forceColour()) || isatty(STDOUT_FILENO)
- ? PosixColourImpl::instance()
- : NoColourImpl::instance();
- }
-
-} // end anon namespace
-} // end namespace Catch
-
-#else // not Windows or ANSI ///////////////////////////////////////////////
-
-namespace Catch {
-
- static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
-
-} // end namespace Catch
-
-#endif // Windows/ ANSI/ None
-
-namespace Catch {
-
- Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
- Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
- Colour::~Colour(){ if( !m_moved ) use( None ); }
-
- void Colour::use( Code _colourCode ) {
- static IColourImpl* impl = isDebuggerActive()
- ? NoColourImpl::instance()
- : platformColourInstance();
- impl->use( _colourCode );
- }
-
-} // end namespace Catch
-
-// #included from: catch_generators_impl.hpp
-#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
-
-#include <vector>
-#include <string>
-#include <map>
-
-namespace Catch {
-
- struct GeneratorInfo : IGeneratorInfo {
-
- GeneratorInfo( std::size_t size )
- : m_size( size ),
- m_currentIndex( 0 )
- {}
-
- bool moveNext() {
- if( ++m_currentIndex == m_size ) {
- m_currentIndex = 0;
- return false;
- }
- return true;
- }
-
- std::size_t getCurrentIndex() const {
- return m_currentIndex;
- }
-
- std::size_t m_size;
- std::size_t m_currentIndex;
- };
-
- ///////////////////////////////////////////////////////////////////////////
-
- class GeneratorsForTest : public IGeneratorsForTest {
-
- public:
- ~GeneratorsForTest() {
- deleteAll( m_generatorsInOrder );
- }
-
- IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
- std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
- if( it == m_generatorsByName.end() ) {
- IGeneratorInfo* info = new GeneratorInfo( size );
- m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
- m_generatorsInOrder.push_back( info );
- return *info;
- }
- return *it->second;
- }
-
- bool moveNext() {
- std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
- std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
- for(; it != itEnd; ++it ) {
- if( (*it)->moveNext() )
- return true;
- }
- return false;
- }
-
- private:
- std::map<std::string, IGeneratorInfo*> m_generatorsByName;
- std::vector<IGeneratorInfo*> m_generatorsInOrder;
- };
-
- IGeneratorsForTest* createGeneratorsForTest()
- {
- return new GeneratorsForTest();
- }
-
-} // end namespace Catch
-
-// #included from: catch_assertionresult.hpp
-#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
-
-namespace Catch {
-
- AssertionInfo::AssertionInfo( std::string const& _macroName,
- SourceLineInfo const& _lineInfo,
- std::string const& _capturedExpression,
- ResultDisposition::Flags _resultDisposition )
- : macroName( _macroName ),
- lineInfo( _lineInfo ),
- capturedExpression( _capturedExpression ),
- resultDisposition( _resultDisposition )
- {}
-
- AssertionResult::AssertionResult() {}
-
- AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
- : m_info( info ),
- m_resultData( data )
- {}
-
- AssertionResult::~AssertionResult() {}
-
- // Result was a success
- bool AssertionResult::succeeded() const {
- return Catch::isOk( m_resultData.resultType );
- }
-
- // Result was a success, or failure is suppressed
- bool AssertionResult::isOk() const {
- return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
- }
-
- ResultWas::OfType AssertionResult::getResultType() const {
- return m_resultData.resultType;
- }
-
- bool AssertionResult::hasExpression() const {
- return !m_info.capturedExpression.empty();
- }
-
- bool AssertionResult::hasMessage() const {
- return !m_resultData.message.empty();
- }
-
- std::string AssertionResult::getExpression() const {
- if( isFalseTest( m_info.resultDisposition ) )
- return "!" + m_info.capturedExpression;
- else
- return m_info.capturedExpression;
- }
- std::string AssertionResult::getExpressionInMacro() const {
- if( m_info.macroName.empty() )
- return m_info.capturedExpression;
- else
- return m_info.macroName + "( " + m_info.capturedExpression + " )";
- }
-
- bool AssertionResult::hasExpandedExpression() const {
- return hasExpression() && getExpandedExpression() != getExpression();
- }
-
- std::string AssertionResult::getExpandedExpression() const {
- return m_resultData.reconstructedExpression;
- }
-
- std::string AssertionResult::getMessage() const {
- return m_resultData.message;
- }
- SourceLineInfo AssertionResult::getSourceInfo() const {
- return m_info.lineInfo;
- }
-
- std::string AssertionResult::getTestMacroName() const {
- return m_info.macroName;
- }
-
-} // end namespace Catch
-
-// #included from: catch_test_case_info.hpp
-#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
-
-namespace Catch {
-
- inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
- if( startsWith( tag, "." ) ||
- tag == "hide" ||
- tag == "!hide" )
- return TestCaseInfo::IsHidden;
- else if( tag == "!throws" )
- return TestCaseInfo::Throws;
- else if( tag == "!shouldfail" )
- return TestCaseInfo::ShouldFail;
- else if( tag == "!mayfail" )
- return TestCaseInfo::MayFail;
- else
- return TestCaseInfo::None;
- }
- inline bool isReservedTag( std::string const& tag ) {
- return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
- }
- inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
- if( isReservedTag( tag ) ) {
- {
- Colour colourGuard( Colour::Red );
- Catch::cerr()
- << "Tag name [" << tag << "] not allowed.\n"
- << "Tag names starting with non alpha-numeric characters are reserved\n";
- }
- {
- Colour colourGuard( Colour::FileName );
- Catch::cerr() << _lineInfo << std::endl;
- }
- exit(1);
- }
- }
-
- TestCase makeTestCase( ITestCase* _testCase,
- std::string const& _className,
- std::string const& _name,
- std::string const& _descOrTags,
- SourceLineInfo const& _lineInfo )
- {
- bool isHidden( startsWith( _name, "./" ) ); // Legacy support
-
- // Parse out tags
- std::set<std::string> tags;
- std::string desc, tag;
- bool inTag = false;
- for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
- char c = _descOrTags[i];
- if( !inTag ) {
- if( c == '[' )
- inTag = true;
- else
- desc += c;
- }
- else {
- if( c == ']' ) {
- TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
- if( prop == TestCaseInfo::IsHidden )
- isHidden = true;
- else if( prop == TestCaseInfo::None )
- enforceNotReservedTag( tag, _lineInfo );
-
- tags.insert( tag );
- tag.clear();
- inTag = false;
- }
- else
- tag += c;
- }
- }
- if( isHidden ) {
- tags.insert( "hide" );
- tags.insert( "." );
- }
-
- TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
- return TestCase( _testCase, info );
- }
-
- TestCaseInfo::TestCaseInfo( std::string const& _name,
- std::string const& _className,
- std::string const& _description,
- std::set<std::string> const& _tags,
- SourceLineInfo const& _lineInfo )
- : name( _name ),
- className( _className ),
- description( _description ),
- tags( _tags ),
- lineInfo( _lineInfo ),
- properties( None )
- {
- std::ostringstream oss;
- for( std::set<std::string>::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it ) {
- oss << "[" << *it << "]";
- std::string lcaseTag = toLower( *it );
- properties = static_cast<SpecialProperties>( properties | parseSpecialTag( lcaseTag ) );
- lcaseTags.insert( lcaseTag );
- }
- tagsAsString = oss.str();
- }
-
- TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
- : name( other.name ),
- className( other.className ),
- description( other.description ),
- tags( other.tags ),
- lcaseTags( other.lcaseTags ),
- tagsAsString( other.tagsAsString ),
- lineInfo( other.lineInfo ),
- properties( other.properties )
- {}
-
- bool TestCaseInfo::isHidden() const {
- return ( properties & IsHidden ) != 0;
- }
- bool TestCaseInfo::throws() const {
- return ( properties & Throws ) != 0;
- }
- bool TestCaseInfo::okToFail() const {
- return ( properties & (ShouldFail | MayFail ) ) != 0;
- }
- bool TestCaseInfo::expectedToFail() const {
- return ( properties & (ShouldFail ) ) != 0;
- }
-
- TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
-
- TestCase::TestCase( TestCase const& other )
- : TestCaseInfo( other ),
- test( other.test )
- {}
-
- TestCase TestCase::withName( std::string const& _newName ) const {
- TestCase other( *this );
- other.name = _newName;
- return other;
- }
-
- void TestCase::swap( TestCase& other ) {
- test.swap( other.test );
- name.swap( other.name );
- className.swap( other.className );
- description.swap( other.description );
- tags.swap( other.tags );
- lcaseTags.swap( other.lcaseTags );
- tagsAsString.swap( other.tagsAsString );
- std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
- std::swap( lineInfo, other.lineInfo );
- }
-
- void TestCase::invoke() const {
- test->invoke();
- }
-
- bool TestCase::operator == ( TestCase const& other ) const {
- return test.get() == other.test.get() &&
- name == other.name &&
- className == other.className;
- }
-
- bool TestCase::operator < ( TestCase const& other ) const {
- return name < other.name;
- }
- TestCase& TestCase::operator = ( TestCase const& other ) {
- TestCase temp( other );
- swap( temp );
- return *this;
- }
-
- TestCaseInfo const& TestCase::getTestCaseInfo() const
- {
- return *this;
- }
-
-} // end namespace Catch
-
-// #included from: catch_version.hpp
-#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
-
-namespace Catch {
-
- Version::Version
- ( unsigned int _majorVersion,
- unsigned int _minorVersion,
- unsigned int _patchNumber,
- std::string const& _branchName,
- unsigned int _buildNumber )
- : majorVersion( _majorVersion ),
- minorVersion( _minorVersion ),
- patchNumber( _patchNumber ),
- branchName( _branchName ),
- buildNumber( _buildNumber )
- {}
-
- std::ostream& operator << ( std::ostream& os, Version const& version ) {
- os << version.majorVersion << "."
- << version.minorVersion << "."
- << version.patchNumber;
-
- if( !version.branchName.empty() ) {
- os << "-" << version.branchName
- << "." << version.buildNumber;
- }
- return os;
- }
-
- Version libraryVersion( 1, 2, 1, "", 0 );
-
-}
-
-// #included from: catch_message.hpp
-#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
-
-namespace Catch {
-
- MessageInfo::MessageInfo( std::string const& _macroName,
- SourceLineInfo const& _lineInfo,
- ResultWas::OfType _type )
- : macroName( _macroName ),
- lineInfo( _lineInfo ),
- type( _type ),
- sequence( ++globalCount )
- {}
-
- // This may need protecting if threading support is added
- unsigned int MessageInfo::globalCount = 0;
-
- ////////////////////////////////////////////////////////////////////////////
-
- ScopedMessage::ScopedMessage( MessageBuilder const& builder )
- : m_info( builder.m_info )
- {
- m_info.message = builder.m_stream.str();
- getResultCapture().pushScopedMessage( m_info );
- }
- ScopedMessage::ScopedMessage( ScopedMessage const& other )
- : m_info( other.m_info )
- {}
-
- ScopedMessage::~ScopedMessage() {
- getResultCapture().popScopedMessage( m_info );
- }
-
-} // end namespace Catch
-
-// #included from: catch_legacy_reporter_adapter.hpp
-#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
-
-// #included from: catch_legacy_reporter_adapter.h
-#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
-
-namespace Catch
-{
- // Deprecated
- struct IReporter : IShared {
- virtual ~IReporter();
-
- virtual bool shouldRedirectStdout() const = 0;
-
- virtual void StartTesting() = 0;
- virtual void EndTesting( Totals const& totals ) = 0;
- virtual void StartGroup( std::string const& groupName ) = 0;
- virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
- virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
- virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
- virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
- virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
- virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
- virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
- virtual void Aborted() = 0;
- virtual void Result( AssertionResult const& result ) = 0;
- };
-
- class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
- {
- public:
- LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
- virtual ~LegacyReporterAdapter();
-
- virtual ReporterPreferences getPreferences() const;
- virtual void noMatchingTestCases( std::string const& );
- virtual void testRunStarting( TestRunInfo const& );
- virtual void testGroupStarting( GroupInfo const& groupInfo );
- virtual void testCaseStarting( TestCaseInfo const& testInfo );
- virtual void sectionStarting( SectionInfo const& sectionInfo );
- virtual void assertionStarting( AssertionInfo const& );
- virtual bool assertionEnded( AssertionStats const& assertionStats );
- virtual void sectionEnded( SectionStats const& sectionStats );
- virtual void testCaseEnded( TestCaseStats const& testCaseStats );
- virtual void testGroupEnded( TestGroupStats const& testGroupStats );
- virtual void testRunEnded( TestRunStats const& testRunStats );
- virtual void skipTest( TestCaseInfo const& );
-
- private:
- Ptr<IReporter> m_legacyReporter;
- };
-}
-
-namespace Catch
-{
- LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
- : m_legacyReporter( legacyReporter )
- {}
- LegacyReporterAdapter::~LegacyReporterAdapter() {}
-
- ReporterPreferences LegacyReporterAdapter::getPreferences() const {
- ReporterPreferences prefs;
- prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
- return prefs;
- }
-
- void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
- void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
- m_legacyReporter->StartTesting();
- }
- void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
- m_legacyReporter->StartGroup( groupInfo.name );
- }
- void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
- m_legacyReporter->StartTestCase( testInfo );
- }
- void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
- m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
- }
- void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
- // Not on legacy interface
- }
-
- bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
- if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
- for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
- it != itEnd;
- ++it ) {
- if( it->type == ResultWas::Info ) {
- ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
- rb << it->message;
- rb.setResultType( ResultWas::Info );
- AssertionResult result = rb.build();
- m_legacyReporter->Result( result );
- }
- }
- }
- m_legacyReporter->Result( assertionStats.assertionResult );
- return true;
- }
- void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
- if( sectionStats.missingAssertions )
- m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
- m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
- }
- void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
- m_legacyReporter->EndTestCase
- ( testCaseStats.testInfo,
- testCaseStats.totals,
- testCaseStats.stdOut,
- testCaseStats.stdErr );
- }
- void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
- if( testGroupStats.aborting )
- m_legacyReporter->Aborted();
- m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
- }
- void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
- m_legacyReporter->EndTesting( testRunStats.totals );
- }
- void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
- }
-}
-
-// #included from: catch_timer.hpp
-
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wc++11-long-long"
-#endif
-
-#ifdef CATCH_PLATFORM_WINDOWS
-#include <windows.h>
-#else
-#include <sys/time.h>
-#endif
-
-namespace Catch {
-
- namespace {
-#ifdef CATCH_PLATFORM_WINDOWS
- uint64_t getCurrentTicks() {
- static uint64_t hz=0, hzo=0;
- if (!hz) {
- QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
- QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
- }
- uint64_t t;
- QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
- return ((t-hzo)*1000000)/hz;
- }
-#else
- uint64_t getCurrentTicks() {
- timeval t;
- gettimeofday(&t,NULL);
- return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
- }
-#endif
- }
-
- void Timer::start() {
- m_ticks = getCurrentTicks();
- }
- unsigned int Timer::getElapsedMicroseconds() const {
- return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
- }
- unsigned int Timer::getElapsedMilliseconds() const {
- return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
- }
- double Timer::getElapsedSeconds() const {
- return getElapsedMicroseconds()/1000000.0;
- }
-
-} // namespace Catch
-
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
-// #included from: catch_common.hpp
-#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
-
-namespace Catch {
-
- bool startsWith( std::string const& s, std::string const& prefix ) {
- return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
- }
- bool endsWith( std::string const& s, std::string const& suffix ) {
- return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
- }
- bool contains( std::string const& s, std::string const& infix ) {
- return s.find( infix ) != std::string::npos;
- }
- void toLowerInPlace( std::string& s ) {
- std::transform( s.begin(), s.end(), s.begin(), ::tolower );
- }
- std::string toLower( std::string const& s ) {
- std::string lc = s;
- toLowerInPlace( lc );
- return lc;
- }
- std::string trim( std::string const& str ) {
- static char const* whitespaceChars = "\n\r\t ";
- std::string::size_type start = str.find_first_not_of( whitespaceChars );
- std::string::size_type end = str.find_last_not_of( whitespaceChars );
-
- return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
- }
-
- bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
- bool replaced = false;
- std::size_t i = str.find( replaceThis );
- while( i != std::string::npos ) {
- replaced = true;
- str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
- if( i < str.size()-withThis.size() )
- i = str.find( replaceThis, i+withThis.size() );
- else
- i = std::string::npos;
- }
- return replaced;
- }
-
- pluralise::pluralise( std::size_t count, std::string const& label )
- : m_count( count ),
- m_label( label )
- {}
-
- std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
- os << pluraliser.m_count << " " << pluraliser.m_label;
- if( pluraliser.m_count != 1 )
- os << "s";
- return os;
- }
-
- SourceLineInfo::SourceLineInfo() : line( 0 ){}
- SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
- : file( _file ),
- line( _line )
- {}
- SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
- : file( other.file ),
- line( other.line )
- {}
- bool SourceLineInfo::empty() const {
- return file.empty();
- }
- bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
- return line == other.line && file == other.file;
- }
- bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
- return line < other.line || ( line == other.line && file < other.file );
- }
-
- std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
-#ifndef __GNUG__
- os << info.file << "(" << info.line << ")";
-#else
- os << info.file << ":" << info.line;
-#endif
- return os;
- }
-
- void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
- std::ostringstream oss;
- oss << locationInfo << ": Internal Catch error: '" << message << "'";
- if( alwaysTrue() )
- throw std::logic_error( oss.str() );
- }
-}
-
-// #included from: catch_section.hpp
-#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
-
-namespace Catch {
-
- SectionInfo::SectionInfo
- ( SourceLineInfo const& _lineInfo,
- std::string const& _name,
- std::string const& _description )
- : name( _name ),
- description( _description ),
- lineInfo( _lineInfo )
- {}
-
- Section::Section( SectionInfo const& info )
- : m_info( info ),
- m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
- {
- m_timer.start();
- }
-
- Section::~Section() {
- if( m_sectionIncluded )
- getResultCapture().sectionEnded( m_info, m_assertions, m_timer.getElapsedSeconds() );
- }
-
- // This indicates whether the section should be executed or not
- Section::operator bool() const {
- return m_sectionIncluded;
- }
-
-} // end namespace Catch
-
-// #included from: catch_debugger.hpp
-#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
-
-#include <iostream>
-
-#ifdef CATCH_PLATFORM_MAC
-
- #include <assert.h>
- #include <stdbool.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <sys/sysctl.h>
-
- namespace Catch{
-
- // The following function is taken directly from the following technical note:
- // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
-
- // Returns true if the current process is being debugged (either
- // running under the debugger or has a debugger attached post facto).
- bool isDebuggerActive(){
-
- int mib[4];
- struct kinfo_proc info;
- size_t size;
-
- // Initialize the flags so that, if sysctl fails for some bizarre
- // reason, we get a predictable result.
-
- info.kp_proc.p_flag = 0;
-
- // Initialize mib, which tells sysctl the info we want, in this case
- // we're looking for information about a specific process ID.
-
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROC;
- mib[2] = KERN_PROC_PID;
- mib[3] = getpid();
-
- // Call sysctl.
-
- size = sizeof(info);
- if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0) != 0 ) {
- Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
- return false;
- }
-
- // We're being debugged if the P_TRACED flag is set.
-
- return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
- }
- } // namespace Catch
-
-#elif defined(_MSC_VER)
- extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
- namespace Catch {
- bool isDebuggerActive() {
- return IsDebuggerPresent() != 0;
- }
- }
-#elif defined(__MINGW32__)
- extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
- namespace Catch {
- bool isDebuggerActive() {
- return IsDebuggerPresent() != 0;
- }
- }
-#else
- namespace Catch {
- inline bool isDebuggerActive() { return false; }
- }
-#endif // Platform
-
-#ifdef CATCH_PLATFORM_WINDOWS
- extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
- namespace Catch {
- void writeToDebugConsole( std::string const& text ) {
- ::OutputDebugStringA( text.c_str() );
- }
- }
-#else
- namespace Catch {
- void writeToDebugConsole( std::string const& text ) {
- // !TBD: Need a version for Mac/ XCode and other IDEs
- Catch::cout() << text;
- }
- }
-#endif // Platform
-
-// #included from: catch_tostring.hpp
-#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
-
-namespace Catch {
-
-namespace Detail {
-
- std::string unprintableString = "{?}";
-
- namespace {
- struct Endianness {
- enum Arch { Big, Little };
-
- static Arch which() {
- union _{
- int asInt;
- char asChar[sizeof (int)];
- } u;
-
- u.asInt = 1;
- return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
- }
- };
- }
-
- std::string rawMemoryToString( const void *object, std::size_t size )
- {
- // Reverse order for little endian architectures
- int i = 0, end = static_cast<int>( size ), inc = 1;
- if( Endianness::which() == Endianness::Little ) {
- i = end-1;
- end = inc = -1;
- }
-
- unsigned char const *bytes = static_cast<unsigned char const *>(object);
- std::ostringstream os;
- os << "0x" << std::setfill('0') << std::hex;
- for( ; i != end; i += inc )
- os << std::setw(2) << static_cast<unsigned>(bytes[i]);
- return os.str();
- }
-}
-
-std::string toString( std::string const& value ) {
- std::string s = value;
- if( getCurrentContext().getConfig()->showInvisibles() ) {
- for(size_t i = 0; i < s.size(); ++i ) {
- std::string subs;
- switch( s[i] ) {
- case '\n': subs = "\\n"; break;
- case '\t': subs = "\\t"; break;
- default: break;
- }
- if( !subs.empty() ) {
- s = s.substr( 0, i ) + subs + s.substr( i+1 );
- ++i;
- }
- }
- }
- return "\"" + s + "\"";
-}
-std::string toString( std::wstring const& value ) {
-
- std::string s;
- s.reserve( value.size() );
- for(size_t i = 0; i < value.size(); ++i )
- s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
- return Catch::toString( s );
-}
-
-std::string toString( const char* const value ) {
- return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
-}
-
-std::string toString( char* const value ) {
- return Catch::toString( static_cast<const char*>( value ) );
-}
-
-std::string toString( const wchar_t* const value )
-{
- return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
-}
-
-std::string toString( wchar_t* const value )
-{
- return Catch::toString( static_cast<const wchar_t*>( value ) );
-}
-
-std::string toString( int value ) {
- std::ostringstream oss;
- oss << value;
- if( value >= 255 )
- oss << " (0x" << std::hex << value << ")";
- return oss.str();
-}
-
-std::string toString( unsigned long value ) {
- std::ostringstream oss;
- oss << value;
- if( value >= 255 )
- oss << " (0x" << std::hex << value << ")";
- return oss.str();
-}
-
-std::string toString( unsigned int value ) {
- return Catch::toString( static_cast<unsigned long>( value ) );
-}
-
-template<typename T>
-std::string fpToString( T value, int precision ) {
- std::ostringstream oss;
- oss << std::setprecision( precision )
- << std::fixed
- << value;
- std::string d = oss.str();
- std::size_t i = d.find_last_not_of( '0' );
- if( i != std::string::npos && i != d.size()-1 ) {
- if( d[i] == '.' )
- i++;
- d = d.substr( 0, i+1 );
- }
- return d;
-}
-
-std::string toString( const double value ) {
- return fpToString( value, 10 );
-}
-std::string toString( const float value ) {
- return fpToString( value, 5 ) + "f";
-}
-
-std::string toString( bool value ) {
- return value ? "true" : "false";
-}
-
-std::string toString( char value ) {
- return value < ' '
- ? toString( static_cast<unsigned int>( value ) )
- : Detail::makeString( value );
-}
-
-std::string toString( signed char value ) {
- return toString( static_cast<char>( value ) );
-}
-
-std::string toString( unsigned char value ) {
- return toString( static_cast<char>( value ) );
-}
-
-#ifdef CATCH_CONFIG_CPP11_NULLPTR
-std::string toString( std::nullptr_t ) {
- return "nullptr";
-}
-#endif
-
-#ifdef __OBJC__
- std::string toString( NSString const * const& nsstring ) {
- if( !nsstring )
- return "nil";
- return "@" + toString([nsstring UTF8String]);
- }
- std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
- if( !nsstring )
- return "nil";
- return "@" + toString([nsstring UTF8String]);
- }
- std::string toString( NSObject* const& nsObject ) {
- return toString( [nsObject description] );
- }
-#endif
-
-} // end namespace Catch
-
-// #included from: catch_result_builder.hpp
-#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
-
-namespace Catch {
-
- ResultBuilder::ResultBuilder( char const* macroName,
- SourceLineInfo const& lineInfo,
- char const* capturedExpression,
- ResultDisposition::Flags resultDisposition )
- : m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition ),
- m_shouldDebugBreak( false ),
- m_shouldThrow( false )
- {}
-
- ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
- m_data.resultType = result;
- return *this;
- }
- ResultBuilder& ResultBuilder::setResultType( bool result ) {
- m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
- return *this;
- }
- ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) {
- m_exprComponents.lhs = lhs;
- return *this;
- }
- ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) {
- m_exprComponents.rhs = rhs;
- return *this;
- }
- ResultBuilder& ResultBuilder::setOp( std::string const& op ) {
- m_exprComponents.op = op;
- return *this;
- }
-
- void ResultBuilder::endExpression() {
- m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );
- captureExpression();
- }
-
- void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
- m_assertionInfo.resultDisposition = resultDisposition;
- m_stream.oss << Catch::translateActiveException();
- captureResult( ResultWas::ThrewException );
- }
-
- void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
- setResultType( resultType );
- captureExpression();
- }
-
- void ResultBuilder::captureExpression() {
- AssertionResult result = build();
- getResultCapture().assertionEnded( result );
-
- if( !result.isOk() ) {
- if( getCurrentContext().getConfig()->shouldDebugBreak() )
- m_shouldDebugBreak = true;
- if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
- m_shouldThrow = true;
- }
- }
- void ResultBuilder::react() {
- if( m_shouldThrow )
- throw Catch::TestFailureException();
- }
-
- bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }
- bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }
-
- AssertionResult ResultBuilder::build() const
- {
- assert( m_data.resultType != ResultWas::Unknown );
-
- AssertionResultData data = m_data;
-
- // Flip bool results if testFalse is set
- if( m_exprComponents.testFalse ) {
- if( data.resultType == ResultWas::Ok )
- data.resultType = ResultWas::ExpressionFailed;
- else if( data.resultType == ResultWas::ExpressionFailed )
- data.resultType = ResultWas::Ok;
- }
-
- data.message = m_stream.oss.str();
- data.reconstructedExpression = reconstructExpression();
- if( m_exprComponents.testFalse ) {
- if( m_exprComponents.op == "" )
- data.reconstructedExpression = "!" + data.reconstructedExpression;
- else
- data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
- }
- return AssertionResult( m_assertionInfo, data );
- }
- std::string ResultBuilder::reconstructExpression() const {
- if( m_exprComponents.op == "" )
- return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
- else if( m_exprComponents.op == "matches" )
- return m_exprComponents.lhs + " " + m_exprComponents.rhs;
- else if( m_exprComponents.op != "!" ) {
- if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
- m_exprComponents.lhs.find("\n") == std::string::npos &&
- m_exprComponents.rhs.find("\n") == std::string::npos )
- return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
- else
- return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs;
- }
- else
- return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}";
- }
-
-} // end namespace Catch
-
-// #included from: catch_tag_alias_registry.hpp
-#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
-
-// #included from: catch_tag_alias_registry.h
-#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
-
-#include <map>
-
-namespace Catch {
-
- class TagAliasRegistry : public ITagAliasRegistry {
- public:
- virtual ~TagAliasRegistry();
- virtual Option<TagAlias> find( std::string const& alias ) const;
- virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
- void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
- static TagAliasRegistry& get();
-
- private:
- std::map<std::string, TagAlias> m_registry;
- };
-
-} // end namespace Catch
-
-#include <map>
-#include <iostream>
-
-namespace Catch {
-
- TagAliasRegistry::~TagAliasRegistry() {}
-
- Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
- std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
- if( it != m_registry.end() )
- return it->second;
- else
- return Option<TagAlias>();
- }
-
- std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
- std::string expandedTestSpec = unexpandedTestSpec;
- for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
- it != itEnd;
- ++it ) {
- std::size_t pos = expandedTestSpec.find( it->first );
- if( pos != std::string::npos ) {
- expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
- it->second.tag +
- expandedTestSpec.substr( pos + it->first.size() );
- }
- }
- return expandedTestSpec;
- }
-
- void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
-
- if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) {
- std::ostringstream oss;
- oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
- throw std::domain_error( oss.str().c_str() );
- }
- if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
- std::ostringstream oss;
- oss << "error: tag alias, \"" << alias << "\" already registered.\n"
- << "\tFirst seen at " << find(alias)->lineInfo << "\n"
- << "\tRedefined at " << lineInfo;
- throw std::domain_error( oss.str().c_str() );
- }
- }
-
- TagAliasRegistry& TagAliasRegistry::get() {
- static TagAliasRegistry instance;
- return instance;
-
- }
-
- ITagAliasRegistry::~ITagAliasRegistry() {}
- ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }
-
- RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
- try {
- TagAliasRegistry::get().add( alias, tag, lineInfo );
- }
- catch( std::exception& ex ) {
- Colour colourGuard( Colour::Red );
- Catch::cerr() << ex.what() << std::endl;
- exit(1);
- }
- }
-
-} // end namespace Catch
-
-// #included from: ../reporters/catch_reporter_xml.hpp
-#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
-
-// #included from: catch_reporter_bases.hpp
-#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
-
-#include <cstring>
-
-namespace Catch {
-
- struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
-
- StreamingReporterBase( ReporterConfig const& _config )
- : m_config( _config.fullConfig() ),
- stream( _config.stream() )
- {}
-
- virtual ~StreamingReporterBase();
-
- virtual void noMatchingTestCases( std::string const& ) {}
-
- virtual void testRunStarting( TestRunInfo const& _testRunInfo ) {
- currentTestRunInfo = _testRunInfo;
- }
- virtual void testGroupStarting( GroupInfo const& _groupInfo ) {
- currentGroupInfo = _groupInfo;
- }
-
- virtual void testCaseStarting( TestCaseInfo const& _testInfo ) {
- currentTestCaseInfo = _testInfo;
- }
- virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
- m_sectionStack.push_back( _sectionInfo );
- }
-
- virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) {
- m_sectionStack.pop_back();
- }
- virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) {
- currentTestCaseInfo.reset();
- }
- virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) {
- currentGroupInfo.reset();
- }
- virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) {
- currentTestCaseInfo.reset();
- currentGroupInfo.reset();
- currentTestRunInfo.reset();
- }
-
- virtual void skipTest( TestCaseInfo const& ) {
- // Don't do anything with this by default.
- // It can optionally be overridden in the derived class.
- }
-
- Ptr<IConfig> m_config;
- std::ostream& stream;
-
- LazyStat<TestRunInfo> currentTestRunInfo;
- LazyStat<GroupInfo> currentGroupInfo;
- LazyStat<TestCaseInfo> currentTestCaseInfo;
-
- std::vector<SectionInfo> m_sectionStack;
- };
-
- struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
- template<typename T, typename ChildNodeT>
- struct Node : SharedImpl<> {
- explicit Node( T const& _value ) : value( _value ) {}
- virtual ~Node() {}
-
- typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
- T value;
- ChildNodes children;
- };
- struct SectionNode : SharedImpl<> {
- explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
- virtual ~SectionNode();
-
- bool operator == ( SectionNode const& other ) const {
- return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
- }
- bool operator == ( Ptr<SectionNode> const& other ) const {
- return operator==( *other );
- }
-
- SectionStats stats;
- typedef std::vector<Ptr<SectionNode> > ChildSections;
- typedef std::vector<AssertionStats> Assertions;
- ChildSections childSections;
- Assertions assertions;
- std::string stdOut;
- std::string stdErr;
- };
-
- struct BySectionInfo {
- BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
- BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
- bool operator() ( Ptr<SectionNode> const& node ) const {
- return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
- }
- private:
- void operator=( BySectionInfo const& );
- SectionInfo const& m_other;
- };
-
- typedef Node<TestCaseStats, SectionNode> TestCaseNode;
- typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
- typedef Node<TestRunStats, TestGroupNode> TestRunNode;
-
- CumulativeReporterBase( ReporterConfig const& _config )
- : m_config( _config.fullConfig() ),
- stream( _config.stream() )
- {}
- ~CumulativeReporterBase();
-
- virtual void testRunStarting( TestRunInfo const& ) {}
- virtual void testGroupStarting( GroupInfo const& ) {}
-
- virtual void testCaseStarting( TestCaseInfo const& ) {}
-
- virtual void sectionStarting( SectionInfo const& sectionInfo ) {
- SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
- Ptr<SectionNode> node;
- if( m_sectionStack.empty() ) {
- if( !m_rootSection )
- m_rootSection = new SectionNode( incompleteStats );
- node = m_rootSection;
- }
- else {
- SectionNode& parentNode = *m_sectionStack.back();
- SectionNode::ChildSections::const_iterator it =
- std::find_if( parentNode.childSections.begin(),
- parentNode.childSections.end(),
- BySectionInfo( sectionInfo ) );
- if( it == parentNode.childSections.end() ) {
- node = new SectionNode( incompleteStats );
- parentNode.childSections.push_back( node );
- }
- else
- node = *it;
- }
- m_sectionStack.push_back( node );
- m_deepestSection = node;
- }
-
- virtual void assertionStarting( AssertionInfo const& ) {}
-
- virtual bool assertionEnded( AssertionStats const& assertionStats ) {
- assert( !m_sectionStack.empty() );
- SectionNode& sectionNode = *m_sectionStack.back();
- sectionNode.assertions.push_back( assertionStats );
- return true;
- }
- virtual void sectionEnded( SectionStats const& sectionStats ) {
- assert( !m_sectionStack.empty() );
- SectionNode& node = *m_sectionStack.back();
- node.stats = sectionStats;
- m_sectionStack.pop_back();
- }
- virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
- Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
- assert( m_sectionStack.size() == 0 );
- node->children.push_back( m_rootSection );
- m_testCases.push_back( node );
- m_rootSection.reset();
-
- assert( m_deepestSection );
- m_deepestSection->stdOut = testCaseStats.stdOut;
- m_deepestSection->stdErr = testCaseStats.stdErr;
- }
- virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
- Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
- node->children.swap( m_testCases );
- m_testGroups.push_back( node );
- }
- virtual void testRunEnded( TestRunStats const& testRunStats ) {
- Ptr<TestRunNode> node = new TestRunNode( testRunStats );
- node->children.swap( m_testGroups );
- m_testRuns.push_back( node );
- testRunEndedCumulative();
- }
- virtual void testRunEndedCumulative() = 0;
-
- virtual void skipTest( TestCaseInfo const& ) {}
-
- Ptr<IConfig> m_config;
- std::ostream& stream;
- std::vector<AssertionStats> m_assertions;
- std::vector<std::vector<Ptr<SectionNode> > > m_sections;
- std::vector<Ptr<TestCaseNode> > m_testCases;
- std::vector<Ptr<TestGroupNode> > m_testGroups;
-
- std::vector<Ptr<TestRunNode> > m_testRuns;
-
- Ptr<SectionNode> m_rootSection;
- Ptr<SectionNode> m_deepestSection;
- std::vector<Ptr<SectionNode> > m_sectionStack;
-
- };
-
- template<char C>
- char const* getLineOfChars() {
- static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
- if( !*line ) {
- memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
- line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
- }
- return line;
- }
-
-} // end namespace Catch
-
-// #included from: ../internal/catch_reporter_registrars.hpp
-#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
-
-namespace Catch {
-
- template<typename T>
- class LegacyReporterRegistrar {
-
- class ReporterFactory : public IReporterFactory {
- virtual IStreamingReporter* create( ReporterConfig const& config ) const {
- return new LegacyReporterAdapter( new T( config ) );
- }
-
- virtual std::string getDescription() const {
- return T::getDescription();
- }
- };
-
- public:
-
- LegacyReporterRegistrar( std::string const& name ) {
- getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
- }
- };
-
- template<typename T>
- class ReporterRegistrar {
-
- class ReporterFactory : public IReporterFactory {
-
- // *** Please Note ***:
- // - If you end up here looking at a compiler error because it's trying to register
- // your custom reporter class be aware that the native reporter interface has changed
- // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
- // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
- // However please consider updating to the new interface as the old one is now
- // deprecated and will probably be removed quite soon!
- // Please contact me via github if you have any questions at all about this.
- // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
- // no idea who is actually using custom reporters at all (possibly no-one!).
- // The new interface is designed to minimise exposure to interface changes in the future.
- virtual IStreamingReporter* create( ReporterConfig const& config ) const {
- return new T( config );
- }
-
- virtual std::string getDescription() const {
- return T::getDescription();
- }
- };
-
- public:
-
- ReporterRegistrar( std::string const& name ) {
- getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
- }
- };
-}
-
-#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
- namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
-#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
- namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
-
-// #included from: ../internal/catch_xmlwriter.hpp
-#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
-
-#include <sstream>
-#include <string>
-#include <vector>
-
-namespace Catch {
-
- class XmlWriter {
- public:
-
- class ScopedElement {
- public:
- ScopedElement( XmlWriter* writer )
- : m_writer( writer )
- {}
-
- ScopedElement( ScopedElement const& other )
- : m_writer( other.m_writer ){
- other.m_writer = NULL;
- }
-
- ~ScopedElement() {
- if( m_writer )
- m_writer->endElement();
- }
-
- ScopedElement& writeText( std::string const& text, bool indent = true ) {
- m_writer->writeText( text, indent );
- return *this;
- }
-
- template<typename T>
- ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
- m_writer->writeAttribute( name, attribute );
- return *this;
- }
-
- private:
- mutable XmlWriter* m_writer;
- };
-
- XmlWriter()
- : m_tagIsOpen( false ),
- m_needsNewline( false ),
- m_os( &Catch::cout() )
- {}
-
- XmlWriter( std::ostream& os )
- : m_tagIsOpen( false ),
- m_needsNewline( false ),
- m_os( &os )
- {}
-
- ~XmlWriter() {
- while( !m_tags.empty() )
- endElement();
- }
-
- XmlWriter& startElement( std::string const& name ) {
- ensureTagClosed();
- newlineIfNecessary();
- stream() << m_indent << "<" << name;
- m_tags.push_back( name );
- m_indent += " ";
- m_tagIsOpen = true;
- return *this;
- }
-
- ScopedElement scopedElement( std::string const& name ) {
- ScopedElement scoped( this );
- startElement( name );
- return scoped;
- }
-
- XmlWriter& endElement() {
- newlineIfNecessary();
- m_indent = m_indent.substr( 0, m_indent.size()-2 );
- if( m_tagIsOpen ) {
- stream() << "/>\n";
- m_tagIsOpen = false;
- }
- else {
- stream() << m_indent << "</" << m_tags.back() << ">\n";
- }
- m_tags.pop_back();
- return *this;
- }
-
- XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
- if( !name.empty() && !attribute.empty() ) {
- stream() << " " << name << "=\"";
- writeEncodedText( attribute );
- stream() << "\"";
- }
- return *this;
- }
-
- XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
- stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\"";
- return *this;
- }
-
- template<typename T>
- XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
- if( !name.empty() )
- stream() << " " << name << "=\"" << attribute << "\"";
- return *this;
- }
-
- XmlWriter& writeText( std::string const& text, bool indent = true ) {
- if( !text.empty() ){
- bool tagWasOpen = m_tagIsOpen;
- ensureTagClosed();
- if( tagWasOpen && indent )
- stream() << m_indent;
- writeEncodedText( text );
- m_needsNewline = true;
- }
- return *this;
- }
-
- XmlWriter& writeComment( std::string const& text ) {
- ensureTagClosed();
- stream() << m_indent << "<!--" << text << "-->";
- m_needsNewline = true;
- return *this;
- }
-
- XmlWriter& writeBlankLine() {
- ensureTagClosed();
- stream() << "\n";
- return *this;
- }
-
- void setStream( std::ostream& os ) {
- m_os = &os;
- }
-
- private:
- XmlWriter( XmlWriter const& );
- void operator=( XmlWriter const& );
-
- std::ostream& stream() {
- return *m_os;
- }
-
- void ensureTagClosed() {
- if( m_tagIsOpen ) {
- stream() << ">\n";
- m_tagIsOpen = false;
- }
- }
-
- void newlineIfNecessary() {
- if( m_needsNewline ) {
- stream() << "\n";
- m_needsNewline = false;
- }
- }
-
- void writeEncodedText( std::string const& text ) {
- static const char* charsToEncode = "<&\"";
- std::string mtext = text;
- std::string::size_type pos = mtext.find_first_of( charsToEncode );
- while( pos != std::string::npos ) {
- stream() << mtext.substr( 0, pos );
-
- switch( mtext[pos] ) {
- case '<':
- stream() << "&lt;";
- break;
- case '&':
- stream() << "&amp;";
- break;
- case '\"':
- stream() << "&quot;";
- break;
- }
- mtext = mtext.substr( pos+1 );
- pos = mtext.find_first_of( charsToEncode );
- }
- stream() << mtext;
- }
-
- bool m_tagIsOpen;
- bool m_needsNewline;
- std::vector<std::string> m_tags;
- std::string m_indent;
- std::ostream* m_os;
- };
-
-}
-namespace Catch {
- class XmlReporter : public StreamingReporterBase {
- public:
- XmlReporter( ReporterConfig const& _config )
- : StreamingReporterBase( _config ),
- m_sectionDepth( 0 )
- {}
-
- virtual ~XmlReporter();
-
- static std::string getDescription() {
- return "Reports test results as an XML document";
- }
-
- public: // StreamingReporterBase
- virtual ReporterPreferences getPreferences() const {
- ReporterPreferences prefs;
- prefs.shouldRedirectStdOut = true;
- return prefs;
- }
-
- virtual void noMatchingTestCases( std::string const& s ) {
- StreamingReporterBase::noMatchingTestCases( s );
- }
-
- virtual void testRunStarting( TestRunInfo const& testInfo ) {
- StreamingReporterBase::testRunStarting( testInfo );
- m_xml.setStream( stream );
- m_xml.startElement( "Catch" );
- if( !m_config->name().empty() )
- m_xml.writeAttribute( "name", m_config->name() );
- }
-
- virtual void testGroupStarting( GroupInfo const& groupInfo ) {
- StreamingReporterBase::testGroupStarting( groupInfo );
- m_xml.startElement( "Group" )
- .writeAttribute( "name", groupInfo.name );
- }
-
- virtual void testCaseStarting( TestCaseInfo const& testInfo ) {
- StreamingReporterBase::testCaseStarting(testInfo);
- m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
-
- if ( m_config->showDurations() == ShowDurations::Always )
- m_testCaseTimer.start();
- }
-
- virtual void sectionStarting( SectionInfo const& sectionInfo ) {
- StreamingReporterBase::sectionStarting( sectionInfo );
- if( m_sectionDepth++ > 0 ) {
- m_xml.startElement( "Section" )
- .writeAttribute( "name", trim( sectionInfo.name ) )
- .writeAttribute( "description", sectionInfo.description );
- }
- }
-
- virtual void assertionStarting( AssertionInfo const& ) { }
-
- virtual bool assertionEnded( AssertionStats const& assertionStats ) {
- const AssertionResult& assertionResult = assertionStats.assertionResult;
-
- // Print any info messages in <Info> tags.
- if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
- for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
- it != itEnd;
- ++it ) {
- if( it->type == ResultWas::Info ) {
- m_xml.scopedElement( "Info" )
- .writeText( it->message );
- } else if ( it->type == ResultWas::Warning ) {
- m_xml.scopedElement( "Warning" )
- .writeText( it->message );
- }
- }
- }
-
- // Drop out if result was successful but we're not printing them.
- if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
- return true;
-
- // Print the expression if there is one.
- if( assertionResult.hasExpression() ) {
- m_xml.startElement( "Expression" )
- .writeAttribute( "success", assertionResult.succeeded() )
- .writeAttribute( "type", assertionResult.getTestMacroName() )
- .writeAttribute( "filename", assertionResult.getSourceInfo().file )
- .writeAttribute( "line", assertionResult.getSourceInfo().line );
-
- m_xml.scopedElement( "Original" )
- .writeText( assertionResult.getExpression() );
- m_xml.scopedElement( "Expanded" )
- .writeText( assertionResult.getExpandedExpression() );
- }
-
- // And... Print a result applicable to each result type.
- switch( assertionResult.getResultType() ) {
- case ResultWas::ThrewException:
- m_xml.scopedElement( "Exception" )
- .writeAttribute( "filename", assertionResult.getSourceInfo().file )
- .writeAttribute( "line", assertionResult.getSourceInfo().line )
- .writeText( assertionResult.getMessage() );
- break;
- case ResultWas::FatalErrorCondition:
- m_xml.scopedElement( "Fatal Error Condition" )
- .writeAttribute( "filename", assertionResult.getSourceInfo().file )
- .writeAttribute( "line", assertionResult.getSourceInfo().line )
- .writeText( assertionResult.getMessage() );
- break;
- case ResultWas::Info:
- m_xml.scopedElement( "Info" )
- .writeText( assertionResult.getMessage() );
- break;
- case ResultWas::Warning:
- // Warning will already have been written
- break;
- case ResultWas::ExplicitFailure:
- m_xml.scopedElement( "Failure" )
- .writeText( assertionResult.getMessage() );
- break;
- default:
- break;
- }
-
- if( assertionResult.hasExpression() )
- m_xml.endElement();
-
- return true;
- }
-
- virtual void sectionEnded( SectionStats const& sectionStats ) {
- StreamingReporterBase::sectionEnded( sectionStats );
- if( --m_sectionDepth > 0 ) {
- XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
- e.writeAttribute( "successes", sectionStats.assertions.passed );
- e.writeAttribute( "failures", sectionStats.assertions.failed );
- e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
-
- if ( m_config->showDurations() == ShowDurations::Always )
- e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
-
- m_xml.endElement();
- }
- }
-
- virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
- StreamingReporterBase::testCaseEnded( testCaseStats );
- XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
- e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
-
- if ( m_config->showDurations() == ShowDurations::Always )
- e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
-
- m_xml.endElement();
- }
-
- virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
- StreamingReporterBase::testGroupEnded( testGroupStats );
- // TODO: Check testGroupStats.aborting and act accordingly.
- m_xml.scopedElement( "OverallResults" )
- .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
- .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
- .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
- m_xml.endElement();
- }
-
- virtual void testRunEnded( TestRunStats const& testRunStats ) {
- StreamingReporterBase::testRunEnded( testRunStats );
- m_xml.scopedElement( "OverallResults" )
- .writeAttribute( "successes", testRunStats.totals.assertions.passed )
- .writeAttribute( "failures", testRunStats.totals.assertions.failed )
- .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
- m_xml.endElement();
- }
-
- private:
- Timer m_testCaseTimer;
- XmlWriter m_xml;
- int m_sectionDepth;
- };
-
- INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
-
-} // end namespace Catch
-
-// #included from: ../reporters/catch_reporter_junit.hpp
-#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
-
-#include <assert.h>
-
-namespace Catch {
-
- class JunitReporter : public CumulativeReporterBase {
- public:
- JunitReporter( ReporterConfig const& _config )
- : CumulativeReporterBase( _config ),
- xml( _config.stream() )
- {}
-
- ~JunitReporter();
-
- static std::string getDescription() {
- return "Reports test results in an XML format that looks like Ant's junitreport target";
- }
-
- virtual void noMatchingTestCases( std::string const& /*spec*/ ) {}
-
- virtual ReporterPreferences getPreferences() const {
- ReporterPreferences prefs;
- prefs.shouldRedirectStdOut = true;
- return prefs;
- }
-
- virtual void testRunStarting( TestRunInfo const& runInfo ) {
- CumulativeReporterBase::testRunStarting( runInfo );
- xml.startElement( "testsuites" );
- }
-
- virtual void testGroupStarting( GroupInfo const& groupInfo ) {
- suiteTimer.start();
- stdOutForSuite.str("");
- stdErrForSuite.str("");
- unexpectedExceptions = 0;
- CumulativeReporterBase::testGroupStarting( groupInfo );
- }
-
- virtual bool assertionEnded( AssertionStats const& assertionStats ) {
- if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
- unexpectedExceptions++;
- return CumulativeReporterBase::assertionEnded( assertionStats );
- }
-
- virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
- stdOutForSuite << testCaseStats.stdOut;
- stdErrForSuite << testCaseStats.stdErr;
- CumulativeReporterBase::testCaseEnded( testCaseStats );
- }
-
- virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
- double suiteTime = suiteTimer.getElapsedSeconds();
- CumulativeReporterBase::testGroupEnded( testGroupStats );
- writeGroup( *m_testGroups.back(), suiteTime );
- }
-
- virtual void testRunEndedCumulative() {
- xml.endElement();
- }
-
- void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
- XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
- TestGroupStats const& stats = groupNode.value;
- xml.writeAttribute( "name", stats.groupInfo.name );
- xml.writeAttribute( "errors", unexpectedExceptions );
- xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
- xml.writeAttribute( "tests", stats.totals.assertions.total() );
- xml.writeAttribute( "hostname", "tbd" ); // !TBD
- if( m_config->showDurations() == ShowDurations::Never )
- xml.writeAttribute( "time", "" );
- else
- xml.writeAttribute( "time", suiteTime );
- xml.writeAttribute( "timestamp", "tbd" ); // !TBD
-
- // Write test cases
- for( TestGroupNode::ChildNodes::const_iterator
- it = groupNode.children.begin(), itEnd = groupNode.children.end();
- it != itEnd;
- ++it )
- writeTestCase( **it );
-
- xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
- xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
- }
-
- void writeTestCase( TestCaseNode const& testCaseNode ) {
- TestCaseStats const& stats = testCaseNode.value;
-
- // All test cases have exactly one section - which represents the
- // test case itself. That section may have 0-n nested sections
- assert( testCaseNode.children.size() == 1 );
- SectionNode const& rootSection = *testCaseNode.children.front();
-
- std::string className = stats.testInfo.className;
-
- if( className.empty() ) {
- if( rootSection.childSections.empty() )
- className = "global";
- }
- writeSection( className, "", rootSection );
- }
-
- void writeSection( std::string const& className,
- std::string const& rootName,
- SectionNode const& sectionNode ) {
- std::string name = trim( sectionNode.stats.sectionInfo.name );
- if( !rootName.empty() )
- name = rootName + "/" + name;
-
- if( !sectionNode.assertions.empty() ||
- !sectionNode.stdOut.empty() ||
- !sectionNode.stdErr.empty() ) {
- XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
- if( className.empty() ) {
- xml.writeAttribute( "classname", name );
- xml.writeAttribute( "name", "root" );
- }
- else {
- xml.writeAttribute( "classname", className );
- xml.writeAttribute( "name", name );
- }
- xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) );
-
- writeAssertions( sectionNode );
-
- if( !sectionNode.stdOut.empty() )
- xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
- if( !sectionNode.stdErr.empty() )
- xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
- }
- for( SectionNode::ChildSections::const_iterator
- it = sectionNode.childSections.begin(),
- itEnd = sectionNode.childSections.end();
- it != itEnd;
- ++it )
- if( className.empty() )
- writeSection( name, "", **it );
- else
- writeSection( className, name, **it );
- }
-
- void writeAssertions( SectionNode const& sectionNode ) {
- for( SectionNode::Assertions::const_iterator
- it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
- it != itEnd;
- ++it )
- writeAssertion( *it );
- }
- void writeAssertion( AssertionStats const& stats ) {
- AssertionResult const& result = stats.assertionResult;
- if( !result.isOk() ) {
- std::string elementName;
- switch( result.getResultType() ) {
- case ResultWas::ThrewException:
- case ResultWas::FatalErrorCondition:
- elementName = "error";
- break;
- case ResultWas::ExplicitFailure:
- elementName = "failure";
- break;
- case ResultWas::ExpressionFailed:
- elementName = "failure";
- break;
- case ResultWas::DidntThrowException:
- elementName = "failure";
- break;
-
- // We should never see these here:
- case ResultWas::Info:
- case ResultWas::Warning:
- case ResultWas::Ok:
- case ResultWas::Unknown:
- case ResultWas::FailureBit:
- case ResultWas::Exception:
- elementName = "internalError";
- break;
- }
-
- XmlWriter::ScopedElement e = xml.scopedElement( elementName );
-
- xml.writeAttribute( "message", result.getExpandedExpression() );
- xml.writeAttribute( "type", result.getTestMacroName() );
-
- std::ostringstream oss;
- if( !result.getMessage().empty() )
- oss << result.getMessage() << "\n";
- for( std::vector<MessageInfo>::const_iterator
- it = stats.infoMessages.begin(),
- itEnd = stats.infoMessages.end();
- it != itEnd;
- ++it )
- if( it->type == ResultWas::Info )
- oss << it->message << "\n";
-
- oss << "at " << result.getSourceInfo();
- xml.writeText( oss.str(), false );
- }
- }
-
- XmlWriter xml;
- Timer suiteTimer;
- std::ostringstream stdOutForSuite;
- std::ostringstream stdErrForSuite;
- unsigned int unexpectedExceptions;
- };
-
- INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
-
-} // end namespace Catch
-
-// #included from: ../reporters/catch_reporter_console.hpp
-#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
-
-namespace Catch {
-
- struct ConsoleReporter : StreamingReporterBase {
- ConsoleReporter( ReporterConfig const& _config )
- : StreamingReporterBase( _config ),
- m_headerPrinted( false )
- {}
-
- virtual ~ConsoleReporter();
- static std::string getDescription() {
- return "Reports test results as plain lines of text";
- }
- virtual ReporterPreferences getPreferences() const {
- ReporterPreferences prefs;
- prefs.shouldRedirectStdOut = false;
- return prefs;
- }
-
- virtual void noMatchingTestCases( std::string const& spec ) {
- stream << "No test cases matched '" << spec << "'" << std::endl;
- }
-
- virtual void assertionStarting( AssertionInfo const& ) {
- }
-
- virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
- AssertionResult const& result = _assertionStats.assertionResult;
-
- bool printInfoMessages = true;
-
- // Drop out if result was successful and we're not printing those
- if( !m_config->includeSuccessfulResults() && result.isOk() ) {
- if( result.getResultType() != ResultWas::Warning )
- return false;
- printInfoMessages = false;
- }
-
- lazyPrint();
-
- AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
- printer.print();
- stream << std::endl;
- return true;
- }
-
- virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
- m_headerPrinted = false;
- StreamingReporterBase::sectionStarting( _sectionInfo );
- }
- virtual void sectionEnded( SectionStats const& _sectionStats ) {
- if( _sectionStats.missingAssertions ) {
- lazyPrint();
- Colour colour( Colour::ResultError );
- if( m_sectionStack.size() > 1 )
- stream << "\nNo assertions in section";
- else
- stream << "\nNo assertions in test case";
- stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
- }
- if( m_headerPrinted ) {
- if( m_config->showDurations() == ShowDurations::Always )
- stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
- m_headerPrinted = false;
- }
- else {
- if( m_config->showDurations() == ShowDurations::Always )
- stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
- }
- StreamingReporterBase::sectionEnded( _sectionStats );
- }
-
- virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) {
- StreamingReporterBase::testCaseEnded( _testCaseStats );
- m_headerPrinted = false;
- }
- virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) {
- if( currentGroupInfo.used ) {
- printSummaryDivider();
- stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
- printTotals( _testGroupStats.totals );
- stream << "\n" << std::endl;
- }
- StreamingReporterBase::testGroupEnded( _testGroupStats );
- }
- virtual void testRunEnded( TestRunStats const& _testRunStats ) {
- printTotalsDivider( _testRunStats.totals );
- printTotals( _testRunStats.totals );
- stream << std::endl;
- StreamingReporterBase::testRunEnded( _testRunStats );
- }
-
- private:
-
- class AssertionPrinter {
- void operator= ( AssertionPrinter const& );
- public:
- AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
- : stream( _stream ),
- stats( _stats ),
- result( _stats.assertionResult ),
- colour( Colour::None ),
- message( result.getMessage() ),
- messages( _stats.infoMessages ),
- printInfoMessages( _printInfoMessages )
- {
- switch( result.getResultType() ) {
- case ResultWas::Ok:
- colour = Colour::Success;
- passOrFail = "PASSED";
- //if( result.hasMessage() )
- if( _stats.infoMessages.size() == 1 )
- messageLabel = "with message";
- if( _stats.infoMessages.size() > 1 )
- messageLabel = "with messages";
- break;
- case ResultWas::ExpressionFailed:
- if( result.isOk() ) {
- colour = Colour::Success;
- passOrFail = "FAILED - but was ok";
- }
- else {
- colour = Colour::Error;
- passOrFail = "FAILED";
- }
- if( _stats.infoMessages.size() == 1 )
- messageLabel = "with message";
- if( _stats.infoMessages.size() > 1 )
- messageLabel = "with messages";
- break;
- case ResultWas::ThrewException:
- colour = Colour::Error;
- passOrFail = "FAILED";
- messageLabel = "due to unexpected exception with message";
- break;
- case ResultWas::FatalErrorCondition:
- colour = Colour::Error;
- passOrFail = "FAILED";
- messageLabel = "due to a fatal error condition";
- break;
- case ResultWas::DidntThrowException:
- colour = Colour::Error;
- passOrFail = "FAILED";
- messageLabel = "because no exception was thrown where one was expected";
- break;
- case ResultWas::Info:
- messageLabel = "info";
- break;
- case ResultWas::Warning:
- messageLabel = "warning";
- break;
- case ResultWas::ExplicitFailure:
- passOrFail = "FAILED";
- colour = Colour::Error;
- if( _stats.infoMessages.size() == 1 )
- messageLabel = "explicitly with message";
- if( _stats.infoMessages.size() > 1 )
- messageLabel = "explicitly with messages";
- break;
- // These cases are here to prevent compiler warnings
- case ResultWas::Unknown:
- case ResultWas::FailureBit:
- case ResultWas::Exception:
- passOrFail = "** internal error **";
- colour = Colour::Error;
- break;
- }
- }
-
- void print() const {
- printSourceInfo();
- if( stats.totals.assertions.total() > 0 ) {
- if( result.isOk() )
- stream << "\n";
- printResultType();
- printOriginalExpression();
- printReconstructedExpression();
- }
- else {
- stream << "\n";
- }
- printMessage();
- }
-
- private:
- void printResultType() const {
- if( !passOrFail.empty() ) {
- Colour colourGuard( colour );
- stream << passOrFail << ":\n";
- }
- }
- void printOriginalExpression() const {
- if( result.hasExpression() ) {
- Colour colourGuard( Colour::OriginalExpression );
- stream << " ";
- stream << result.getExpressionInMacro();
- stream << "\n";
- }
- }
- void printReconstructedExpression() const {
- if( result.hasExpandedExpression() ) {
- stream << "with expansion:\n";
- Colour colourGuard( Colour::ReconstructedExpression );
- stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n";
- }
- }
- void printMessage() const {
- if( !messageLabel.empty() )
- stream << messageLabel << ":" << "\n";
- for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
- it != itEnd;
- ++it ) {
- // If this assertion is a warning ignore any INFO messages
- if( printInfoMessages || it->type != ResultWas::Info )
- stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n";
- }
- }
- void printSourceInfo() const {
- Colour colourGuard( Colour::FileName );
- stream << result.getSourceInfo() << ": ";
- }
-
- std::ostream& stream;
- AssertionStats const& stats;
- AssertionResult const& result;
- Colour::Code colour;
- std::string passOrFail;
- std::string messageLabel;
- std::string message;
- std::vector<MessageInfo> messages;
- bool printInfoMessages;
- };
-
- void lazyPrint() {
-
- if( !currentTestRunInfo.used )
- lazyPrintRunInfo();
- if( !currentGroupInfo.used )
- lazyPrintGroupInfo();
-
- if( !m_headerPrinted ) {
- printTestCaseAndSectionHeader();
- m_headerPrinted = true;
- }
- }
- void lazyPrintRunInfo() {
- stream << "\n" << getLineOfChars<'~'>() << "\n";
- Colour colour( Colour::SecondaryText );
- stream << currentTestRunInfo->name
- << " is a Catch v" << libraryVersion << " host application.\n"
- << "Run with -? for options\n\n";
-
- if( m_config->rngSeed() != 0 )
- stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
-
- currentTestRunInfo.used = true;
- }
- void lazyPrintGroupInfo() {
- if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
- printClosedHeader( "Group: " + currentGroupInfo->name );
- currentGroupInfo.used = true;
- }
- }
- void printTestCaseAndSectionHeader() {
- assert( !m_sectionStack.empty() );
- printOpenHeader( currentTestCaseInfo->name );
-
- if( m_sectionStack.size() > 1 ) {
- Colour colourGuard( Colour::Headers );
-
- std::vector<SectionInfo>::const_iterator
- it = m_sectionStack.begin()+1, // Skip first section (test case)
- itEnd = m_sectionStack.end();
- for( ; it != itEnd; ++it )
- printHeaderString( it->name, 2 );
- }
-
- SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
-
- if( !lineInfo.empty() ){
- stream << getLineOfChars<'-'>() << "\n";
- Colour colourGuard( Colour::FileName );
- stream << lineInfo << "\n";
- }
- stream << getLineOfChars<'.'>() << "\n" << std::endl;
- }
-
- void printClosedHeader( std::string const& _name ) {
- printOpenHeader( _name );
- stream << getLineOfChars<'.'>() << "\n";
- }
- void printOpenHeader( std::string const& _name ) {
- stream << getLineOfChars<'-'>() << "\n";
- {
- Colour colourGuard( Colour::Headers );
- printHeaderString( _name );
- }
- }
-
- // if string has a : in first line will set indent to follow it on
- // subsequent lines
- void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
- std::size_t i = _string.find( ": " );
- if( i != std::string::npos )
- i+=2;
- else
- i = 0;
- stream << Text( _string, TextAttributes()
- .setIndent( indent+i)
- .setInitialIndent( indent ) ) << "\n";
- }
-
- struct SummaryColumn {
-
- SummaryColumn( std::string const& _label, Colour::Code _colour )
- : label( _label ),
- colour( _colour )
- {}
- SummaryColumn addRow( std::size_t count ) {
- std::ostringstream oss;
- oss << count;
- std::string row = oss.str();
- for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
- while( it->size() < row.size() )
- *it = " " + *it;
- while( it->size() > row.size() )
- row = " " + row;
- }
- rows.push_back( row );
- return *this;
- }
-
- std::string label;
- Colour::Code colour;
- std::vector<std::string> rows;
-
- };
-
- void printTotals( Totals const& totals ) {
- if( totals.testCases.total() == 0 ) {
- stream << Colour( Colour::Warning ) << "No tests ran\n";
- }
- else if( totals.assertions.total() > 0 && totals.assertions.allPassed() ) {
- stream << Colour( Colour::ResultSuccess ) << "All tests passed";
- stream << " ("
- << pluralise( totals.assertions.passed, "assertion" ) << " in "
- << pluralise( totals.testCases.passed, "test case" ) << ")"
- << "\n";
- }
- else {
-
- std::vector<SummaryColumn> columns;
- columns.push_back( SummaryColumn( "", Colour::None )
- .addRow( totals.testCases.total() )
- .addRow( totals.assertions.total() ) );
- columns.push_back( SummaryColumn( "passed", Colour::Success )
- .addRow( totals.testCases.passed )
- .addRow( totals.assertions.passed ) );
- columns.push_back( SummaryColumn( "failed", Colour::ResultError )
- .addRow( totals.testCases.failed )
- .addRow( totals.assertions.failed ) );
- columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
- .addRow( totals.testCases.failedButOk )
- .addRow( totals.assertions.failedButOk ) );
-
- printSummaryRow( "test cases", columns, 0 );
- printSummaryRow( "assertions", columns, 1 );
- }
- }
- void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
- for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
- std::string value = it->rows[row];
- if( it->label.empty() ) {
- stream << label << ": ";
- if( value != "0" )
- stream << value;
- else
- stream << Colour( Colour::Warning ) << "- none -";
- }
- else if( value != "0" ) {
- stream << Colour( Colour::LightGrey ) << " | ";
- stream << Colour( it->colour )
- << value << " " << it->label;
- }
- }
- stream << "\n";
- }
-
- static std::size_t makeRatio( std::size_t number, std::size_t total ) {
- std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
- return ( ratio == 0 && number > 0 ) ? 1 : ratio;
- }
- static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
- if( i > j && i > k )
- return i;
- else if( j > k )
- return j;
- else
- return k;
- }
-
- void printTotalsDivider( Totals const& totals ) {
- if( totals.testCases.total() > 0 ) {
- std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
- std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
- std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
- while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
- findMax( failedRatio, failedButOkRatio, passedRatio )++;
- while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
- findMax( failedRatio, failedButOkRatio, passedRatio )--;
-
- stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
- stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
- if( totals.testCases.allPassed() )
- stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
- else
- stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
- }
- else {
- stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
- }
- stream << "\n";
- }
- void printSummaryDivider() {
- stream << getLineOfChars<'-'>() << "\n";
- }
-
- private:
- bool m_headerPrinted;
- };
-
- INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
-
-} // end namespace Catch
-
-// #included from: ../reporters/catch_reporter_compact.hpp
-#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
-
-namespace Catch {
-
- struct CompactReporter : StreamingReporterBase {
-
- CompactReporter( ReporterConfig const& _config )
- : StreamingReporterBase( _config )
- {}
-
- virtual ~CompactReporter();
-
- static std::string getDescription() {
- return "Reports test results on a single line, suitable for IDEs";
- }
-
- virtual ReporterPreferences getPreferences() const {
- ReporterPreferences prefs;
- prefs.shouldRedirectStdOut = false;
- return prefs;
- }
-
- virtual void noMatchingTestCases( std::string const& spec ) {
- stream << "No test cases matched '" << spec << "'" << std::endl;
- }
-
- virtual void assertionStarting( AssertionInfo const& ) {
- }
-
- virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
- AssertionResult const& result = _assertionStats.assertionResult;
-
- bool printInfoMessages = true;
-
- // Drop out if result was successful and we're not printing those
- if( !m_config->includeSuccessfulResults() && result.isOk() ) {
- if( result.getResultType() != ResultWas::Warning )
- return false;
- printInfoMessages = false;
- }
-
- AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
- printer.print();
-
- stream << std::endl;
- return true;
- }
-
- virtual void testRunEnded( TestRunStats const& _testRunStats ) {
- printTotals( _testRunStats.totals );
- stream << "\n" << std::endl;
- StreamingReporterBase::testRunEnded( _testRunStats );
- }
-
- private:
- class AssertionPrinter {
- void operator= ( AssertionPrinter const& );
- public:
- AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
- : stream( _stream )
- , stats( _stats )
- , result( _stats.assertionResult )
- , messages( _stats.infoMessages )
- , itMessage( _stats.infoMessages.begin() )
- , printInfoMessages( _printInfoMessages )
- {}
-
- void print() {
- printSourceInfo();
-
- itMessage = messages.begin();
-
- switch( result.getResultType() ) {
- case ResultWas::Ok:
- printResultType( Colour::ResultSuccess, passedString() );
- printOriginalExpression();
- printReconstructedExpression();
- if ( ! result.hasExpression() )
- printRemainingMessages( Colour::None );
- else
- printRemainingMessages();
- break;
- case ResultWas::ExpressionFailed:
- if( result.isOk() )
- printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
- else
- printResultType( Colour::Error, failedString() );
- printOriginalExpression();
- printReconstructedExpression();
- printRemainingMessages();
- break;
- case ResultWas::ThrewException:
- printResultType( Colour::Error, failedString() );
- printIssue( "unexpected exception with message:" );
- printMessage();
- printExpressionWas();
- printRemainingMessages();
- break;
- case ResultWas::FatalErrorCondition:
- printResultType( Colour::Error, failedString() );
- printIssue( "fatal error condition with message:" );
- printMessage();
- printExpressionWas();
- printRemainingMessages();
- break;
- case ResultWas::DidntThrowException:
- printResultType( Colour::Error, failedString() );
- printIssue( "expected exception, got none" );
- printExpressionWas();
- printRemainingMessages();
- break;
- case ResultWas::Info:
- printResultType( Colour::None, "info" );
- printMessage();
- printRemainingMessages();
- break;
- case ResultWas::Warning:
- printResultType( Colour::None, "warning" );
- printMessage();
- printRemainingMessages();
- break;
- case ResultWas::ExplicitFailure:
- printResultType( Colour::Error, failedString() );
- printIssue( "explicitly" );
- printRemainingMessages( Colour::None );
- break;
- // These cases are here to prevent compiler warnings
- case ResultWas::Unknown:
- case ResultWas::FailureBit:
- case ResultWas::Exception:
- printResultType( Colour::Error, "** internal error **" );
- break;
- }
- }
-
- private:
- // Colour::LightGrey
-
- static Colour::Code dimColour() { return Colour::FileName; }
-
-#ifdef CATCH_PLATFORM_MAC
- static const char* failedString() { return "FAILED"; }
- static const char* passedString() { return "PASSED"; }
-#else
- static const char* failedString() { return "failed"; }
- static const char* passedString() { return "passed"; }
-#endif
-
- void printSourceInfo() const {
- Colour colourGuard( Colour::FileName );
- stream << result.getSourceInfo() << ":";
- }
-
- void printResultType( Colour::Code colour, std::string passOrFail ) const {
- if( !passOrFail.empty() ) {
- {
- Colour colourGuard( colour );
- stream << " " << passOrFail;
- }
- stream << ":";
- }
- }
-
- void printIssue( std::string issue ) const {
- stream << " " << issue;
- }
-
- void printExpressionWas() {
- if( result.hasExpression() ) {
- stream << ";";
- {
- Colour colour( dimColour() );
- stream << " expression was:";
- }
- printOriginalExpression();
- }
- }
-
- void printOriginalExpression() const {
- if( result.hasExpression() ) {
- stream << " " << result.getExpression();
- }
- }
-
- void printReconstructedExpression() const {
- if( result.hasExpandedExpression() ) {
- {
- Colour colour( dimColour() );
- stream << " for: ";
- }
- stream << result.getExpandedExpression();
- }
- }
-
- void printMessage() {
- if ( itMessage != messages.end() ) {
- stream << " '" << itMessage->message << "'";
- ++itMessage;
- }
- }
-
- void printRemainingMessages( Colour::Code colour = dimColour() ) {
- if ( itMessage == messages.end() )
- return;
-
- // using messages.end() directly yields compilation error:
- std::vector<MessageInfo>::const_iterator itEnd = messages.end();
- const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
-
- {
- Colour colourGuard( colour );
- stream << " with " << pluralise( N, "message" ) << ":";
- }
-
- for(; itMessage != itEnd; ) {
- // If this assertion is a warning ignore any INFO messages
- if( printInfoMessages || itMessage->type != ResultWas::Info ) {
- stream << " '" << itMessage->message << "'";
- if ( ++itMessage != itEnd ) {
- Colour colourGuard( dimColour() );
- stream << " and";
- }
- }
- }
- }
-
- private:
- std::ostream& stream;
- AssertionStats const& stats;
- AssertionResult const& result;
- std::vector<MessageInfo> messages;
- std::vector<MessageInfo>::const_iterator itMessage;
- bool printInfoMessages;
- };
-
- // Colour, message variants:
- // - white: No tests ran.
- // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
- // - white: Passed [both/all] N test cases (no assertions).
- // - red: Failed N tests cases, failed M assertions.
- // - green: Passed [both/all] N tests cases with M assertions.
-
- std::string bothOrAll( std::size_t count ) const {
- return count == 1 ? "" : count == 2 ? "both " : "all " ;
- }
-
- void printTotals( const Totals& totals ) const {
- if( totals.testCases.total() == 0 ) {
- stream << "No tests ran.";
- }
- else if( totals.testCases.failed == totals.testCases.total() ) {
- Colour colour( Colour::ResultError );
- const std::string qualify_assertions_failed =
- totals.assertions.failed == totals.assertions.total() ?
- bothOrAll( totals.assertions.failed ) : "";
- stream <<
- "Failed " << bothOrAll( totals.testCases.failed )
- << pluralise( totals.testCases.failed, "test case" ) << ", "
- "failed " << qualify_assertions_failed <<
- pluralise( totals.assertions.failed, "assertion" ) << ".";
- }
- else if( totals.assertions.total() == 0 ) {
- stream <<
- "Passed " << bothOrAll( totals.testCases.total() )
- << pluralise( totals.testCases.total(), "test case" )
- << " (no assertions).";
- }
- else if( totals.assertions.failed ) {
- Colour colour( Colour::ResultError );
- stream <<
- "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", "
- "failed " << pluralise( totals.assertions.failed, "assertion" ) << ".";
- }
- else {
- Colour colour( Colour::ResultSuccess );
- stream <<
- "Passed " << bothOrAll( totals.testCases.passed )
- << pluralise( totals.testCases.passed, "test case" ) <<
- " with " << pluralise( totals.assertions.passed, "assertion" ) << ".";
- }
- }
- };
-
- INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
-
-} // end namespace Catch
-
-namespace Catch {
- NonCopyable::~NonCopyable() {}
- IShared::~IShared() {}
- StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
- IContext::~IContext() {}
- IResultCapture::~IResultCapture() {}
- ITestCase::~ITestCase() {}
- ITestCaseRegistry::~ITestCaseRegistry() {}
- IRegistryHub::~IRegistryHub() {}
- IMutableRegistryHub::~IMutableRegistryHub() {}
- IExceptionTranslator::~IExceptionTranslator() {}
- IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
- IReporter::~IReporter() {}
- IReporterFactory::~IReporterFactory() {}
- IReporterRegistry::~IReporterRegistry() {}
- IStreamingReporter::~IStreamingReporter() {}
- AssertionStats::~AssertionStats() {}
- SectionStats::~SectionStats() {}
- TestCaseStats::~TestCaseStats() {}
- TestGroupStats::~TestGroupStats() {}
- TestRunStats::~TestRunStats() {}
- CumulativeReporterBase::SectionNode::~SectionNode() {}
- CumulativeReporterBase::~CumulativeReporterBase() {}
-
- StreamingReporterBase::~StreamingReporterBase() {}
- ConsoleReporter::~ConsoleReporter() {}
- CompactReporter::~CompactReporter() {}
- IRunner::~IRunner() {}
- IMutableContext::~IMutableContext() {}
- IConfig::~IConfig() {}
- XmlReporter::~XmlReporter() {}
- JunitReporter::~JunitReporter() {}
- TestRegistry::~TestRegistry() {}
- FreeFunctionTestCase::~FreeFunctionTestCase() {}
- IGeneratorInfo::~IGeneratorInfo() {}
- IGeneratorsForTest::~IGeneratorsForTest() {}
- TestSpec::Pattern::~Pattern() {}
- TestSpec::NamePattern::~NamePattern() {}
- TestSpec::TagPattern::~TagPattern() {}
- TestSpec::ExcludedPattern::~ExcludedPattern() {}
-
- Matchers::Impl::StdString::Equals::~Equals() {}
- Matchers::Impl::StdString::Contains::~Contains() {}
- Matchers::Impl::StdString::StartsWith::~StartsWith() {}
- Matchers::Impl::StdString::EndsWith::~EndsWith() {}
-
- void Config::dummy() {}
-}
-
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
-
-#endif
-
-#ifdef CATCH_CONFIG_MAIN
-// #included from: internal/catch_default_main.hpp
-#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
-
-#ifndef __OBJC__
-
-// Standard C/C++ main entry point
-int main (int argc, char * const argv[]) {
- return Catch::Session().run( argc, argv );
-}
-
-#else // __OBJC__
-
-// Objective-C entry point
-int main (int argc, char * const argv[]) {
-#if !CATCH_ARC_ENABLED
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-#endif
-
- Catch::registerTestMethods();
- int result = Catch::Session().run( argc, (char* const*)argv );
-
-#if !CATCH_ARC_ENABLED
- [pool drain];
-#endif
-
- return result;
-}
-
-#endif // __OBJC__
-
-#endif
-
-#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
-# undef CLARA_CONFIG_MAIN
-#endif
-
-//////
-
-// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
-#ifdef CATCH_CONFIG_PREFIX_ALL
-
-#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
-#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
-
-#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS" )
-#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
-#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" )
-
-#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" )
-#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" )
-#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" )
-#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" )
-#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" )
-
-#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" )
-#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" )
-#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
-
-#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
-#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
-
-#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
-#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
-#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
-#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
-#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
-
-#ifdef CATCH_CONFIG_VARIADIC_MACROS
- #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
- #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
- #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
- #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
- #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
- #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
-#else
- #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
- #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
- #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
- #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
- #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
- #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
-#endif
-#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
-
-#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
-#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
-
-#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
-
-// "BDD-style" convenience wrappers
-#ifdef CATCH_CONFIG_VARIADIC_MACROS
-#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
-#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
-#else
-#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
-#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
-#endif
-#define CATCH_GIVEN( desc ) CATCH_SECTION( "Given: " desc, "" )
-#define CATCH_WHEN( desc ) CATCH_SECTION( " When: " desc, "" )
-#define CATCH_AND_WHEN( desc ) CATCH_SECTION( " And: " desc, "" )
-#define CATCH_THEN( desc ) CATCH_SECTION( " Then: " desc, "" )
-#define CATCH_AND_THEN( desc ) CATCH_SECTION( " And: " desc, "" )
-
-// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
-#else
-
-#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
-#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
-
-#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "REQUIRE_THROWS" )
-#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
-#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" )
-
-#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
-#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" )
-#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" )
-#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" )
-#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" )
-
-#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS" )
-#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
-#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
-
-#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
-#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
-
-#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
-#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
-#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
-#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
-#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
-
-#ifdef CATCH_CONFIG_VARIADIC_MACROS
- #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
- #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
- #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
- #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
- #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
- #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
-#else
- #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
- #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
- #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
- #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
- #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
- #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
-#endif
-#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
-
-#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
-#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
-
-#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
-
-#endif
-
-#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
-
-// "BDD-style" convenience wrappers
-#ifdef CATCH_CONFIG_VARIADIC_MACROS
-#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
-#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
-#else
-#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
-#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
-#endif
-#define GIVEN( desc ) SECTION( " Given: " desc, "" )
-#define WHEN( desc ) SECTION( " When: " desc, "" )
-#define AND_WHEN( desc ) SECTION( "And when: " desc, "" )
-#define THEN( desc ) SECTION( " Then: " desc, "" )
-#define AND_THEN( desc ) SECTION( " And: " desc, "" )
-
-using Catch::Detail::Approx;
-
-// #included from: internal/catch_reenable_warnings.h
-
-#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
-
-#ifdef __clang__
-# ifdef __ICC // icpc defines the __clang__ macro
-# pragma warning(pop)
-# else
-# pragma clang diagnostic pop
-# endif
-#elif defined __GNUC__
-# pragma GCC diagnostic pop
-#endif
-
-#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
-
diff --git a/src/tests/catchy/catchy_tests.h b/src/tests/catchy/catchy_tests.h
deleted file mode 100644
index ab621d0f9..000000000
--- a/src/tests/catchy/catchy_tests.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// (C) 2015 Simon Warta (Kullo GmbH)
-// Botan is released under the Simplified BSD License (see license.txt)
-
-#ifndef BOTAN_CATCHY_TESTS_H__
-#define BOTAN_CATCHY_TESTS_H__
-
-#include "catch.hpp"
-#include <botan/build.h>
-
-
-// BEGIN CATCH STD::VECTOR IMPLEMENTATION
-// This is basically https://github.com/philsquared/Catch/pull/466
-#include <vector>
-
-#include <type_traits>
-
-namespace Catch {
-
-namespace Matchers {
- namespace Impl {
-
- namespace Generic {
- template<typename ExpressionT>
- struct Not : public MatcherImpl<Not<ExpressionT>, ExpressionT>
- {
- Not( Matcher<ExpressionT> const& matcher ) : m_matcher(matcher.clone()) {}
- Not( Not const& other ) : m_matcher( other.m_matcher ) {}
-
- virtual bool match( ExpressionT const& expr ) const
- {
- return !m_matcher->match( expr );
- }
- virtual std::string toString() const {
- return "not " + m_matcher->toString();
- }
-
- Ptr<Matcher<ExpressionT>> m_matcher;
- };
- } // namespace Generic
-
- namespace StdVector {
- template<typename T, typename Alloc>
- struct Equals : MatcherImpl<Equals<T, Alloc>, std::vector<T, Alloc> >
- {
- Equals( std::vector<T, Alloc> const& vec ) : m_vector( vec ){}
- Equals( Equals const& other ) : m_vector( other.m_vector ){}
-
- virtual ~Equals() {}
-
- virtual bool match( std::vector<T, Alloc> const& expr ) const {
- return m_vector == expr;
- }
- virtual std::string toString() const {
- return "equals: std::vector of length " + Catch::toString(m_vector.size());
- }
-
- std::vector<T, Alloc> m_vector;
- };
- } // namespace StdVector
-
- namespace Boolean {
- struct Equals : MatcherImpl<Equals, bool>
- {
- Equals( const bool expected ) : m_expected( expected ){}
- Equals( Equals const& other ) : m_expected( other.m_expected ){}
-
- virtual ~Equals() override {}
-
- virtual bool match( bool const& expr ) const override {
- return m_expected == expr;
- }
- virtual std::string toString() const override {
- return "== " + Catch::toString(m_expected);
- }
-
- bool m_expected;
- };
- } // Boolean
-
- namespace Integer {
- template<typename T>
- struct Equals : MatcherImpl<Equals<T>, T>
- {
- Equals( const T expected ) : m_expected( expected ){}
- Equals( Equals const& other ) : m_expected( other.m_expected ){}
-
- virtual ~Equals() override {}
-
- virtual bool match( T const& expr ) const override {
- return m_expected == expr;
- }
- virtual std::string toString() const override {
- return "== " + Catch::toString(m_expected);
- }
-
- T m_expected;
- };
- } // namespace Integer
-
- } // namespace Impl
-
- // The following functions create the actual matcher objects.
- // This allows the types to be inferred
- template<typename ExpressionT>
- inline Impl::Generic::Not<ExpressionT> Not( Impl::Matcher<ExpressionT> const& m ) {
- return Impl::Generic::Not<ExpressionT>( m );
- }
-
- template <typename T, typename Alloc>
- inline Impl::StdVector::Equals<T, Alloc> Equals( std::vector<T, Alloc> const& vec ) {
- return Impl::StdVector::Equals<T, Alloc>( vec );
- }
-
- template <typename T,
- typename = typename std::enable_if<std::numeric_limits<T>::is_integer, T>::type>
- inline Impl::Integer::Equals<T> Equals( T expected ) {
- return Impl::Integer::Equals<T>( expected );
- }
-
- inline Impl::Boolean::Equals Equals( bool expected ) {
- return Impl::Boolean::Equals( expected );
- }
-
-} // namespace Matchers
-} // namespace Catch
-// END CATCH STD::VECTOR IMPLEMENTATION
-
-#endif // BOTAN_CATCHY_TESTS_H__
diff --git a/src/tests/catchy/test_base.cpp b/src/tests/catchy/test_base.cpp
deleted file mode 100644
index 057b29eb3..000000000
--- a/src/tests/catchy/test_base.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// (C) 2015 Simon Warta (Kullo GmbH)
-// Botan is released under the Simplified BSD License (see license.txt)
-
-#include "catchy_tests.h"
-#include <botan/symkey.h>
-
-using namespace Botan;
-
-TEST_CASE("OctetString", "[base]")
- {
- auto empty = secure_vector<byte>{ };
- auto one = secure_vector<byte>{ 94 }; // ^
- auto some = secure_vector<byte>{ 0x48, 0x65, 0x6c, 0x6c, 0x6f }; // Hello
- auto utf8 = secure_vector<byte>{ 0xc3, 0xb6 }; // ö
-
- auto os_empty = OctetString("");
- auto os_one = OctetString("5e");
- auto os_some = OctetString("48656c6c6f");
- auto os_utf8 = OctetString("c3b6");
-
- CHECK_THAT(os_empty.bits_of(), Equals(empty));
- CHECK_THAT(os_one.bits_of(), Equals(one));
- CHECK_THAT(os_some.bits_of(), Equals(some));
- CHECK_THAT(os_utf8.bits_of(), Equals(utf8));
- }
diff --git a/src/tests/catchy/test_base64.cpp b/src/tests/catchy/test_base64.cpp
deleted file mode 100644
index fe7739a8d..000000000
--- a/src/tests/catchy/test_base64.cpp
+++ /dev/null
@@ -1,232 +0,0 @@
-// (C) 2015 Simon Warta (Kullo GmbH)
-// Botan is released under the Simplified BSD License (see license.txt)
-
-#include "catchy_tests.h"
-
-#if defined(BOTAN_HAS_BASE64_CODEC)
-
-#include <botan/base64.h>
-
-namespace {
-std::vector<Botan::byte> toStdVector(const Botan::secure_vector<Botan::byte> &in)
- {
- return std::vector<Botan::byte>(in.cbegin(), in.cend());
- }
-
-std::vector<Botan::byte> toStdVector(const std::string &in)
- {
- return std::vector<Botan::byte>(in.cbegin(), in.cend());
- }
-}
-
-TEST_CASE("Base64 encode empty string", "[base64]")
- {
- // common knowledge
- auto emptyString = std::string("");
- auto emptyVector = std::vector<Botan::byte>(emptyString.cbegin(), emptyString.cend());
- CHECK_THAT(Botan::base64_encode(emptyVector), Equals(""));
- }
-
-TEST_CASE("Base64 encode short string", "[base64]")
- {
- // test vectors from http://tools.ietf.org/html/rfc4648
- auto in1 = std::vector<Botan::byte>{ 'f' };
- auto in2 = std::vector<Botan::byte>{ 'f', 'o' };
- auto in3 = std::vector<Botan::byte>{ 'f', 'o', 'o' };
- CHECK_THAT(Botan::base64_encode(in1), Equals("Zg=="));
- CHECK_THAT(Botan::base64_encode(in2), Equals("Zm8="));
- CHECK_THAT(Botan::base64_encode(in3), Equals("Zm9v"));
- }
-
-TEST_CASE("Base64 encode string", "[base64]")
- {
- // Generated by: echo -n "xyz" | base64
- auto in1 = std::vector<Botan::byte>{ 'h','e','l','l','o',' ','w','o','r','l','d' };
- auto in2 = std::vector<Botan::byte>{ 'h','e','l','l','o',' ','w','o','r','l','d','!' };
- auto in3 = std::vector<Botan::byte>{ 'H','e','l','l','o',',',' ','w','o','r','l','d','.' };
- auto in4 = std::vector<Botan::byte>{ 'T','h','e',' ','1','2',' ','c','h','a','r','s' };
- auto in5 = std::vector<Botan::byte>{ 'T','h','e',' ','1','3',' ','c','h','a','r','s','.' };
- auto in6 = std::vector<Botan::byte>{ 'T','h','e',' ','1','4',' ','c','h','a','r','s','.','.' };
- auto in7 = std::vector<Botan::byte>{ 'T','h','e',' ','1','5',' ','c','h','a','r','s','.','.','.' };
- CHECK_THAT(Botan::base64_encode(in1), Equals("aGVsbG8gd29ybGQ="));
- CHECK_THAT(Botan::base64_encode(in2), Equals("aGVsbG8gd29ybGQh"));
- CHECK_THAT(Botan::base64_encode(in3), Equals("SGVsbG8sIHdvcmxkLg=="));
- CHECK_THAT(Botan::base64_encode(in4), Equals("VGhlIDEyIGNoYXJz"));
- CHECK_THAT(Botan::base64_encode(in5), Equals("VGhlIDEzIGNoYXJzLg=="));
- CHECK_THAT(Botan::base64_encode(in6), Equals("VGhlIDE0IGNoYXJzLi4="));
- CHECK_THAT(Botan::base64_encode(in7), Equals("VGhlIDE1IGNoYXJzLi4u"));
- }
-
-TEST_CASE("Base64 encode string special chars", "[base64]")
- {
- // Generated by: echo -n "xyz" | base64
- auto in1 = toStdVector("An UTF-8 uuml: ü");
- auto in2 = toStdVector("Weird German 2 byte thing: ß.");
- CHECK_THAT(Botan::base64_encode(in1), Equals("QW4gVVRGLTggdXVtbDogw7w="));
- CHECK_THAT(Botan::base64_encode(in2), Equals("V2VpcmQgR2VybWFuIDIgYnl0ZSB0aGluZzogw58u"));
- }
-
-TEST_CASE("Base64 encode empty binary", "[base64]")
- {
- auto binary0 = std::vector<unsigned char>{};
- CHECK_THAT(Botan::base64_encode(binary0), Equals(""));
- }
-
-TEST_CASE("Base64 encode binary", "[base64]")
- {
- // Generated by: cat /dev/urandom | head -c 3 | tee /tmp/mybinary | hexdump -C && cat /tmp/mybinary | base64
- std::vector<unsigned char> binary1 = {0x9b};
- CHECK_THAT(Botan::base64_encode(binary1), Equals("mw=="));
-
- std::vector<unsigned char> binary2 = {0x1c, 0x60};
- CHECK_THAT(Botan::base64_encode(binary2), Equals("HGA="));
-
- std::vector<unsigned char> binary3 = {0x81, 0x34, 0xbd};
- CHECK_THAT(Botan::base64_encode(binary3), Equals("gTS9"));
-
- std::vector<unsigned char> binary4 = {0x5e, 0x6c, 0xff, 0xde};
- CHECK_THAT(Botan::base64_encode(binary4), Equals("Xmz/3g=="));
-
- std::vector<unsigned char> binary5 = {0xb2, 0xcd, 0xf0, 0xdc, 0x7f};
- CHECK_THAT(Botan::base64_encode(binary5), Equals("ss3w3H8="));
-
- std::vector<unsigned char> binary6 = {0xfc, 0x56, 0x2d, 0xda, 0xd4, 0x0e};
- CHECK_THAT(Botan::base64_encode(binary6), Equals("/FYt2tQO"));
-
- std::vector<unsigned char> binary7 = {0x29, 0xb2, 0x32, 0x2e, 0x88, 0x41, 0xe8};
- CHECK_THAT(Botan::base64_encode(binary7), Equals("KbIyLohB6A=="));
-
- std::vector<unsigned char> binary8 = {0x0f, 0x0f, 0xce, 0xd9, 0x49, 0x7a, 0xaf, 0x92};
- CHECK_THAT(Botan::base64_encode(binary8), Equals("Dw/O2Ul6r5I="));
-
- std::vector<unsigned char> binary9 = {0x27, 0x0f, 0xb1, 0x89, 0x82, 0x80, 0x0d, 0xa6, 0x40};
- CHECK_THAT(Botan::base64_encode(binary9), Equals("Jw+xiYKADaZA"));
- }
-
-TEST_CASE("Base64 decode empty string", "[base64]")
- {
- // common knowledge
- auto outVector = toStdVector(Botan::base64_decode(""));
- CHECK_THAT(outVector, Equals(std::vector<Botan::byte>{}));
- }
-
-TEST_CASE("Base64 decode short string", "[base64]")
- {
- // test vectors from http://tools.ietf.org/html/rfc4648
- CHECK_THAT(toStdVector(Botan::base64_decode("Zg==")), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode("Zm8=")), Equals(toStdVector("fo")));
- CHECK_THAT(toStdVector(Botan::base64_decode("Zm9v")), Equals(toStdVector("foo")));
- }
-
-TEST_CASE("Base64 decode string", "[base64]")
- {
- // Generated by: echo -n "xyz" | base64
- CHECK_THAT(toStdVector(Botan::base64_decode("aGVsbG8gd29ybGQ=")), Equals(toStdVector("hello world")));
- CHECK_THAT(toStdVector(Botan::base64_decode("aGVsbG8gd29ybGQh")), Equals(toStdVector("hello world!")));
- CHECK_THAT(toStdVector(Botan::base64_decode("SGVsbG8sIHdvcmxkLg==")), Equals(toStdVector("Hello, world.")));
- CHECK_THAT(toStdVector(Botan::base64_decode("VGhlIDEyIGNoYXJz")), Equals(toStdVector("The 12 chars")));
- CHECK_THAT(toStdVector(Botan::base64_decode("VGhlIDEzIGNoYXJzLg==")), Equals(toStdVector("The 13 chars.")));
- CHECK_THAT(toStdVector(Botan::base64_decode("VGhlIDE0IGNoYXJzLi4=")), Equals(toStdVector("The 14 chars..")));
- CHECK_THAT(toStdVector(Botan::base64_decode("VGhlIDE1IGNoYXJzLi4u")), Equals(toStdVector("The 15 chars...")));
- }
-
-TEST_CASE("Base64 decode string special chars", "[base64]")
- {
- // Generated by: echo -n "xyz" | base64
- auto in1 = std::string("QW4gVVRGLTggdXVtbDogw7w=");
- auto in2 = std::string("V2VpcmQgR2VybWFuIDIgYnl0ZSB0aGluZzogw58u");
- auto out1 = std::string("An UTF-8 uuml: ü");
- auto out2 = std::string("Weird German 2 byte thing: ß.");
- CHECK_THAT(toStdVector(Botan::base64_decode(in1)), Equals(toStdVector(out1)));
- CHECK_THAT(toStdVector(Botan::base64_decode(in2)), Equals(toStdVector(out2)));
- }
-
-TEST_CASE("Base64 decode binary", "[base64]")
- {
- // Generated by: cat /dev/urandom | head -c 3 | tee /tmp/mybinary | hexdump -C && cat /tmp/mybinary | base64
- std::vector<unsigned char> binary0 = {};
- CHECK_THAT(toStdVector(Botan::base64_decode("")), Equals(binary0));
-
- std::vector<unsigned char> binary1 = {0x9b};
- CHECK_THAT(toStdVector(Botan::base64_decode("mw==")), Equals(binary1));
-
- std::vector<unsigned char> binary2 = {0x1c, 0x60};
- CHECK_THAT(toStdVector(Botan::base64_decode("HGA=")), Equals(binary2));
-
- std::vector<unsigned char> binary3 = {0x81, 0x34, 0xbd};
- CHECK_THAT(toStdVector(Botan::base64_decode("gTS9")), Equals(binary3));
-
- std::vector<unsigned char> binary4 = {0x5e, 0x6c, 0xff, 0xde};
- CHECK_THAT(toStdVector(Botan::base64_decode("Xmz/3g==")), Equals(binary4));
-
- std::vector<unsigned char> binary5 = {0xb2, 0xcd, 0xf0, 0xdc, 0x7f};
- CHECK_THAT(toStdVector(Botan::base64_decode("ss3w3H8=")), Equals(binary5));
-
- std::vector<unsigned char> binary6 = {0xfc, 0x56, 0x2d, 0xda, 0xd4, 0x0e};
- CHECK_THAT(toStdVector(Botan::base64_decode("/FYt2tQO")), Equals(binary6));
-
- std::vector<unsigned char> binary7 = {0x29, 0xb2, 0x32, 0x2e, 0x88, 0x41, 0xe8};
- CHECK_THAT(toStdVector(Botan::base64_decode("KbIyLohB6A==")), Equals(binary7));
-
- std::vector<unsigned char> binary8 = {0x0f, 0x0f, 0xce, 0xd9, 0x49, 0x7a, 0xaf, 0x92};
- CHECK_THAT(toStdVector(Botan::base64_decode("Dw/O2Ul6r5I=")), Equals(binary8));
-
- std::vector<unsigned char> binary9 = {0x27, 0x0f, 0xb1, 0x89, 0x82, 0x80, 0x0d, 0xa6, 0x40};
- CHECK_THAT(toStdVector(Botan::base64_decode("Jw+xiYKADaZA")), Equals(binary9));
- }
-
-TEST_CASE("Base64 decode and ignore whitespace", "[base64]")
- {
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string(" Zg=="), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Z g=="), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg =="), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg= ="), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg== "), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("\rZg=="), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("\nZg=="), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("\tZg=="), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg\r=="), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg\n=="), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg\t=="), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg==\r"), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg==\n"), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg==\t"), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("\r Zg=="), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("\n Zg=="), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("\t Zg=="), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg\r =="), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg\n =="), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg\t =="), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg==\r "), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg==\n "), true)), Equals(toStdVector("f")));
- CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg==\t "), true)), Equals(toStdVector("f")));
- }
-
-TEST_CASE("Base64 decode and don't ignore whitespace", "[base64]")
- {
- CHECK_THROWS(Botan::base64_decode(std::string(" Zg=="), false));
- CHECK_THROWS(Botan::base64_decode(std::string("Z g=="), false));
- CHECK_THROWS(Botan::base64_decode(std::string("Zg =="), false));
- CHECK_THROWS(Botan::base64_decode(std::string("Zg= ="), false));
- CHECK_THROWS(Botan::base64_decode(std::string("Zg== "), false));
- CHECK_THROWS(Botan::base64_decode(std::string("\rZg=="), false));
- CHECK_THROWS(Botan::base64_decode(std::string("\nZg=="), false));
- CHECK_THROWS(Botan::base64_decode(std::string("\tZg=="), false));
- CHECK_THROWS(Botan::base64_decode(std::string("Zg\r=="), false));
- CHECK_THROWS(Botan::base64_decode(std::string("Zg\n=="), false));
- CHECK_THROWS(Botan::base64_decode(std::string("Zg\t=="), false));
- CHECK_THROWS(Botan::base64_decode(std::string("Zg==\r"), false));
- CHECK_THROWS(Botan::base64_decode(std::string("Zg==\n"), false));
- CHECK_THROWS(Botan::base64_decode(std::string("Zg==\t"), false));
- CHECK_THROWS(Botan::base64_decode(std::string("\r Zg=="), false));
- CHECK_THROWS(Botan::base64_decode(std::string("\n Zg=="), false));
- CHECK_THROWS(Botan::base64_decode(std::string("\t Zg=="), false));
- CHECK_THROWS(Botan::base64_decode(std::string("Zg\r =="), false));
- CHECK_THROWS(Botan::base64_decode(std::string("Zg\n =="), false));
- CHECK_THROWS(Botan::base64_decode(std::string("Zg\t =="), false));
- CHECK_THROWS(Botan::base64_decode(std::string("Zg==\r "), false));
- CHECK_THROWS(Botan::base64_decode(std::string("Zg==\n "), false));
- CHECK_THROWS(Botan::base64_decode(std::string("Zg==\t "), false));
- }
-
-#endif // BOTAN_HAS_BASE64_CODEC
diff --git a/src/tests/catchy/test_bigint.cpp b/src/tests/catchy/test_bigint.cpp
deleted file mode 100644
index 67821eaf0..000000000
--- a/src/tests/catchy/test_bigint.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-// (C) 2015 Simon Warta (Kullo GmbH)
-// Botan is released under the Simplified BSD License (see license.txt)
-
-#include "catchy_tests.h"
-
-#if defined(BOTAN_HAS_BIGINT)
-
-#include <botan/bigint.h>
-
-using namespace Botan;
-
-TEST_CASE("Bigint basics", "[bigint]")
- {
- SECTION("in 0-bit border")
- {
- BigInt a(0u);
- CHECK_THAT(a.bits(), Equals(0));
- CHECK_THAT(a.bytes(), Equals(0));
- CHECK_THAT(a.to_u32bit(), Equals(0));
- }
- SECTION("above 0-bit border")
- {
- BigInt a(1u);
- CHECK_THAT(a.bits(), Equals(1));
- CHECK_THAT(a.bytes(), Equals(1));
- CHECK_THAT(a.to_u32bit(), Equals(1));
- }
- SECTION("in 8-bit border")
- {
- BigInt a(255u);
- CHECK_THAT(a.bits(), Equals(8));
- CHECK_THAT(a.bytes(), Equals(1));
- CHECK_THAT(a.to_u32bit(), Equals(255));
- }
- SECTION("above 8-bit border")
- {
- BigInt a(256u);
- CHECK_THAT(a.bits(), Equals(9));
- CHECK_THAT(a.bytes(), Equals(2));
- CHECK_THAT(a.to_u32bit(), Equals(256));
- }
- SECTION("in 16-bit border")
- {
- BigInt a(65535u);
- CHECK_THAT(a.bits(), Equals(16));
- CHECK_THAT(a.bytes(), Equals(2));
- CHECK_THAT(a.to_u32bit(), Equals(65535));
- }
- SECTION("above 16-bit border")
- {
- BigInt a(65536u);
- CHECK_THAT(a.bits(), Equals(17));
- CHECK_THAT(a.bytes(), Equals(3));
- CHECK_THAT(a.to_u32bit(), Equals(65536));
- }
- SECTION("in 32-bit border")
- {
- BigInt a(4294967295u);
- CHECK_THAT(a.bits(), Equals(32));
- CHECK_THAT(a.bytes(), Equals(4));
- CHECK_THAT(a.to_u32bit(), Equals(4294967295u));
- }
- SECTION("above 32-bit border")
- {
- BigInt a(4294967296u);
- CHECK_THAT(a.bits(), Equals(33));
- CHECK_THAT(a.bytes(), Equals(5));
- CHECK_THROWS( a.to_u32bit() );
- }
- }
-
-TEST_CASE("Bigint random_integer", "[bigint]")
- {
- RandomNumberGenerator *rng = RandomNumberGenerator::make_rng();
-
- SECTION("min is 0")
- {
- // 0–9
- const size_t MIN = 0;
- const size_t MAX = 10; // excluded
- const int ITERATIONS = 10000;
-
- std::vector<int> counts(MAX, 0);
- std::vector<double> ratios(MAX, 1.0);
-
- for (size_t i = 0; i < ITERATIONS; i++)
- {
- BigInt b = BigInt::random_integer(*rng, MIN, MAX);
- size_t x = b.to_u32bit();
- counts[x]++;
- }
-
- std::stringstream debug;
- for (size_t d = MIN; d < MAX; ++d)
- {
- auto ratio = static_cast<double>(counts[d]) / ITERATIONS;
- ratios[d] = ratio;
-
- if (!debug.str().empty())
- {
- debug << ", ";
- }
- debug << d << ": " << std::setprecision(3) << ratio;
- }
-
- INFO( debug.str() )
-
- // Have ~ 10 % on each digit from 0-9
- CHECK(( 0.085 <= ratios[0] )); CHECK(( ratios[0] <= 0.115 ));
- CHECK(( 0.085 <= ratios[1] )); CHECK(( ratios[1] <= 0.115 ));
- CHECK(( 0.085 <= ratios[2] )); CHECK(( ratios[2] <= 0.115 ));
- CHECK(( 0.085 <= ratios[3] )); CHECK(( ratios[3] <= 0.115 ));
- CHECK(( 0.085 <= ratios[4] )); CHECK(( ratios[4] <= 0.115 ));
- CHECK(( 0.085 <= ratios[5] )); CHECK(( ratios[5] <= 0.115 ));
- CHECK(( 0.085 <= ratios[6] )); CHECK(( ratios[6] <= 0.115 ));
- CHECK(( 0.085 <= ratios[7] )); CHECK(( ratios[7] <= 0.115 ));
- CHECK(( 0.085 <= ratios[8] )); CHECK(( ratios[8] <= 0.115 ));
- CHECK(( 0.085 <= ratios[9] )); CHECK(( ratios[9] <= 0.115 ));
- //CHECK( false );
- }
-
- SECTION("min is 10")
- {
- // 10–19
- const size_t MIN = 10;
- const size_t MAX = 20; // excluded
- const size_t ITERATIONS = 10000;
-
- std::vector<int> counts(MAX, 0);
- std::vector<double> ratios(MAX, 1.0);
-
- for (size_t i = 0; i < ITERATIONS; i++)
- {
- BigInt b = BigInt::random_integer(*rng, MIN, MAX);
- size_t x = b.to_u32bit();
- counts[x]++;
- }
-
- std::stringstream debug;
- for (size_t d = MIN; d < MAX; ++d)
- {
- auto ratio = static_cast<double>(counts[d]) / ITERATIONS;
- ratios[d] = ratio;
-
- if (!debug.str().empty())
- {
- debug << ", ";
- }
- debug << d << ": " << std::setprecision(3) << ratio;
- }
-
- INFO( debug.str() )
-
- // Have ~ 10 % on each digit from 10-19
- CHECK(( 0.085 <= ratios[10] )); CHECK(( ratios[10] <= 0.115 ));
- CHECK(( 0.085 <= ratios[11] )); CHECK(( ratios[11] <= 0.115 ));
- CHECK(( 0.085 <= ratios[12] )); CHECK(( ratios[12] <= 0.115 ));
- CHECK(( 0.085 <= ratios[13] )); CHECK(( ratios[13] <= 0.115 ));
- CHECK(( 0.085 <= ratios[14] )); CHECK(( ratios[14] <= 0.115 ));
- CHECK(( 0.085 <= ratios[15] )); CHECK(( ratios[15] <= 0.115 ));
- CHECK(( 0.085 <= ratios[16] )); CHECK(( ratios[16] <= 0.115 ));
- CHECK(( 0.085 <= ratios[17] )); CHECK(( ratios[17] <= 0.115 ));
- CHECK(( 0.085 <= ratios[18] )); CHECK(( ratios[18] <= 0.115 ));
- CHECK(( 0.085 <= ratios[19] )); CHECK(( ratios[19] <= 0.115 ));
- //CHECK( false );
- }
- }
-
-#endif
diff --git a/src/tests/catchy/test_cvc.cpp b/src/tests/catchy/test_cvc.cpp
deleted file mode 100644
index 2ac6be848..000000000
--- a/src/tests/catchy/test_cvc.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-// (C) 2015 Simon Warta (Kullo GmbH)
-// Botan is released under the Simplified BSD License (see license.txt)
-
-#include "catchy_tests.h"
-
-#if defined(BOTAN_HAS_CVC)
-
-#include <botan/eac_asn_obj.h>
-
-TEST_CASE("human readable time", "[EAC_Time]")
- {
- auto time1 = Botan::EAC_Time("2008-02-01");
- auto time2 = Botan::EAC_Time("2008/02/28");
- auto time3 = Botan::EAC_Time("2004-06-14");
-
- CHECK(( time1.time_is_set() == true ));
- CHECK(( time2.time_is_set() == true ));
- CHECK(( time3.time_is_set() == true ));
-
- CHECK(( time1.readable_string() == "2008/02/01" ));
- CHECK(( time2.readable_string() == "2008/02/28" ));
- CHECK(( time3.readable_string() == "2004/06/14" ));
- }
-
-TEST_CASE("no time", "[EAC_Time]")
- {
- auto time = Botan::EAC_Time("");
- CHECK(( time.time_is_set() == false ));
- }
-
-TEST_CASE("invalis time", "[EAC_Time]")
- {
- CHECK_THROWS( Botan::EAC_Time(" ") );
- CHECK_THROWS( Botan::EAC_Time("2008`02-01") );
- CHECK_THROWS( Botan::EAC_Time("9999-02-01") );
- CHECK_THROWS( Botan::EAC_Time("2000-02-01 17") );
- CHECK_THROWS( Botan::EAC_Time("999921") );
- }
-
-#endif // BOTAN_HAS_CVC
diff --git a/src/tests/catchy/test_stl_util.cpp b/src/tests/catchy/test_stl_util.cpp
deleted file mode 100644
index f7c2c9990..000000000
--- a/src/tests/catchy/test_stl_util.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-// (C) 2015 Simon Warta (Kullo GmbH)
-// Botan is released under the Simplified BSD License (see license.txt)
-
-#include "catchy_tests.h"
-
-#include <botan/internal/stl_util.h>
-
-TEST_CASE("secure vector to string", "[STL_Util]")
- {
- using namespace Botan;
- auto empty = secure_vector<byte>{ };
- auto one = secure_vector<byte>{ 94 };
- auto some = secure_vector<byte>{ 0x48, 0x65, 0x6c, 0x6c, 0x6f };
- // echo -n "ö" | hexdump -C
- auto utf8 = secure_vector<byte>{ 0xc3, 0xb6 };
-
- CHECK_THAT(to_string(empty), Equals(""));
- CHECK_THAT(to_string(one), Equals("^"));
- CHECK_THAT(to_string(some), Equals("Hello"));
- CHECK_THAT(to_string(utf8), Equals("ö"));
- }
diff --git a/src/tests/catchy/test_utils.cpp b/src/tests/catchy/test_utils.cpp
deleted file mode 100644
index eb94be0f4..000000000
--- a/src/tests/catchy/test_utils.cpp
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
-(C) 2015 Simon Warta (Kullo GmbH)
-(C) 2015 Jack Lloyd
-
-Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include "catchy_tests.h"
-
-#include <botan/calendar.h>
-#include <botan/parsing.h>
-#include <botan/loadstor.h>
-#include <botan/internal/rounding.h>
-
-using namespace Botan;
-
-TEST_CASE("round_up strictly positive", "[utils]")
- {
- CHECK_THAT(round_up( 1, 10), Equals(10));
- CHECK_THAT(round_up( 3, 10), Equals(10));
- CHECK_THAT(round_up( 9, 10), Equals(10));
- CHECK_THAT(round_up(10, 10), Equals(10));
-
- CHECK_THAT(round_up( 1, 4), Equals( 4));
- CHECK_THAT(round_up( 3, 4), Equals( 4));
- CHECK_THAT(round_up( 4, 4), Equals( 4));
- CHECK_THAT(round_up( 9, 4), Equals(12));
- CHECK_THAT(round_up(10, 4), Equals(12));
- }
-
-TEST_CASE("round_up zero", "[utils]")
- {
- CHECK_THAT(round_up(0, 2), Equals(0));
- CHECK_THAT(round_up(0, 10), Equals(0));
- CHECK_THAT(round_up(0, 1000), Equals(0));
- CHECK_THAT(round_up(0, 99999), Equals(0));
- CHECK_THAT(round_up(0, 2222222), Equals(0));
- }
-
-TEST_CASE("round_up invalid input", "[utils]")
- {
- CHECK_THROWS(round_up(3, 0));
- CHECK_THROWS(round_up(5, 0));
- }
-
-TEST_CASE("calendar_point constructor works", "[utils]")
- {
- {
- auto point1 = calendar_point(1988, 04, 23, 14, 37, 28);
- CHECK_THAT(point1.year, Equals(1988));
- CHECK_THAT(point1.month, Equals(4));
- CHECK_THAT(point1.day, Equals(23));
- CHECK_THAT(point1.hour, Equals(14));
- CHECK_THAT(point1.minutes, Equals(37));
- CHECK_THAT(point1.seconds, Equals(28));
- }
-
- {
- auto point2 = calendar_point(1800, 01, 01, 0, 0, 0);
- CHECK_THAT(point2.year, Equals(1800));
- CHECK_THAT(point2.month, Equals(1));
- CHECK_THAT(point2.day, Equals(1));
- CHECK_THAT(point2.hour, Equals(0));
- CHECK_THAT(point2.minutes, Equals(0));
- CHECK_THAT(point2.seconds, Equals(0));
- }
-
- {
- auto point = calendar_point(2037, 12, 31, 24, 59, 59);
- CHECK_THAT(point.year, Equals(2037));
- CHECK_THAT(point.month, Equals(12));
- CHECK_THAT(point.day, Equals(31));
- CHECK_THAT(point.hour, Equals(24));
- CHECK_THAT(point.minutes, Equals(59));
- CHECK_THAT(point.seconds, Equals(59));
- }
-
- {
- auto point = calendar_point(2100, 5, 1, 0, 0, 0);
- CHECK_THAT(point.year, Equals(2100));
- CHECK_THAT(point.month, Equals(5));
- CHECK_THAT(point.day, Equals(1));
- CHECK_THAT(point.hour, Equals(0));
- CHECK_THAT(point.minutes, Equals(0));
- CHECK_THAT(point.seconds, Equals(0));
- }
- }
-
-TEST_CASE("calendar_point to stl timepoint and back", "[utils]")
- {
- SECTION("default test")
- {
- auto in = calendar_point(1988, 04, 23, 14, 37, 28);
- auto out = calendar_value(in.to_std_timepoint());
- CHECK_THAT(out.year, Equals(1988));
- CHECK_THAT(out.month, Equals(4));
- CHECK_THAT(out.day, Equals(23));
- CHECK_THAT(out.hour, Equals(14));
- CHECK_THAT(out.minutes, Equals(37));
- CHECK_THAT(out.seconds, Equals(28));
- }
-
- // _mkgmtime on Windows does not work for dates before 1970
- SECTION("first possible time point")
- {
- auto in = calendar_point(1970, 01, 01, 00, 00, 00);
- auto out = calendar_value(in.to_std_timepoint());
- CHECK_THAT(out.year, Equals(1970));
- CHECK_THAT(out.month, Equals(01));
- CHECK_THAT(out.day, Equals(01));
- CHECK_THAT(out.hour, Equals(00));
- CHECK_THAT(out.minutes, Equals(00));
- CHECK_THAT(out.seconds, Equals(00));
- }
-
- SECTION("latest possible time point")
- {
- auto in = calendar_point(2037, 12, 31, 23, 59, 59);
- auto out = calendar_value(in.to_std_timepoint());
- CHECK_THAT(out.year, Equals(2037));
- CHECK_THAT(out.month, Equals(12));
- CHECK_THAT(out.day, Equals(31));
- CHECK_THAT(out.hour, Equals(23));
- CHECK_THAT(out.minutes, Equals(59));
- CHECK_THAT(out.seconds, Equals(59));
- }
-
- SECTION("year too early")
- {
- {
- auto in = calendar_point(1800, 01, 01, 0, 0, 0);
- CHECK_THROWS(in.to_std_timepoint());
- }
-
- {
- auto in = calendar_point(1899, 12, 31, 23, 59, 59);
- CHECK_THROWS(in.to_std_timepoint());
- }
-
- {
- auto in = calendar_point(1969, 12, 31, 23, 59, 58); // time_t = -2
- CHECK_THROWS(in.to_std_timepoint());
- }
-
- {
- auto in = calendar_point(1969, 12, 31, 23, 59, 59); // time_t = -1
- CHECK_THROWS(in.to_std_timepoint());
- }
- }
-
- SECTION("year too late")
- {
- auto in = calendar_point(2038, 01, 01, 0, 0, 0);
- CHECK_THROWS(in.to_std_timepoint());
- }
- }
-
-TEST_CASE("load/store operations", "[utils]")
- {
- const byte mem[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
- 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
-
- const u16bit in16 = 0x1234;
- const u32bit in32 = 0xA0B0C0D0;
- const u64bit in64 = 0xABCDEF0123456789;
-
- CHECK_THAT(get_byte(0, in32), Equals(0xA0));
- CHECK_THAT(get_byte(1, in32), Equals(0xB0));
- CHECK_THAT(get_byte(2, in32), Equals(0xC0));
- CHECK_THAT(get_byte(3, in32), Equals(0xD0));
-
- CHECK_THAT(make_u16bit(0xAA, 0xBB), Equals(0xAABB));
- CHECK_THAT(make_u32bit(0x01, 0x02, 0x03, 0x04), Equals(0x01020304));
-
- CHECK_THAT(load_be<u16bit>(mem, 0), Equals(0x0011));
- CHECK_THAT(load_be<u16bit>(mem, 1), Equals(0x2233));
- CHECK_THAT(load_be<u16bit>(mem, 2), Equals(0x4455));
- CHECK_THAT(load_be<u16bit>(mem, 3), Equals(0x6677));
-
- CHECK_THAT(load_le<u16bit>(mem, 0), Equals(0x1100));
- CHECK_THAT(load_le<u16bit>(mem, 1), Equals(0x3322));
- CHECK_THAT(load_le<u16bit>(mem, 2), Equals(0x5544));
- CHECK_THAT(load_le<u16bit>(mem, 3), Equals(0x7766));
-
- CHECK_THAT(load_be<u32bit>(mem, 0), Equals(0x00112233));
- CHECK_THAT(load_be<u32bit>(mem, 1), Equals(0x44556677));
- CHECK_THAT(load_be<u32bit>(mem, 2), Equals(0x8899AABB));
- CHECK_THAT(load_be<u32bit>(mem, 3), Equals(0xCCDDEEFF));
-
- CHECK_THAT(load_le<u32bit>(mem, 0), Equals(0x33221100));
- CHECK_THAT(load_le<u32bit>(mem, 1), Equals(0x77665544));
- CHECK_THAT(load_le<u32bit>(mem, 2), Equals(0xBBAA9988));
- CHECK_THAT(load_le<u32bit>(mem, 3), Equals(0xFFEEDDCC));
-
- CHECK_THAT(load_be<u64bit>(mem, 0), Equals(0x0011223344556677));
- CHECK_THAT(load_be<u64bit>(mem, 1), Equals(0x8899AABBCCDDEEFF));
-
- CHECK_THAT(load_le<u64bit>(mem, 0), Equals(0x7766554433221100));
- CHECK_THAT(load_le<u64bit>(mem, 1), Equals(0xFFEEDDCCBBAA9988));
-
- // Check misaligned loads:
- CHECK_THAT(load_be<u16bit>(mem + 1, 0), Equals(0x1122));
- CHECK_THAT(load_le<u16bit>(mem + 3, 0), Equals(0x4433));
-
- CHECK_THAT(load_be<u32bit>(mem + 1, 1), Equals(0x55667788));
- CHECK_THAT(load_le<u32bit>(mem + 3, 1), Equals(0xAA998877));
-
- CHECK_THAT(load_be<u64bit>(mem + 1, 0), Equals(0x1122334455667788));
- CHECK_THAT(load_le<u64bit>(mem + 7, 0), Equals(0xEEDDCCBBAA998877));
- CHECK_THAT(load_le<u64bit>(mem + 5, 0), Equals(0xCCBBAA9988776655));
-
- byte outbuf[16] = { 0 };
-
- for(size_t offset = 0; offset != 7; ++offset)
- {
- byte* out = outbuf + offset;
-
- store_be(in16, out);
- CHECK_THAT(out[0], Equals(0x12));
- CHECK_THAT(out[1], Equals(0x34));
-
- store_le(in16, out);
- CHECK_THAT(out[0], Equals(0x34));
- CHECK_THAT(out[1], Equals(0x12));
-
- store_be(in32, out);
- CHECK_THAT(out[0], Equals(0xA0));
- CHECK_THAT(out[1], Equals(0xB0));
- CHECK_THAT(out[2], Equals(0xC0));
- CHECK_THAT(out[3], Equals(0xD0));
-
- store_le(in32, out);
- CHECK_THAT(out[0], Equals(0xD0));
- CHECK_THAT(out[1], Equals(0xC0));
- CHECK_THAT(out[2], Equals(0xB0));
- CHECK_THAT(out[3], Equals(0xA0));
-
- store_be(in64, out);
- CHECK_THAT(out[0], Equals(0xAB));
- CHECK_THAT(out[1], Equals(0xCD));
- CHECK_THAT(out[2], Equals(0xEF));
- CHECK_THAT(out[3], Equals(0x01));
- CHECK_THAT(out[4], Equals(0x23));
- CHECK_THAT(out[5], Equals(0x45));
- CHECK_THAT(out[6], Equals(0x67));
- CHECK_THAT(out[7], Equals(0x89));
-
- store_le(in64, out);
- CHECK_THAT(out[0], Equals(0x89));
- CHECK_THAT(out[1], Equals(0x67));
- CHECK_THAT(out[2], Equals(0x45));
- CHECK_THAT(out[3], Equals(0x23));
- CHECK_THAT(out[4], Equals(0x01));
- CHECK_THAT(out[5], Equals(0xEF));
- CHECK_THAT(out[6], Equals(0xCD));
- CHECK_THAT(out[7], Equals(0xAB));
- }
-}
-
-TEST_CASE("uint32 parsing valid", "[utils]")
- {
- CHECK_THAT(to_u32bit("0"), Equals(0));
- CHECK_THAT(to_u32bit("1"), Equals(1));
- CHECK_THAT(to_u32bit("2"), Equals(2));
- CHECK_THAT(to_u32bit("10"), Equals(10));
- CHECK_THAT(to_u32bit("100"), Equals(100));
- CHECK_THAT(to_u32bit("1000"), Equals(1000));
- CHECK_THAT(to_u32bit("10000"), Equals(10000));
- CHECK_THAT(to_u32bit("100000"), Equals(100000));
- CHECK_THAT(to_u32bit("1000000"), Equals(1000000));
- // biggest allowed value
- CHECK_THAT(to_u32bit("4294967295"), Equals(4294967295));
-
- // leading zeros
- CHECK_THAT(to_u32bit("00"), Equals(0));
- CHECK_THAT(to_u32bit("01"), Equals(1));
- CHECK_THAT(to_u32bit("02"), Equals(2));
- CHECK_THAT(to_u32bit("010"), Equals(10));
- CHECK_THAT(to_u32bit("0000000000000000000000000010"), Equals(10));
-
- // leading and trailing whitespace
- CHECK_THROWS(to_u32bit(" 1"));
- CHECK_THROWS(to_u32bit(" 1 "));
- CHECK_THROWS(to_u32bit("\n1"));
- CHECK_THROWS(to_u32bit("1\n"));
- CHECK_THROWS(to_u32bit("1 5"));
- CHECK_THROWS(to_u32bit("1\t5"));
- CHECK_THROWS(to_u32bit("1\n5"));
-
- // Other stuff that is no digit
- CHECK_THROWS(to_u32bit("1Z"));
-
- // invalid input
- CHECK_THROWS(to_u32bit(""));
- CHECK_THROWS(to_u32bit(" "));
- CHECK_THROWS(to_u32bit("!"));
- //CHECK_THROWS(to_u32bit("1!"));
- CHECK_THROWS(to_u32bit("!1"));
-
- // Avoid overflow: value too big for uint32
- CHECK_THROWS(to_u32bit("4294967296"));
- }
diff --git a/src/tests/catchy/test_x509.cpp b/src/tests/catchy/test_x509.cpp
deleted file mode 100644
index cb2f8f0cf..000000000
--- a/src/tests/catchy/test_x509.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-// (C) 2015 Simon Warta (Kullo GmbH)
-// Botan is released under the Simplified BSD License (see license.txt)
-
-#include "catchy_tests.h"
-
-#if defined(BOTAN_HAS_ASN1)
-
-#include <botan/exceptn.h>
-#include <botan/asn1_time.h>
-
-using namespace Botan;
-using namespace Catch;
-
-TEST_CASE("human readable time", "[X509]")
- {
- auto time1 = X509_Time("0802010000Z", ASN1_Tag::UTC_TIME);
- auto time2 = X509_Time("0802011724Z", ASN1_Tag::UTC_TIME);
- auto time3 = X509_Time("040614233430Z", ASN1_Tag::UTC_TIME);
-
- CHECK_THAT(time1.time_is_set(), Equals(true));
- CHECK_THAT(time2.time_is_set(), Equals(true));
- CHECK_THAT(time3.time_is_set(), Equals(true));
-
- CHECK_THAT(time1.readable_string(), Equals("2008/02/01 00:00:00 UTC"));
- CHECK_THAT(time2.readable_string(), Equals("2008/02/01 17:24:00 UTC"));
- CHECK_THAT(time3.readable_string(), Equals("2004/06/14 23:34:30 UTC"));
- }
-
-TEST_CASE("Implicit copy constructor", "[X509]")
- {
- auto time_orig = X509_Time("0802010000Z", ASN1_Tag::UTC_TIME);
- auto time_copy = time_orig;
-
- // Check that implicit copy and assignment work:
- // time_copy and time_orig must have the same data but
- // must sit at different places in memory
- CHECK((time_orig == time_copy));
-
- auto address1 = reinterpret_cast<uintptr_t>(&time_orig);
- auto address2 = reinterpret_cast<uintptr_t>(&time_copy);
-
- CHECK_THAT(address1, Not(Equals(address2)));
- }
-
-TEST_CASE("no time", "[X509]")
- {
- auto time = X509_Time();
- CHECK_THAT(time.time_is_set(), Equals(false));
- }
-
-TEST_CASE("valid UTCTime", "[X509]")
- {
- SECTION("precision: minute; including timezone: no", "Length 11")
- {
- CHECK_NOTHROW(X509_Time("0802010000Z", ASN1_Tag::UTC_TIME));
- CHECK_NOTHROW(X509_Time("0802011724Z", ASN1_Tag::UTC_TIME));
- CHECK_NOTHROW(X509_Time("0406142334Z", ASN1_Tag::UTC_TIME));
- CHECK_NOTHROW(X509_Time("9906142334Z", ASN1_Tag::UTC_TIME));
- CHECK_NOTHROW(X509_Time("0006142334Z", ASN1_Tag::UTC_TIME));
- }
-
- SECTION("precision: seconds; including timezone: no", "Length 13")
- {
- CHECK_NOTHROW(X509_Time("080201000000Z", ASN1_Tag::UTC_TIME));
- CHECK_NOTHROW(X509_Time("080201172412Z", ASN1_Tag::UTC_TIME));
- CHECK_NOTHROW(X509_Time("040614233433Z", ASN1_Tag::UTC_TIME));
- CHECK_NOTHROW(X509_Time("990614233444Z", ASN1_Tag::UTC_TIME));
- CHECK_NOTHROW(X509_Time("000614233455Z", ASN1_Tag::UTC_TIME));
- }
-
- SECTION("precision: minute; including timezone: yes", "Length 15")
- {
- // Valid times that are not supported by Botan
- CHECK_THROWS_AS(X509_Time("0802010000-0000", ASN1_Tag::UTC_TIME), Unsupported_Argument);
- CHECK_THROWS_AS(X509_Time("0802011724+0000", ASN1_Tag::UTC_TIME), Unsupported_Argument);
- CHECK_THROWS_AS(X509_Time("0406142334-0500", ASN1_Tag::UTC_TIME), Unsupported_Argument);
- CHECK_THROWS_AS(X509_Time("9906142334+0500", ASN1_Tag::UTC_TIME), Unsupported_Argument);
- CHECK_THROWS_AS(X509_Time("0006142334-0530", ASN1_Tag::UTC_TIME), Unsupported_Argument);
- CHECK_THROWS_AS(X509_Time("0006142334+0530", ASN1_Tag::UTC_TIME), Unsupported_Argument);
- }
-
- SECTION("precision: seconds; including timezone: yes", "Length 17")
- {
- // Valid times that are not supported by Botan
- CHECK_THROWS_AS(X509_Time("080201000000-0000", ASN1_Tag::UTC_TIME), Unsupported_Argument);
- CHECK_THROWS_AS(X509_Time("080201172412+0000", ASN1_Tag::UTC_TIME), Unsupported_Argument);
- CHECK_THROWS_AS(X509_Time("040614233433-0500", ASN1_Tag::UTC_TIME), Unsupported_Argument);
- CHECK_THROWS_AS(X509_Time("990614233444+0500", ASN1_Tag::UTC_TIME), Unsupported_Argument);
- CHECK_THROWS_AS(X509_Time("000614233455-0530", ASN1_Tag::UTC_TIME), Unsupported_Argument);
- CHECK_THROWS_AS(X509_Time("000614233455+0530", ASN1_Tag::UTC_TIME), Unsupported_Argument);
- }
- }
-
-TEST_CASE("invalid UTCTime", "[X509]")
- {
- // invalid length
- CHECK_THROWS(X509_Time("", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time(" ", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("2008`02-01", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("9999-02-01", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("2000-02-01 17", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("999921", ASN1_Tag::UTC_TIME));
-
- // valid length 13 -> range check
- CHECK_THROWS(X509_Time("080201000061Z", ASN1_Tag::UTC_TIME)); // seconds too big (61)
- CHECK_THROWS(X509_Time("080201000060Z", ASN1_Tag::UTC_TIME)); // seconds too big (60, leap seconds not covered by the standard)
- CHECK_THROWS(X509_Time("0802010000-1Z", ASN1_Tag::UTC_TIME)); // seconds too small (-1)
- CHECK_THROWS(X509_Time("080201006000Z", ASN1_Tag::UTC_TIME)); // minutes too big (60)
- CHECK_THROWS(X509_Time("080201240000Z", ASN1_Tag::UTC_TIME)); // hours too big (24:00)
-
- // valid length 13 -> invalid numbers
- CHECK_THROWS(X509_Time("08020123112 Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("08020123112!Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("08020123112,Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("08020123112\nZ", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("080201232 33Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("080201232!33Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("080201232,33Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("080201232\n33Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("0802012 3344Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("0802012!3344Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("0802012,3344Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("08022\n334455Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("08022 334455Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("08022!334455Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("08022,334455Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("08022\n334455Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("082 33445511Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("082!33445511Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("082,33445511Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("082\n33445511Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("2 2211221122Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("2!2211221122Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("2,2211221122Z", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("2\n2211221122Z", ASN1_Tag::UTC_TIME));
-
- // wrong time zone
- CHECK_THROWS(X509_Time("0802010000", ASN1_Tag::UTC_TIME));
- CHECK_THROWS(X509_Time("0802010000z", ASN1_Tag::UTC_TIME));
- }
-
-#endif // BOTAN_HAS_ASN1
diff --git a/src/tests/data/base64.vec b/src/tests/data/base64.vec
new file mode 100644
index 000000000..e1aa028a0
--- /dev/null
+++ b/src/tests/data/base64.vec
@@ -0,0 +1,73 @@
+
+[valid]
+# empty string
+Binary =
+Base64 =
+
+Binary = 66
+Base64 = Zg==
+
+Binary = 666F
+Base64 = Zm8=
+
+Binary = 666F6F
+Base64 = Zm9v
+
+Binary = 68656C6C6F20776F726C64
+Base64 = aGVsbG8gd29ybGQ=
+
+Binary = 68656C6C6F20776F726C6421
+Base64 = aGVsbG8gd29ybGQh
+
+Binary = 48656C6C6F2C20776F726C642E
+Base64 = SGVsbG8sIHdvcmxkLg==
+
+Binary = 546865203132206368617273
+Base64 = VGhlIDEyIGNoYXJz
+
+Binary = 5468652031332063686172732E
+Base64 = VGhlIDEzIGNoYXJzLg==
+
+Binary = 5468652031342063686172732E2E
+Base64 = VGhlIDE0IGNoYXJzLi4=
+
+Binary = 5468652031352063686172732E2E2E
+Base64 = VGhlIDE1IGNoYXJzLi4u
+
+Binary = 416E205554462D382075756D6C3A20C3BC
+Base64 = QW4gVVRGLTggdXVtbDogw7w=
+
+Binary = 5765697264204765726D616E20322062797465207468696E673A20C39F2E
+Base64 = V2VpcmQgR2VybWFuIDIgYnl0ZSB0aGluZzogw58u
+
+Binary = 9B
+Base64 = mw==
+
+Binary = 1C60
+Base64 = HGA=
+
+Binary = 8134BD
+Base64 = gTS9
+
+Binary = 5E6CFFDE
+Base64 = Xmz/3g==
+
+Binary = b2cdf0dc7f
+Base64 = ss3w3H8=
+
+Binary = fc562ddad40e
+Base64 = /FYt2tQO
+
+Binary = 29b2322e8841e8
+Base64 = KbIyLohB6A==
+
+Binary = 0f0fced9497aaf92
+Base64 = Dw/O2Ul6r5I=
+
+Binary = 270fb18982800da640
+Base64 = Jw+xiYKADaZA
+
+[invalid]
+Base64 = ZOOL!isnotvalidbase64
+
+Base64 = Neitheris:this?
diff --git a/src/tests/data/bcrypt.vec b/src/tests/data/bcrypt.vec
new file mode 100644
index 000000000..c78ab970a
--- /dev/null
+++ b/src/tests/data/bcrypt.vec
@@ -0,0 +1,9 @@
+
+
+# Generated by jBCrypt 0.3
+Password = 616263
+Passhash = $2a$05$DfPyLs.G6.To9fXEFgUL1O6HpYw3jIXgPcl/L3Qt3jESuWmhxtmpS
+
+# http://www.openwall.com/lists/john-dev/2011/06/19/2
+Password = A3
+Passhash = $2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq
diff --git a/src/tests/data/bigint.vec b/src/tests/data/bigint.vec
new file mode 100644
index 000000000..bba83deb6
--- /dev/null
+++ b/src/tests/data/bigint.vec
@@ -0,0 +1,2582 @@
+[Addition]
+In1 = 0x0
+In2 = 0x0
+Output = 0x0
+
+In1 = 0x0
+In2 = 0x1
+Output = 0x1
+
+In1 = 0x1
+In2 = 0x0
+Output = 0x1
+
+In1 = 0x1
+In2 = 0x1
+Output = 0x2
+
+In1 = 0x1
+In2 = -0x1
+Output = 0x0
+
+In1 = 0x5
+In2 = 0x0
+Output = 0x5
+
+In1 = -0x5
+In2 = 0x0
+Output = -0x5
+
+In1 = 0x0
+In2 = 0x5
+Output = 0x5
+
+In1 = 0xFF
+In2 = 0x1
+Output = 0x100
+
+In1 = 0xFFFF
+In2 = 0x1
+Output = 0x10000
+
+In1 = 0xFFFFFFFF
+In2 = 0x1
+Output = 0x100000000
+
+In1 = 0xFFFFFFFFFFFFFFFF
+In2 = 0x1
+Output = 0x10000000000000000
+
+In1 = 0x1BA7129B437EF98
+In2 = 0x1BA7129B437EF98
+Output = 0x374E253686FDF30
+
+In1 = 0x7FFFFFFFFFFFFFFF
+In2 = 0xFFFFFFFFFFFF
+Output = 0x8000FFFFFFFFFFFE
+
+In1 = 0x7FFFFFFFFFFFFFFF
+In2 = 0x1FFFFFFFFF
+Output = 0x8000001FFFFFFFFE
+
+In1 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+In2 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+Output = 0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+
+In1 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+In2 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+Output = 0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+
+In1 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+In2 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+Output = 0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+
+In1 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+In2 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+Output = 0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+
+In1 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+In2 = 0x10000000000000000
+Output = 0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF
+
+In1 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+In2 = 0x1
+Output = 0x100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+
+In1 = -0x31CB6DFD33AA855F61B671C2B7A4972C47FDE3DEED69355B0793E1AC350FC8E5DAB5E38E60696D4220DE0557049C04CA1BE7A909D0DFE3D7F2450528554D
+In2 = -0x4FAF03723E
+Output = -0x31CB6DFD33AA855F61B671C2B7A4972C47FDE3DEED69355B0793E1AC350FC8E5DAB5E38E60696D4220DE0557049C04CA1BE7A909D0DFE3D7F294B42BC78B
+
+In1 = 0x2DEBD3724F91912E542CDF60606F9FB9F07633A66D8F9CBABA08C0605FA9EEEC16C2DF65D47113291EF2
+In2 = -0x497EE12838529EEAF98B7A9646B59E07167D3005EA4648CA2B1D3C3EC55AB04E58927611E5
+Output = 0x2DEBD3724F48124D2BF48CC17576143F5A2F7E0866791F8AB41E7A17957ED1AFD7FD84B5861880B30D0D
+
+In1 = 0x6792AC6F0
+In2 = 0x1DA0E10503E00FCDEC773EA1330EA45DE602FE
+Output = 0x1DA0E10503E00FCDEC773EA1330EAAD710C9EE
+
+In1 = -0x27734811B5580DBA54C80C6D9C057889E8A71FA5D1D3726A18EF26FE5DB08BED2BBC06D11C049378C49
+In2 = 0x3DE58956EE296060A33D7DDA649E69570ECFB2968E85D1CE72E30FBB9A9C0598028F6EF0B8CFD0DB0D4FB6F06D9F48FB6F7A927E7F644DF1C7DC
+Output = 0x3DE58956EE296060A33D7DDA649E69570C587E15733050F2CD968EF4C0DBAE0F6404FCF65BB299B46BC0C48087C4403C9CBED2116DA404BA3B93
+
+In1 = -0x7D4DC4A968F81D20854DEEAC5B77B64A33470756A2BA41F83BB9E9A9CFA06A0E6D2FB7D6A754762EA165DA
+In2 = 0x7D5C11470F594E657B88A67443DFDDECB0FE57BEEB07F5C2AE4BB8DC6C1E
+Output = -0x7D4DC4A968F81D20854DEEAC5AFA5A38EC37AE083D3EB951C77609CBE2EF6BB6AE44AFE0E4A62A75C4F9BC
+
+In1 = 0x139344D0E396BA8ACA4221920CF3A7376C7F2A3C4835A9D97454F86
+In2 = 0xBCF9A6F9335AC6C0933269C0D70CD977DB93EB525B5EF59FE1CF3EF9950D00D107A74BBA81137B1645E5D69C7130
+Output = 0xBCF9A6F9335AC6C0933269C0D70CD977DB93EC8B8FAC03D94D77EB9DB72621A0421AC28273B73F99A0836DE1C0B6
+
+In1 = 0xEC36DC35526EF1B844B26079B9D5456CFC2F645AEA9D8B2C38EFC6EF48BD723CF
+In2 = -0x466A4EA57C0EF2266F6BE04CB94D48E0B993E3472F0
+Output = 0xEC36DC35526EF1B844B260334F869FF0ED3D3DEB7EBD3E72EBA6E635B4DA2B0DF
+
+In1 = 0x6B8B8B01CEF353F5BC8A1ADD88EACCFABAF15C904D7C65625FCA6F9436441951D79C5B869FBF8C5441AF21EA89F6DD3CE039D535A65A980E1CF7A
+In2 = -0x14343B3A5134010B9D7C83E2C01DD65E46F5CC1AC5CF38192A1D422AFE1324A447DE5E19135FA3B1DB2714
+Output = 0x6B8B8B01CEF353F5BC8A1ADD88EACCF977ADA8EB3A3C54A8880231683466B36D683F99DA42CC0AC19FDAFF3AA8C492F86253F3A470605CF06A866
+
+In1 = -0x1E3A56C5AC5932B82D4B9603A4FA6D4BF0CED0C491F8A09BF4203BDC2DCFA8C40A1F99A678DC669E1
+In2 = 0x40491CCEF0700F7C5E1BC5FCA64E3C68
+Output = -0x1E3A56C5AC5932B82D4B9603A4FA6D4BF0CED0C491F8A09BF01BAA0F3EC8A7CC443DDD46AE7782D79
+
+In1 = -0x86537488CD11859CF3EAF06AA893670B3A739CED553D152352100EBBDB2CA971802DF2553F77E24B5AD2A6137E0516B
+In2 = 0x488AB9DEDE8BB0932CB000EAE2CA82FBCD62A021DA9EC4904C6F7103CFC26ED74EA7B6ACB267BFDF98BFCA7B8B4DF6D82F97790A363F9B
+Output = 0x488AB9DEDE8BB08AC778B85E11B2292C8EB39977516853DCA535A22E7BF11CA22DA6CAEEFF9D28C795E0A52793CFD222826D17D255EE30
+
+In1 = -0x2CCF281FB315255B1F6E31F597A9BD5F00BB938A7D9ED80B8C889AAD25ECE3313C8B50EFA175CB40647CB57B2673DA26AEED
+In2 = 0x3AB8C0A37
+Output = -0x2CCF281FB315255B1F6E31F597A9BD5F00BB938A7D9ED80B8C889AAD25ECE3313C8B50EFA175CB40647CB57B26702E9AA4B6
+
+In1 = -0x4A9B578ACA5D1EA250BABE2F2ABD410B05F9298CCE37D5CDA089D7AA6FA7A339C27BC38D586230A89C6ED7C62D9952B1937BBE623294B0D31E887E0DAFA24772
+In2 = 0x68A7F76ECAF9E8A9DF5D04A8F237C241E3B0651CF36256D3E23F96DC5415F634CDE
+Output = -0x4A9B578ACA5D1EA250BABE2F2ABD410B05F9298CCE37D5CDA089D7AA6FA79CAF4304D6DDB9D792B2CC2448A2B17534768D29EF2C0D2772AF251AB8CC503EFA94
+
+In1 = -0xEA9861C035A7F78F79D402D1
+In2 = -0x1B622BF9A4C6A10721233B00E2C90C8690742FFA0D903BC1B7B2D03288D3839336AE0D5AF4
+Output = -0x1B622BF9A4C6A10721233B00E2C90C8690742FFA0D903BC1B89D689449092B8AC627E15DC5
+
+In1 = 0x49943D5A8D58F68F7D5D98F2A0AD8E8010C86EF6C311447E4A7BBA1DB4C11CBE554A10F2A31F622085131B15B891ADB95A0CB02D25FC93708855963
+In2 = -0x116AAFB7BE514668033D0A0B8E3B3CEAC557C65B7713DD4A
+Output = 0x49943D5A8D58F68F7D5D98F2A0AD8E8010C86EF6C311447E4A7BBA1DB4C11CBE554A10F18C7466A49FFEB49584C10D007658E180D0802DB91717C19
+
+In1 = -0x13158EF38BE6500747FCDB4432C217C992C9B5E20BDDD910891447E21B4F008EE4
+In2 = 0x38370F553F6BDCFD3028116984B2962818B6E5F65FDE8F845CB9415CC23F9DB26E9D179E18FC835124ACAAA16F38D977F7BF6E579DF5E3E2BF253F7
+Output = 0x38370F553F6BDCFD3028116984B2962818B6E5F65FDE8F845CB9402B695064F4099CA31E4B48402503301174D3DAB8BA1A2E65C65977C22DCF1C513
+
+In1 = 0x385D4675443BAFCE295DAB2E2DB3E3CB3217507541D0EF36AB6C922CC844B2A0227816E5B3C6355C24E00AD015EE1C
+In2 = 0x106EC3C473D2D7DE8998F946354C604F5
+Output = 0x385D4675443BAFCE295DAB2E2DB3E3CB3217507541D0EF36AB6C922CC844B3A70EB45E22E1441DF5B4746E24DBF311
+
+In1 = 0x9CD07AF9B4785B26D2E5F9C4C0D104DC4287C42EDB5FF52C87315FEAA15BEB3E2C66B8615E1487B17902
+In2 = -0xE3AD3F9961602DAC3DDBA390AC1E96AAC8C45184AF0FE03525D96DA0F
+Output = 0x9CD07AF9B4785B26D2E5F9C4C0C2CA0848F1AE2C009C17724E269E0136AF5EF9141BC7635AC22A1A9EF3
+
+In1 = 0xE2D8E7F293F2373C51B646D81274B2CABD27372090A2D3714AD59BD3
+In2 = 0x3E3
+Output = 0xE2D8E7F293F2373C51B646D81274B2CABD27372090A2D3714AD59FB6
+
+In1 = -0x44115A4B59BE63F072FDD861F4E7EC64D30157B6D92FA67CBF661CAD4F96309BA78ADF09314309A440FA163DC20A9A9
+In2 = -0xCFBE263DD0A0251C9706E66C7F4B753B
+Output = -0x44115A4B59BE63F072FDD861F4E7EC64D30157B6D92FA67CBF661CAD4F9630A8A36D42E63B455B6DB1687D05B6C1EE4
+
+In1 = 0xB3481E6859024D
+In2 = -0x2D09421F94471EA0D9A09CF9C7309332E7C8E59BAE4953347C9C5265F5D3B2E25CF582F0BCA0919641AD90895EA43B46ECA0E19BE9B54FE652A14CC7F5
+Output = -0x2D09421F94471EA0D9A09CF9C7309332E7C8E59BAE4953347C9C5265F5D3B2E25CF582F0BCA0919641AD90895EA43B46ECA0E19BE9B49C9E3438F3C5A8
+
+In1 = 0x255D7BA88D09ABA60C035ED8ABB89A8D02254911BA235C97C3132E9B18DB9E7E391AA646A2D1EC2ED4CA0800
+In2 = 0x84220D06C756970279F399BC07C7D89F24779D5D1144A4339511626ADCE96AE00C7766D34D7DD546F1EE04F837DC185BD3B5B86479DC970FEE79F8
+Output = 0x84220D06C756970279F399BC07C7D8C481F345EA1AF04A3F98703B169583F7E231C0788D70DA6D0A051CA011137A9694EE5BFF074BC8C5E4B881F8
+
+In1 = -0xE642F1B
+In2 = -0x6D778DB5694A6C7180304EB1FAD28D51939E45AEA8CFE43FD65730DCBBDE77A8D5055F4050CBB1507B800376D29048662F8D16
+Output = -0x6D778DB5694A6C7180304EB1FAD28D51939E45AEA8CFE43FD65730DCBBDE77A8D5055F4050CBB1507B800376D290487493BC31
+
+In1 = 0xF52FCC04B4A30DC9136AEEDEC91CB994036FA80CFBB5DCBBCE75CDF0C41BE8B93BBCBDF067B3C97B1EA059EFCD1B83D
+In2 = -0x7B3BD57EE9BA2AC03FE0C8E41CA1AD40666340C61712314DB2832D879EA95011FD3D80E6F
+Output = 0xF52FCC04B4A30DC9136AEE638D473AAA4944E7CD1AECF89F2CC88D8A60DB22A2298B703DE48641DC755047F28F9A9CE
+
+In1 = 0x5BBE86E0D10ED4A4259DF61CAB3A
+In2 = -0x9ADFDFD329CA3359E12D474ED10BEB5251A752BFB473950
+Output = -0x9ADFDFD329CA3359E1278B6662FEDA650764F8E052A8E16
+
+In1 = -0x2B832987277E4971FA111454E665CBBABC55C2C457D549F4581BF72
+In2 = 0x3287838CC03525B22C894A4CABDB91F9426E356DB3921A79106E19566F5848C15F4B4E9F80F2
+Output = 0x3287838CC03525B22C89479479431F815DD715CCA24CCC12B3B26D91132C03440AAC091DC180
+
+In1 = 0xF9458F73A7B72F27EFFB031AE424F1308B171B57F07A9EB918F8045973AF186C7427DF1CDE10C24E8BC6E8706ADA20F5F1BA4EE3356C1DCD65
+In2 = -0x1A658503EC5C465A561C335A392C06A7BB05556D04BC78B192BC105480F6BE8B54339F3097ED82F5F1C6403AE266E2AD64300288E48B32873
+Output = 0xF79F372368F16AC24A993FE5409230C60F66C601202ED72DFFCC43542B9FAC83BEE4A529D491EA1F2CAA846CBCB3B2CB1B774EBAA7236AA4F2
+
+In1 = -0x169740C522EB8836AE0D0E7DA06752EFE505EF97A73AF4E3FEE5C91A8C05E1131CA1593F8DE1F4BBEE03B80F6A8AFE508F6E6837295D1C28
+In2 = 0xA65C24F
+Output = -0x169740C522EB8836AE0D0E7DA06752EFE505EF97A73AF4E3FEE5C91A8C05E1131CA1593F8DE1F4BBEE03B80F6A8AFE508F6E68371EF759D9
+
+In1 = 0x1AB82F244FEF0640DB4A97D7214720EC18B4B77C1FBC08F314BD784897CCF9E185298555988C9574562E4C77F4EC650DA19C09C0D89035EDCEADB5
+In2 = 0x167AAF488058CE55F05B6AE43198B1A80D9E8D99BFA9A20003B335F082E226E8DD5631DD2E7FB2
+Output = 0x1AB82F244FEF0640DB4A97D7214720EC18B4B77C3636B83B9516469E882864C5B6C236FDA62B230E15D7EE77F89F9AFE247E30A9B5E667CAFD2D67
+
+In1 = -0x10D5DE9388F06
+In2 = -0x3E24151D5BE9F749B196896BFC6568A77DAF0739B66900E7A1DEA64D47B6BA15E2C72B3EA12A7062B
+Output = -0x3E24151D5BE9F749B196896BFC6568A77DAF0739B66900E7A1DEA64D47B6BA15E2C73C147FBDF9531
+
+In1 = 0x626F98431DDA4857818188C5C4759289DA8F766A9CBE73B37FA2392EB8C9CEDB39E61F
+In2 = -0x36C1E7ADC26936882E2C9A38072B2EF0C76CE3FA6C87
+Output = 0x626F98431DDA4857818188C5C43ED0A22CCD0D3414904719479B0DFFC80261F73F7998
+
+In1 = -0x4
+In2 = -0x4F168C48971684B343A380811A468C48784CF8DAA8E3DD3893F846BAF37323030A2F
+Output = -0x4F168C48971684B343A380811A468C48784CF8DAA8E3DD3893F846BAF37323030A33
+
+In1 = -0x63370496EAA7F2FA4B03BE322CC91B18BD97ED204A1826C819458ABA6925DE0C
+In2 = 0x4E2A2C70A
+Output = -0x63370496EAA7F2FA4B03BE322CC91B18BD97ED204A1826C819458AB586831702
+
+In1 = -0xA7F8E69657921ED1F8433D95D3CB4C65B0AD08E4AFD6898EA0B3B4711A7178C16B60D742F2F5156C39D1810E
+In2 = 0x3CDF24E7B7A33ABD03CB9F1706E630A605C4B4BBC230D2F99A11BD2739D60126BD260674D14139ECF4C90
+Output = -0xA7F518A40916A49E4C7300DBE25ADE02A64CAC99641A6681711A135547FDDB6158F504E28BA801589B02347E
+
+In1 = -0x17A057602CF743924B6A4AB0E9939C85EBF369409A3AD000AB938CD0644AAB1C6A03FB97FA3FA9C629F37792889319F38782B3A23C842268982E39FCF7
+In2 = -0x14986367147AE2D224A9FB19A08E2134A7153CAA49
+Output = -0x17A057602CF743924B6A4AB0E9939C85EBF369409A3AD000AB938CD0644AAB1C6A03FB97FA3FA9C63E8BDAF99D0DFCC5AC2CAEBBDD12439D3F4376A740
+
+In1 = -0xFCBC189F66432585076812699F4E42AAF5C3FC9061E9B5933356B7FC1448A1210CC1B87314DDF814361A8
+In2 = -0x1CD60D0606E846CFEFE36BC897203517E2F8227489EE8F909F5C70229F524AFCA8D682AE40C87F302DEA78C48B2DDBEDA6FD62306CF1400D4EB0
+Output = -0x1CD60D0606E846CFEFE36BC897203527AEB9AC6AEE20E7E115DD96BC943675AC05164BB45F63D8636355F885CFB7EDFE7318E961BAD0C150B058
+
+In1 = 0x223AD9BB2B417744EB50C54710B1E535851C0A4CE28558817E6A16FA1DEC1C302EEDEB52375A9712B35461C40E36F1935B03D83D8928C70
+In2 = 0xF9ADDF1B8C21DE8E903DC3
+Output = 0x223AD9BB2B417744EB50C54710B1E535851C0A4CE28558817E6A16FA1DEC1C302EEDEB52375A9712B35461C41DD1CF8513C5F626722CA33
+
+In1 = -0xA6005ED6D3C542C8C3B3CF9D0E6CC1C355A9F12F8AC043F1BB93451491237CB723DA0F76A1D040E4848F0392FBC4D5D06FC8017909446C45573159E854
+In2 = -0xD521F630AF6ED1802E37053D3A173AFEED8AED368B68BECF5404A7855D905AB23151E3E03F3561EC6C662B
+Output = -0xA6005ED6D3C542C8C3B3CF9D0E6CC1C355AAC65180F0F3608D13734B9660B6CE5ED8FD018F06CC4D435E5797A34A3360CA7A32CAED24AB7AB91DC64E7F
+
+In1 = 0xC9288E6D4476953C30937FC29A
+In2 = 0x53241A699F33D008F6DE731D9EC0C995635E27FC351C3B9667FE9F97FAD14715F5519F9C85679D8C3610A1D
+Output = 0x53241A699F33D008F6DE731D9EC0C995635E27FC351C3B9667FE9F97FAD153A87E3873E3EEBB60956E0CCB7
+
+In1 = -0x14D6605B6CA0BED0E3C6E15DA4D7414FBE269A0CE226CCD6B053A8A97064D8B43B398F28D94EF83D155B9A39335C08
+In2 = -0x38223FD65C8CA3CF81E65A30EC9FBC385B453AD0E22264BB681667035C2F726459A242A646EE55D0C4B801B957C5E9A
+Output = -0x396FA5DC1356AFBC9022C846C6ED304D5727A471B044D188D31BA18DF335BFEF9D55DB98D4834554960DBB5CEAFBAA2
+
+In1 = -0x9250771C
+In2 = -0x5041B8CD1CADE059F336C29C205B994C1105613021BD0BF840980D52E884ED3945A607E1D3673BC81D7EE4BC59FD896B82EA9BA3A8279CE83F29BA
+Output = -0x5041B8CD1CADE059F336C29C205B994C1105613021BD0BF840980D52E884ED3945A607E1D3673BC81D7EE4BC59FD896B82EA9BA3A8279D7A8FA0D6
+
+In1 = -0x252555C6ECA1C9C564021DB32BA447987766DFB5F3
+In2 = -0xB51B999F81898F62EA530710294E7DCA18433099E063C4052B5D7C91BD3385F2CD1F13CE29A2321475B8A41E0722
+Output = -0xB51B999F81898F62EA530710294E7DCA18433099E063C4052B82A1E7842027BC928315EBDCCDD65C0E300AFDBD15
+
+In1 = 0xAA0A5EDC83FC46646DB83AA93BFB2A84EA8A836EF67B0F3658E9769B60E4300BEF0E67F28B2DD7F8
+In2 = -0x61223220ECC267957
+Output = 0xAA0A5EDC83FC46646DB83AA93BFB2A84EA8A836EF67B0F3658E9769B60E43005DCEB45E3BF075EA1
+
+In1 = -0x35FE95A43E5D5FAF40675669A29DB87336DC363D446E2C6FA1F1F146D2C3C948B26EECF0CC4CA81CABFE7E468436C9CB0300085F562CBF0016B066E97C103
+In2 = -0x3E8F1F274373D75817D5D67E5215302D10481D7F963236B658EF0D326B2D7C99B493C9000F9068277E369DC05BC5F56C060AD3B
+Output = -0x35FE95A43E5D5FAF406756A831BCDFB6AAB38E551A44AAC1B7221E571AE148DEE4A5A349BB59DA87D97B17FB17FFC9DA93682FDD8CCA7F5BDCA5D2EF86E3E
+
+In1 = -0x6379E5426D1A80CF647E5E018A469A7B4391A68F376
+In2 = -0x529E84159D037B2DF823E397F68AE81F
+Output = -0x6379E5426D1FAAB7A5D82E393D261CB97D110F3DB95
+
+In1 = -0x6B313343CF9C60799B6F67CF1901E282FF1879CA9158EC397D95565236F6A1EA2FD52DE77996511CF5C0DC16C2CEA1B9DF1B747
+In2 = -0x47C68A1FA0E084C4CF6F62726D35D0E44E36751E1282E07E2E4B19CCBCD193C4981FE3B87FE77DCE5760
+Output = -0x6B313343CF9C60799B73E437BAFBF08B4B6570C0B87FBF968BDA39B988D7CA1837B8129916621E36320A5E14FE56A031BC00EA7
+
+In1 = 0xBE7
+In2 = -0x1B2B372D015EC298BE2E53F61AAB688A8048DBE4218D04D367AFE5B989943E14C76549C8BC04618A3ABD684568D8D7E129A3DD3B38E
+Output = -0x1B2B372D015EC298BE2E53F61AAB688A8048DBE4218D04D367AFE5B989943E14C76549C8BC04618A3ABD684568D8D7E129A3DD3A7A7
+
+In1 = -0xC4F9D29310EA767AA8DD0AF418447DD3DC2C220C48591F99B6DBF0521F7A5640
+In2 = 0xC4F9D29310EA767AA8DD0AF418447DD3DC2C220C48591F99B6DBF0521F7A5640
+Output = 0x0
+
+In1 = -0xC4F9D29310EA767AA8DD0AF418447DD3DC2C220C48591F99B6DBF0521F7A5640
+In2 = -0xC4F9D29310EA767AA8DD0AF418447DD3DC2C220C48591F99B6DBF0521F7A5640
+Output = -0x189F3A52621D4ECF551BA15E83088FBA7B858441890B23F336DB7E0A43EF4AC80
+
+In1 = 0x17FB5C14378626E94EC16B21FB8CCC92F76FB2F2B50B97B4638A9077C2246D721FB9964F37BD2896868BB07A00851CF7F4D7E2A1EB82564F0CEEA
+In2 = -0xED7032C591ADDE75225BC72B43AFE64B506E9C9FED691F97
+Output = 0x17FB5C14378626E94EC16B21FB8CCC92F76FB2F2B50B97B4638A9077C2246D721FB987783490CF7BA8A45E54441268BCF6732D9B01B857787AF53
+
+In1 = -0x4640AA0277F7114A67A2094094D2DD4FE579BAE27177FC081D6C960F3AABC0406C6C42636454AE4BF6378B0C89E95B6FE21752
+In2 = -0x28ECEDB2C3BF2BAF41E7CB48A68776ECCCB1D9842D3A3CD5D8D2ACDEFC09FC3CEEEA07AA993361FB1B2D3BC1BCAAA6716C700591BA4A678B150C52211E5E5
+Output = -0x28ECEDB2C3BF2BAF41E7CB4D0A9217144C22EE2AA75AD0DF260081DD53A5AA640669C82C6FFCC2EEC5E93FC8836ECCA7B1BAEA511DC31853B3A2091F3FD37
+
+In1 = 0x5F2FED076FEF762B
+In2 = -0x211E0872E976CCD667969DC26A4FDE294E64EB5C062E88A5DC762CCBE5227766417F58AA752681DCBC9F1FA6EEFDCFBCE23B
+Output = -0x211E0872E976CCD667969DC26A4FDE294E64EB5C062E88A5DC762CCBE5227766417F58AA752681DCBC9EC07701F65FCD6C10
+
+In1 = -0x2B393039B13A32B6F67B9B2F1A1088347D0DC1A07A4559C746CEB81658C6566300861CB140CEE7374A83
+In2 = -0x65E413EE9891FB5BB176200C3F66DA777CB23ED295BED8B2EF1981D8D04BDB3630EF254901A0A4B297443E562A98CDA74B8CF9E1CA5314BAEB95
+Output = -0x65E413EE9891FB5BB176200C3F66DA77A7EB6F0C46F90B69E5951D07EA5C636AADFCE6E97BE5FE79DE12F66C835F240A4C1316930B21FBF23618
+
+[Subtraction]
+In1 = 0x0
+In2 = 0x0
+Output = 0x0
+
+In1 = 0x0
+In2 = 0x1
+Output = -0x1
+
+In1 = 0x1
+In2 = -0x1
+Output = 0x2
+
+In1 = 0x64
+In2 = -0x64
+Output = 0xC8
+
+In1 = 0x0
+In2 = -0x1
+Output = 0x1
+
+In1 = 0x0
+In2 = 0x100000000
+Output = -0x100000000
+
+In1 = 0x100000000
+In2 = -0x100000000
+Output = 0x200000000
+
+In1 = 0xFFFFFFFF
+In2 = -0xFFFFFFFF
+Output = 0x1FFFFFFFE
+
+In1 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+In2 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+Output = 0x0
+
+In1 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+In2 = -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+Output = 0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+
+In1 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+In2 = -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+Output = 0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+
+In1 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+In2 = 0x1
+Output = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+
+In1 = 0xC4F9D29310EA767AA8DD0AF418447DD3DC2C220C48591F99B6DBF0521F7A5640
+In2 = 0x6D72F5441CA9DBAFCBF4DB9701D6C667C1D5376251DE09468E3EFBF1FB04CD95
+Output = 0x5786DD4EF4409ACADCE82F5D166DB76C1A56EAA9F67B1653289CF460247588AB
+
+In1 = 0x91AF1AE9122BA385DEAE3F9B478C8270A2D2221396FB3639B44E06E3A1AE9817
+In2 = 0x8966B342D42332D2155FE03FEF2D3F84B415D1FDA1168A5C63D0F9B86B77CCE
+Output = 0x8918AFB4E4E97058BD5841974899AE785790C4F3BCE9CD93EE10F7481AF71B49
+
+In1 = 0x7720BC7E5A52D5A9083EE9AB0E3B6FA60EB34585FEF514A813E821345D39AE747A6AFACCB5C865D60757711D82F8BB81B3F127B30E245B1A0C744651CDF
+In2 = 0x363867D8F525A952FBA8AA74B63D6D61D7117AE6CC611B27832F93C97161C65F8226388F4BD9D2478284B438CA11A2914B057
+Output = 0x7720BC7E5A52D5A9083EE974D5D396B0E909F28A564A9FF1D67ABF5D4BBEC7A8194FD34986349C64A591119B5CC02C35DA1EE0308970224FFAD1B506C88
+
+In1 = 0x1B821B0F516E447A95442D3F2FE5CAC83B6A7AA
+In2 = 0x19B9B7821A31A6E588C47B8D7D9CBDF3B2A2BADBF6FCAFE97B0C160042BD2AAC7762AE119355761C1AF1
+Output = -0x19B9B7821A31A6E588C47B8D7D9CBDF3B2A2BADBF6FCAE31595B20E95E758158348EBB1336A8F2657347
+
+In1 = -0x7730253C6B1A76063F070D25DFB7F1E69FCF5283F983DB9B585FEDE87B78B7B2C8DCE72BFF55323E6C375C43FF4E2A8F25950B1F18E6B2714EA061BA212964E
+In2 = 0x3E441DEDA948142D7F60717EC693F5FC29011349E7C
+Output = -0x7730253C6B1A76063F070D25DFB7F1E69FCF5283F983DB9B585FEDE87B78B7B2C8DCE72BFF55323E6C379A881D3BD3D739C28A7F8A657905449C8ABB34734CA
+
+In1 = 0x195277431B3AAFA0C3F
+In2 = -0xF951B313DDB8244D5079AE4D47F6CECB812E4982AAC597D23AC806E5
+Output = 0xF951B313DDB8244D5079AE4D47F6CECB812E4B17D239C985E5C21324
+
+In1 = 0xCC42E47D0B6CE51C676F0A3BB5877E0B2884A51E1E58F1D1849E0ED13695CDFAD0A28FD40F64F076DBFABA918A28ACB2B541D8C3AACA9D1
+In2 = 0x360BC009F31DE8A1A6901FE6076EEDF42F999EC63CA892E6FCAF73B6DC9D89D2A84ADB1CE6443D8D555C745C4AE151F87CEFC03898539F158313CC
+Output = -0x360BBFFD2EEFA0D0EFC1CE1F907E4A38D721BE13B45E41051720569E92BC9CBF3EEDFB6FDC1B404C5F0D6CEE8B35A8DFDA64F50D443612DAD669FB
+
+In1 = 0x50879BE5916651A9D7E6640E3A818E2177014B72CF77
+In2 = -0x37E8530CD80B0C64B814E66E65FCD380AA59F6E3359EF417BE6C2465992BEE7
+Output = 0x37E8530CD80B0C64B819EEE82455E9E5C4F7754976829C30A083947A5058E5E
+
+In1 = -0x378C40B5FBC9F973CBD794D2752F4DD
+In2 = 0xDE34CB783A1057CF55DD139E899392992FDB371BA5409F691
+Output = -0xDE34CB783A1057CF56149FDF3F8F5C92A3A70EB077B5CEB6E
+
+In1 = -0x3947B0
+In2 = -0x7B5ED9D74939C00A693972A3BDD623044A05AD3B6
+Output = 0x7B5ED9D74939C00A693972A3BDD623044A0218C06
+
+In1 = 0x3D98651545ECAE4E240F938476B9D4709A140179AA4AF93CD76F0A66B4E52CA28D81CFCB6666199265B516DC7EE3550
+In2 = -0x1F467AB19963FE68CB00D77FEDE42A738DD24EE4485096B605AD8A7
+Output = 0x3D98651545ECAE4E240F938476B9D4709A140179C99173EE70D308CF7FE604227B65FA3EF4386876AE05AD928490DF7
+
+In1 = -0x6DD6EE5139C34D3E56714C43
+In2 = 0x5FF068173D0DE8F8C68D0226167586F4284B075622F627DABA741A11E566D385D6BC1C15C9840E91129037A8
+Output = -0x5FF068173D0DE8F8C68D0226167586F4284B075622F627DABA741A11E566D38644930A6703475BCF690183EB
+
+In1 = 0x1263BCBF9EC5099241CFE7B0FDFBCA97DDA555C2BF
+In2 = -0x2F665AEBC1F2114C74E772B8AB6C9CF40DB1210C4C28D400E251EB37B6073E5D658149378B42840831FEB0ED5B5DE
+Output = 0x2F665AEBC1F2114C74E772B8AB6C9CF40DB1210C4C28D400E253117382012AADFEA56636065263C4DB7C8B42B789D
+
+In1 = 0x1379687600BC3FAB4A66824C26306E2BB0A296AF1DABD12E5951F61E2E853C920EAD081F594FB2A3BE34F7D4755DF83DE89ED5164
+In2 = 0x763C9C1832B246CFEED0CE9BF0D5FD30A8A8FED598CB52E6D390DF6A65EDAD2
+Output = 0x1379687600BC3FAB4A66824C26306E2BB0A296AF1D359492411F43D75E966BC372BC322228A709A4E89C2C818E8A675E7E38E7692
+
+In1 = 0xBB140C866A8B5923D037C4CBDC9738CD58DF1FF00942E419F6BDF510AC96EC67AA79
+In2 = 0x315844738557F7DA0DB1558A96EB8485FC18AC45A0102CF90AE667D16117604A5FACA5E
+Output = -0x314C9332BCF14F247B74520E4A2DBB126F431E53A10F98CAC946FBF2100C96DB9931FE5
+
+In1 = 0xD723BA742F0E47FEC
+In2 = 0xDA6D7DA1
+Output = 0xD723BA7421677024B
+
+In1 = 0x3443AABAFA42542770B
+In2 = -0x246EA87A1D42B3B08BB7516BBF9AE5D269EBD94093F0054D9D34F14276694D1A58759475374827427F78AEBE139492FB00
+Output = 0x246EA87A1D42B3B08BB7516BBF9AE5D269EBD94093F0054D9D34F14276694D1A5875947537482745C3B35A6DB7B9D5720B
+
+In1 = 0x1E329598DC8E2B0ABAB6291BC7C1103CACF4A0B20B8A101905EC0BB5E
+In2 = 0xB12FBBFBA56
+Output = 0x1E329598DC8E2B0ABAB6291BC7C1103CACF4A0B20B8A0F67D63010108
+
+In1 = -0x30BD94A10E4B9ABEDE8DBA276B495C170E9ACAA5290582EF9F08AD7D67202B775DBF196B8AB32AE842E48F2DADECC3BC878EE13113E3A0B3EC
+In2 = -0x2E31D36EDB4BCB1CE3B7261861105A479F07740C4A31945993456C77
+Output = -0x30BD94A10E4B9ABEDE8DBA276B495C170E9ACAA5290582EF9F08AD7D66F1F9A3EEE3CDA06DCF73C22A837ED3664DBC487B44AF9CBA505B4775
+
+In1 = -0xAB37F3BF5CBE52F52C1008E4C4FC0E1818580A910C486D4CA7B659BC0FCA913A0206F95EC44D5570
+In2 = -0x3DDC55
+Output = -0xAB37F3BF5CBE52F52C1008E4C4FC0E1818580A910C486D4CA7B659BC0FCA913A0206F95EC40F791B
+
+In1 = -0x310E3
+In2 = -0xD9CC840605B9D18EE2536D8E28DADC94219ECC18AFCE94034614FCC73D8CAB16D8B01DDE6A6EECCCC25BDBEA36B8FE57574B6F081A838AE09807A85593D46C
+Output = 0xD9CC840605B9D18EE2536D8E28DADC94219ECC18AFCE94034614FCC73D8CAB16D8B01DDE6A6EECCCC25BDBEA36B8FE57574B6F081A838AE09807A85590C389
+
+In1 = 0x16623E0D6BB8429DC7AB
+In2 = 0x473131A802E3B451D0E151729E0C21EAD0DF5F19EEC54DD79C0163BDD5DE716D0FAB0D0A9EB96C67AAB5EA30C2141B9AD37AB4DA37FAA9CBFC0
+Output = -0x473131A802E3B451D0E151729E0C21EAD0DF5F19EEC54DD79C0163BDD5DE716D0FAB0D0A9EB96C67AAB5EA30C2141B996D56D4037C767FEF815
+
+In1 = 0x3DF6E94FAD38D8E3AEE058315BFDA4AF03F7D09BBFD
+In2 = 0xC6524E617604BC6DD7426CB88219F162F5A84B3DD1974B9
+Output = -0xC652106A8CB50F34FE5EBDD829E8956550F9474600FB8BC
+
+In1 = -0xB6FDDB59ABC6A5BF6FD8C3949897F1E8
+In2 = 0x1DFA9658309AA530153A27319B4D7A52CA562BF51ED1B50D2AF9A1C211142CDE8E4237BFDC5CEF71169622B1639D832F73AFA411
+Output = -0x1DFA9658309AA530153A27319B4D7A52CA562BF51ED1B50D2AF9A1C211142CDE8E4237C0935ACACAC25CC870D37646C40C4795F9
+
+In1 = 0x3B615FC54652B5E9129DE9CD2
+In2 = 0x260288F4854CDC72E1ADD425EC91A9B95F0757161CD36A017FC813A828AF7BAEB1
+Output = -0x260288F4854CDC72E1ADD425EC91A9B95F075716191D54052B62E84997859D11DF
+
+In1 = 0x10EEA3D6D71A528F780B6ECA281D08B96F7642CACFB0A15D86BA14DDF32
+In2 = 0x16F94151B72EC25D563A5D8C27018D
+Output = 0x10EEA3D6D71A528F780B6ECA281D0749DB612757E38ACBF9E0E1526DDA5
+
+In1 = 0x47C7BAF7BF826F2C8A5AE2DC2CB9966518C57DD8EC31C39DEA5D3329D7BE41677DF4572D86B
+In2 = 0xD211114CE5460E73AB175
+Output = 0x47C7BAF7BF826F2C8A5AE2DC2CB9966518C57DD8EC31C39DEA5D3257C6ACF48237E5E3826F6
+
+In1 = 0x84129AB18924955D4C37E7B86862E992AFCECD208747259F34A87E2A0A47190F59B440
+In2 = 0x62D8D5C0A48DA85EF50BC708BA96555A1E9C803D50A8BB7AB38293C2DC48033FA1580046E5A8245B33EB63EE02B8C8
+Output = -0x62D8D5C0A48DA85EF50BC7083683BAA89577EAE00470D3C24B1FAA302C79361F1A10DAA7B0FFA63129A44ADEA90488
+
+In1 = 0xAC39D955EAC8A0F9AFE661DA0324F3D2FF36D81F042179BF4153F14D29E2AECE1470240F40D
+In2 = 0xCF0F0C36
+Output = 0xAC39D955EAC8A0F9AFE661DA0324F3D2FF36D81F042179BF4153F14D29E2AECE1463331E7D7
+
+In1 = 0x76A19793E9390241
+In2 = 0x45B7CA117BC3099801DD020928073D08C53EF9E303CCFE75DE7FA4721FC08B4D78456
+Output = -0x45B7CA117BC3099801DD020928073D08C53EF9E303CCFE75DE7F9D0806474CB9E8215
+
+In1 = -0x6B34647A3A898E65D20332C6426CCD6B66EA9C87326092E4EAC09B03BE69CD69B629DBE0B36A5E85758943B7E6212B4D0BBFCC3610771AF
+In2 = 0x7F9DF6EE1FB45FC5F63BBE99961D270B968ABB74A3DEB9A78E95EDA704F0AA3C9EA912B66572845BA633054C48245FDEA703535AEA0CF270AAD81F97D
+Output = -0x7F9DF6EE201F942A70764827FBEF2A3E5CCD28420F45A44415C84E39E9DB6AD7A2677C83CF28AE3786E66FAACD99E9225EE974863718B23CE0E896B2C
+
+In1 = -0x34ADE05D484ACF1FA10799988AC0027C308722E147400DCBDEE53B11865AB76AF0AFA040EA7760AB7EF
+In2 = -0x13C09CA26760AAD90E3ECD0E9B8B7DEE3E95D3698B0373868682AEFC0CE5ECAEA609510FE97B68F7BAB686D5428344
+Output = 0x13C09CA2675D5FFB086A4861A9916D74A50D276963406B14586E3AFB3027FE5AF4F0EB6472CC5DFDB6A7DF5F37CB55
+
+In1 = -0x19E698A7522219757
+In2 = 0x19B3A167C1C066B11A01BB3929CFF936DED7E27D4EAAE4ED94EEE2B68FF90E68AD2FCFEFEF36A18AB75D43E02D3D178C167A0AE325EE
+Output = -0x19B3A167C1C066B11A01BB3929CFF936DED7E27D4EAAE4ED94EEE2B68FF90E68AD2FCFEFEF36A18AB75D43E02D3EB5F5A0EF2D04BD45
+
+In1 = 0x3577FD69874BF7BD48718C5CB8DE663D2213D45C810E86A9411D382A31A171A7116F00A8A3005DF371DA5032A0DE5FD2E2343F6B2
+In2 = -0x6BE1C6BDB549E0CFE07A42F66BCB
+Output = 0x3577FD69874BF7BD48718C5CB8DE663D2213D45C810E86A9411D382A31A171A7116F00A8A30064B18E462B873EEB5DDA8663A627D
+
+In1 = -0xD9844A898712B18FC3F0551B5EF89CA13AC4376BB560DC85B3F2
+In2 = -0x1836EDAA6C75FF0D0E682
+Output = -0xD9844A898712B18FC3F0551B5EF89C9FB7555CC4EE00EBB4CD70
+
+In1 = -0x1
+In2 = -0x5D5B041CAB471FD3
+Output = 0x5D5B041CAB471FD2
+
+In1 = -0xE1E7680699E0061716952373432335BAD42A7DB4739D6D90285D4AE59FE8E989C0598
+In2 = 0x26A399E79403
+Output = -0xE1E7680699E0061716952373432335BAD42A7DB4739D6D90285D4AE5A25323283999B
+
+In1 = -0xB61166437A1082A37C28F1B6F969D161957A34C091174739CFFD5351E654B41D661BDF60AB
+In2 = -0x304A78BF5DD055F2F6674291BB5BBB1FC74817B4752629B080002A2DFE1CDC26575CE5BD2D33A02BA2F2C55646707615B
+Output = 0x304A78BF5DD055F2F66742865A4556E8263FED7CB2970E40E9631414A679901D45E872202D5E6B0D3DA7837FE4B2800B0
+
+In1 = -0x7468BD0C34E52F0347B54587937752BC54E31E4135E5138B0F53B2184C0E1101F54F0EA9B4BCACFCF1F18485E9D6C2BD3AE0FE70C691FB55E42E6D
+In2 = -0x1BCFE32324EBFDC03FB8900EDFB857465DB
+Output = -0x7468BD0C34E52F0347B54587937752BC54E31E4135E5138B0F53B2184C0E1101F54F0EA9B4BCACFCF1EFC787B7A473FD5EDD02E7C5A3FFD06FC892
+
+In1 = -0xF6BE2059893585C4ED40ACDBA6BE7CAB5
+In2 = -0x2E326CF70C16FA855D06924096AD488190CC
+Output = 0x2E230115067E672D00B7BE35C8F2DC99C617
+
+In1 = 0x1763F6F487F598E9F1D19DF90099954E587919841D8EB229E26538780
+In2 = -0xBAE1B8B021A878208107BF9EA020AEA939828FC193A703EB93258B39F8
+Output = 0xBC57F81F6A27D1AF2024D97E302A47FE1F0A2159D57FEF0E314BDEC178
+
+In1 = -0x54AE8AF71D0C1AADFD028DB3BDA070FA20F927E4FE20D09DAB7F6D9BE0B05474DE5E6CFC6A06AAE708B71CC6D78C41F886695D05
+In2 = -0x892F22B52E8F518E4025041F84EF9B6EF6C5D67E7EF2C4567F07CE85EF2D0AF85C2CAE0ABB80987B259C1A298DB698047C6F027AE1C7D1E0CE20E5BE4DEF
+Output = 0x892F22B52E8F518E4024AF70F9F87E62DC17D97BF13F06B60E0DAD8CC7480CD78B8F028B4DE4B7CAD1273BCB20BA2DFDD187F9C3C500FA548C285F54F0EA
+
+In1 = -0x13F2AFF42BDA18DF82B8E23A09BA3F4E8B8EC6F081AF379D22623576D749174C3CC641E6
+In2 = 0x1159C6A3912A5E1AE41DE8EF2BAFE0ACDE194A80FAFE7653488D9F84D460EA7639319A4A5BF86540164E31
+Output = -0x1159C6A3912A5E2ED6CDDD1B05C8C02F96FB848AB53DC4DED7549006839887989B671121A50FB17CDC9017
+
+In1 = -0x232575C46B02F59F8C2F9D1AD8
+In2 = -0x1F9FE8B4C1DA5E8B2AA8719E36DE92
+Output = 0x1F9FC58F4C15F3883508E56E99C3BA
+
+In1 = 0x1E87AC7EE4C2DB126AA81EBE15139E9225085AAF1940DCA3C4CEC04
+In2 = -0x7ECDA4AEB61FF5A6EA23D7914DD97D2F2B36994D869E7778B2
+Output = 0x1E87B46BBF0DC6746A028D60528CB36FBCDB4D6282D5B50DAC464B6
+
+In1 = 0x32A836FD13
+In2 = 0xD4B270491655376BFF41DCF05D1D1EF90C11677EF89DAD8B3058B5DBB09EF8155170566FB58DCBBCC7A8BD14C
+Output = -0xD4B270491655376BFF41DCF05D1D1EF90C11677EF89DAD8B3058B5DBB09EF8155170566FB58DCBB99D254D439
+
+In1 = 0x6DCE620B44F2DFD1FF3CC99A249967448
+In2 = -0x44AB2F
+Output = 0x6DCE620B44F2DFD1FF3CC99A249DB1F77
+
+In1 = -0xD480356FB22C5BF78E98DAB436B1E57B8368EF76191FE6C6FAFA819FCC833AA1236
+In2 = -0x38DD7464DD0AFDA7CF3C61ACA7F5059F6B1EAF69E5AA647F3A41027CEA1DDCF303595FC06465803B91F1D841EED5D161FC78C3DA2B2
+Output = 0x38DD7464DD0AFDA7CF3C61ACA7F5059F6B1EAF69112A2F0F8814A6855B85023ECCA77A44E0FC90C578D1F17AF3DB4FC22FF5893907C
+
+In1 = 0x6399F2B8BBB7E537F
+In2 = 0x53F47E2EECB8AC51E84174C0384E03B061B12F90F13EDEAADD8A36990989981C7E184AEBD077BCB93832F97000FC2161
+Output = -0x53F47E2EECB8AC51E84174C0384E03B061B12F90F13EDEAADD8A36990989981C7E184AEBD077BCB2FE93CDE4457DCDE2
+
+In1 = 0x24921974D2806EEA74A787B21C065201A4A45BCA62F8160E7E40D62E76572DD2F94F47C3C7AEAE34563DF66A345063D8F4BF9B67A7B1763
+In2 = 0x72445470A38A5B8CC9AB488959F6DDA83CCC02712C7652213DED88E5B6F71BA1436039D6E2856BAC20B44D72A31B2AD
+Output = 0x24921974D2806EEA02633341787BF674DAF91341090138664174D3BD49E0DBB1BB61BEDE10B7929312DDBC9351CAF82CD40B4DF504964B6
+
+In1 = 0x450746A7BD2CE46E185EE4AC4D139CB9382C4432033D62364AE7B7CDE753E5746B342C1061108679677B1DBC8EB275DED
+In2 = -0xEB200F
+Output = 0x450746A7BD2CE46E185EE4AC4D139CB9382C4432033D62364AE7B7CDE753E5746B342C1061108679677B1DBC8EC127DFC
+
+[Multiplication]
+In1 = 0x0
+In2 = 0x0
+Output = 0x0
+
+In1 = 0x0
+In2 = 0x1
+Output = 0x0
+
+In1 = 0x1
+In2 = 0x0
+Output = 0x0
+
+In1 = 0x1
+In2 = -0x1
+Output = -0x1
+
+In1 = -0x1
+In2 = 0x1
+Output = -0x1
+
+In1 = -0x1
+In2 = -0x1
+Output = 0x1
+
+In1 = 0x0
+In2 = 0x5
+Output = 0x0
+
+In1 = 0x5
+In2 = 0x0
+Output = 0x0
+
+In1 = -0x5
+In2 = 0x0
+Output = 0x0
+
+In1 = 0x0
+In2 = -0x5
+Output = 0x0
+
+In1 = 0x100000000
+In2 = 0xFFFFFFFF
+Output = 0xFFFFFFFF00000000
+
+In1 = 0xF30CC0
+In2 = 0x3BF036B268242F2C0F8D3169A1D0A7D6EB
+Output = 0x38E80022123D08942C34CC2F7A9BDE755D053440
+
+In1 = -0xF30CC0
+In2 = 0x3BF036B268242F2C0F8D3169A1D0A7D6EB
+Output = -0x38E80022123D08942C34CC2F7A9BDE755D053440
+
+In1 = 0xF30CC0
+In2 = -0x3BF036B268242F2C0F8D3169A1D0A7D6EB
+Output = -0x38E80022123D08942C34CC2F7A9BDE755D053440
+
+In1 = -0xF30CC0
+In2 = -0x3BF036B268242F2C0F8D3169A1D0A7D6EB
+Output = 0x38E80022123D08942C34CC2F7A9BDE755D053440
+
+In1 = 0x3BF036B268242F2C0F8D3169A1D0A7D6EB
+In2 = 0xF30CC0
+Output = 0x38E80022123D08942C34CC2F7A9BDE755D053440
+
+In1 = -0x3BF036B268242F2C0F8D3169A1D0A7D6EB
+In2 = 0xF30CC0
+Output = -0x38E80022123D08942C34CC2F7A9BDE755D053440
+
+In1 = 0x3BF036B268242F2C0F8D3169A1D0A7D6EB
+In2 = -0xF30CC0
+Output = -0x38E80022123D08942C34CC2F7A9BDE755D053440
+
+In1 = -0x3BF036B268242F2C0F8D3169A1D0A7D6EB
+In2 = -0xF30CC0
+Output = 0x38E80022123D08942C34CC2F7A9BDE755D053440
+
+In1 = 0xFFFFFFFFFFFFFFFEFFFFFFFFFFF6F67B
+In2 = 0xFFFFFFFFFFFFFFFFFFFEFFFFFFFFFF04
+Output = 0xFFFFFFFFFFFFFFFEFFFEFFFFFFF6F57F00010000000001050985000008E55EEC
+
+In1 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+In2 = 0x80000000000000000000000000000000
+Output = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80000000000000000000000000000000
+
+In1 = 0x80000000000000000000000000090985
+In2 = 0xBFFFFFFFFFFFFFFFFFFFFFFFFFDDE48C
+Output = 0x5FFFFFFFFFFFFFFFFFFFFFFFFFF5B969BFFFFFFFFFFFFFFFFFFFFECBC43CA8BC
+
+In1 = 0xDFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFF
+In2 = 0x7FFFFFFFFFFEFFFFFFFFFFFFFFFDEFAD
+Output = 0x6FFFFFFFFFFF1FFFFFFFFFFFFFFE29B6E0000000100100000000000021074053
+
+In1 = 0xAFC1CFFD57BE9A5D50136FC20CC5D26
+In2 = 0x12412589AF125C363D32631463F51F45
+Output = 0xC885A9B2978B29FF512F3A3454B090ECAFDBC51971956C865FBE806DBAB53E
+
+In1 = 0x6DD921FE56D7207A520C25D947FBA37C
+In2 = 0xB68B7760D6B79A1E63F7DECBE79338B2
+Output = 0x4E543649C3325C67BBB672BC7114F89C74B1D8FDF05E5E647D666A2ADCEECC38
+
+In1 = 0xAFC1CFFD57BE9A5D50136FC20CC5D26
+In2 = 0xB68B7760D6B79A1E63F7DECBE79338B2
+Output = 0x7D538A0F9EB6FA3F92BD8460B4EE5A93EDE95B2FE6FD63D3FBD7104494B146C
+
+In1 = 0x6DD921FE56D7207A520C25D947FBA37C
+In2 = 0x12412589AF125C363D32631463F51F45
+Output = 0x7D538A0F9EB6FA3F92BD8460B4EE5A93EDE95B2FE6FD63D3FBD7104494B146C
+
+In1 = 0x653B2B2729F34B5D59C090A1138282BC0D79FD80A0D5296723B14D0DFB3B4A742A758E0FF7303A51
+In2 = 0x76564ECAE696BA53812142B305057827F3FB001AAA52CF41629A1A477694E9F6EB1C1E546074A3EE
+Output = 0x2ECB66ECCF82FB460EE7668D10C25C722EBC1CA1EE83330C82E86E20BF7A0CB5BF0E1D5C81805D8942864680171DFDF285AD7369A09F35B9FF1729E7EC1724DC38C2CAA7FF370F6C2D30F58850ABCA4E
+
+In1 = 0x21A9269D7B8B63CF18FAA933B3C868BA1E8CB3F00B57E197709ABF96EEB9BF12E8FE22B3
+In2 = 0x144C992B68E3CA712678215D5BC968702CCFEA17717737BA501A38D26FA5091BA
+Output = 0x2AB495F91AFD7C36F85ECE6FD58577F995DE88D62A98A07C6D9E3500AE67B0F100BC709D1F30894662774D0CADFBA091788C427CC6F4BACB26E42CF92F6E4494E03C990E
+
+In1 = 0x416E63549E2CF08FB225058B3545CB4A47CBF9
+In2 = 0xDE38C473C27F7BDEF02A084192B3E17F435CF7
+Output = 0x38CC3C7F360737411DF7B52A222A3672C6E0D39F0A868479176A6143E1129D44D5AA61BE493F
+
+In1 = 0xAA20B1355073F21C57530D2F90BC40E47AC463
+In2 = 0x8315DFA60E97FF3DAB7A6F61FCEC2CD5B6F127
+Output = 0x571D43FDA6CE14A78534AC72C50B58738D62630766A59A7CEC1A63433E499B1B5EAC5EF71E15
+
+In1 = 0xF641594177C8C364D922C659A8F7AE0460C7D74B266C8CC258AD5F
+In2 = 0x5948DD29FC5172C37C31DA6957779A1BEBE452D8DEBA26C5D3D390
+Output = 0x55E2CF27AA49F938584DCA4044D944077E226206C6F8C7688E8760F3B5C106413FD0EF4B63A97991DA86FD113FF4822A41F76913D270
+
+In1 = 0x3FEF06998B0DDD140E01527426EA409B2B9E640F223DFD652229FD17EB99D44F6BE6D4935505DF676F48C8FCBFE2D5096345D6509267AA40C54D427F0CCE45CD0F8FA7E4A22492D7ED4FFA45E3C0E5E3C25C841943FB2CECD6EE9275AE93C4E15E2D9F8F317C44C541ED52A6338B0FB9F7F7F4DEA78CF7EF5201837C00A6D4D2
+In2 = 0x260ACC6378341B2B894DACAB3A44B914F19292BB32898B155584A406161BB04AD9C14DB20888DFCDAB613B368B5C699305C4E9B226D90F9523FBCB6293407BD2BB18BF7BDBA8539FB577F19B72124C2D83A2BC31F44366E917DDC705085B79FE9E0DF0E98E4F6AE3DF63D9B321382C18B95DE1DC4D1DB93B3092C9C6F8C9764
+Output = 0x9802D5C5D5A73F9D4E694A8920F951CE4BFE80C13A35CD5332A556136B83495A2E9B4D2ED53AAE1218D2E1C41349311F86B1EE1F2AD5CD3C5B264E8E68906CA45BD7D0FC8E8A5A9648F458CECBA41FD0848A04F506BB11DDB378F3214085CF865BA5533CFD73B28B1E12784F447B156F59A3B68E6EC68303DDFCE59CE33CA386FF3316E6A5E6F9B4201682AA9E59A6D7CB9315A492457640ACCA19FC7DC3A25A316FEA9A0F1D32838B7F911650647F996551263C2D001FA1C720753AFCA316C7137300FF93F2DDD2846CE14C55D0EAD626F681BD11707F9674905396A9BC9A889EAE721AB6407586880A95575A968B43BDF50323627AA0FCDDFA4E198B0008
+
+In1 = 0x3BA5A9C550B8CF6C3B87CC106B6551221A0DC90AC193EBCC526E4E5F53CF012FA6E05B155DCB3C4C0E1A90A01062A67EC434F6744195349194770711EA836A8B
+In2 = 0x54F04F121D22DB842523E9BF75727D5B0E9EF17E6D727918894927FADE87CEEB2106684C4AF7C49653425E29F7A91ABF8ADEC4DE2CA499DF2534644397E454AC
+Output = 0x13CA59703F4C087C16A9A7BC7022904A37A469C1D0FD9FA7FFABE8F7D887FE1572C0BF5C75FDE6913B565F8106BBA9C26C9BBCE190A9B8967112D74C0AC3D4FF9D2A385B96833E3C456D5601C74D8D2C9FFF35ABC60E7CC15D7C680F20757C13A415F1B8FBE3C6C32434AA36C528473DD20EA39F0E5EE22D1CD23040900D3164
+
+In1 = 0x570B19E
+In2 = 0x3B18009209FD4C028455CDB9900AD2529B45BCB63AE44C31F00C5EDD7D907C
+Output = 0x1417B832B4BA4579992399BA1317FF6034537892B64B08E811ED10E89947226A4E888
+
+In1 = -0x570B19E
+In2 = 0x3B18009209FD4C028455CDB9900AD2529B45BCB63AE44C31F00C5EDD7D907C
+Output = -0x1417B832B4BA4579992399BA1317FF6034537892B64B08E811ED10E89947226A4E888
+
+In1 = 0x570B19E
+In2 = -0x3B18009209FD4C028455CDB9900AD2529B45BCB63AE44C31F00C5EDD7D907C
+Output = -0x1417B832B4BA4579992399BA1317FF6034537892B64B08E811ED10E89947226A4E888
+
+In1 = -0x570B19E
+In2 = -0x3B18009209FD4C028455CDB9900AD2529B45BCB63AE44C31F00C5EDD7D907C
+Output = 0x1417B832B4BA4579992399BA1317FF6034537892B64B08E811ED10E89947226A4E888
+
+In1 = -0x5E0B6C8E3F8C928EF1FDCDEB13EB08C542B3B4E788E601
+In2 = 0x2F3EF3255D06D3C6E78287D37B48F46270E1492A07F1A6641CE9B29D682A996F59A48CBEAB50859AD30566464
+Output = -0x115B3904F9FC9256104218397F0BD0B7BF07EC01127192F7C2C04ED5CA3057FE54F3137A36C198569DF622B8635F7D74CE943C248EA6273B53B67245AF217E65FA83C64
+
+In1 = 0x198A05D8
+In2 = 0x3CAD0058399C667A82D3586EC9C750E2546834163F0B28CC0AF256AB9A9C204741488F8ADCE6057FC155D69325377D6997A187C6B4A
+Output = 0x60D9BAD602957E1DEC8057D007A03C2D90057DF811675005445F97972C5121FDC25E78770745E0350EFBCCBD792670A66FF6463B0B26F6F870
+
+In1 = 0xBB949E1DB00F1203ABA4C3B1EE66
+In2 = 0x860A675F181BFA0A3AE9A6BB40ED734BBCAE5F5BCC10E95E139603D7C771BD4F7BA42E933FA91D7A9344B553322A9EEE58FDCAA48DB483A1CA
+Output = 0x62376A5030BFD1951CD922EBD1D94CAA19C0880B328336AE1795F06C9D4ACD3F4CE0CDF3BF1374502A20BC126362DDA566C4BCC96D77850067847C3AAC53F7E4F6F4F00786427C
+
+In1 = -0x180CD72159F7E6E080B143BCA1ACC7ED3A5A9A5497
+In2 = 0xA5B3C58B5CDFCE1E8C299F51BBBCE92222F92D3F14FF49E976259F17DAD09A709C480BF93FC217CBFBAF1DA7640EC186F80EB62CF
+Output = -0xF912A31E48DCD59565CCC6E65FAC100630532D2083A605557C08CFDC9A31F0B881D84F43BEFCEAE95D356FBED4D327217CE37BC4C7E3F8CD614E3450C9BB7B00D4AC64544E7DC93419
+
+In1 = 0xDC92577DE968EDB102F4DD166C311997494FC1465A0E5A694CF202CE8002065E155EDBFEC64930C83F8D5E2BBFF6C2884604
+In2 = -0x6A013A88ADE1C0CAD9C0E347AA292D521
+Output = -0x5B55A73B6585C575839E8B3674C33E5FF003BED948F0C01D73CB58BC90325C951552896B26E92849BB95456895F2BC1B9E85DF2D7EBF73698FEEFD3936A98EC1A5A84
+
+In1 = -0x3E93C7EDAFD4D794E1768EF78246D45C542549735D1A36E5DF40CF4DD2359880D95866714D3E1E1
+In2 = -0x14AD163
+Output = 0x50DDAE91C405D5A93A8D79469F4A60F3C7F877AA189A6A2C46AFB4799FACCCA253573946DFAFF35630B03
+
+In1 = 0xC3FB959E5202F3A25F17720D277DFE4958D66EBD49615310962D35AC6206023DE1A7C44B9AC7EDF1E767FF0
+In2 = 0x3DE5504EBBB6FC15304F2DB66C636AC6697D0C431CC0AEBF8084B
+Output = 0x2F62802E7547FCB26E4DFDCEA44D11451801064AC97FFABD0CA6853E7F991581C865695EAA6D5DE148412C67EFEF3A0CBE892769737EBB6B0B070FE698215E20ADEEE136FB50
+
+In1 = -0x1375275109E077A7023
+In2 = -0x1C9D3
+Output = 0x22CC2CBF126CD99BC18E7D9
+
+In1 = -0x1DE4500770DF85A0F298B5EEDA3CAB2ACFCE9
+In2 = 0xEDF885B509B154AC71AE341854135E540B6BCC657B767059
+Output = -0x1BC962E12BD675B50803B8115C1C92F77198113A5FD25C1EB1FADB069E1796AE52731EBBA8CD1532FDD01
+
+In1 = 0x3FADA5
+In2 = -0x34C9610F66
+Output = -0xD215CFF2D10DABE
+
+In1 = -0x2
+In2 = -0x11ECB36DD9ED9A0F1128598E6CA26887FDAB5484777
+Output = 0x23D966DBB3DB341E2250B31CD944D10FFB56A908EEE
+
+In1 = -0x4DF26D6B19CF843C4B283EA7617A334BC70EA35847F274
+In2 = -0xFDB8F4AFA89BA798A89A0714B356197022412E4922A87C6D700A90485183BC50BB317F65CC277DF4410489755BA2E5FC639346863CC3732C4D05F39F0831
+Output = 0x4D40E6E209D6004539F24A588E12DE8BCA522DEC89C5A3A2AAC522A9ABD61E11DB830B463BB8A779EA42C3903713E8F25406A1BC246BF0306F52715F86C4EB7B663D3C865EA3E9CE05A7A2C9190313A81DD7650834
+
+In1 = 0xA98F2DE45A73CFACD98B520
+In2 = -0x115EF0155C49B0A71A275CC775901A7F77137E28AA9C1CF517E4A9E9600BF0E942F8EE9732AF4E4CCE931C444B16C3C23249FAD4DE0FC
+Output = -0xB8163A364C0032BFE022B7647BB4D5459B1922513EBF4ECB1CC59A2B333A2D901B9D3703B4537395FACCB422469EE6CA705D35CDBC459121BC5290C82FD1B6E4B80
+
+In1 = 0x1952E20297E1ADB1FE86050A9499491A9055DFCBB8718CB8699CFE2D8B4987D4AC61DF3C5B74FE4A0B0B4C9F949DA244E3821
+In2 = 0x1A40B85646D1262AABDA42A8A409C598CEFC68339D19E76792B142B600FA578ABA11E080E207AA0E61ECB60676FC1FC4798778182060FEB212C1E992
+Output = 0x298D1E8DF5E08567ACCA69A4DA68230E4CFFE1931A5F59C6A6B0651D1C48FB62FB5D2476CE454B110FBD6937167B60C4EDCF022AC5B4F926555A35ED0254C96F5236B7EAC96F6EBF1BD8398D201FC554B1EF74545B90DDCC11638CB4A8AFA25C548C93F808351EDA4D5088930BD2
+
+In1 = -0x23E6681D521DD9D3DDCAC61632A5ED3B0EB596B76F3EA608A34C5E81EB64E13F53414CB55F169124E95F2B1BF5206F0BD5FDB35D2C6155DFBDBC51A1293
+In2 = -0x6D08C7C1539CB43C2E82D222
+Output = 0xF4A558AF43E3D0D861BAA6B0DEFB03F44750549AE676281CBBFF68041DA0C4699A9E17DB68E69413C3D9264E7CA0D42F31F71A78F05738DCB84A42EAC2BF1B9CA5D3DA37E769590D86
+
+In1 = 0x9589A033A984D72C440D8C73113BDF3E9
+In2 = -0x3C27FBE1C134279947753CA728C444B27C6853F14780554514C06E4
+Output = -0x23239CA5527DA325621CE946896B62496ACC75D3A599C6B9227318952433DD9208B1249D38DD1A312B10B184
+
+In1 = 0x33279DFD6376351E72BE42F41CAC576E66E5F9100A181BA
+In2 = -0x75E2E69C35
+Output = -0x178E724316D3F61C14AB7334D675967B7E0017AD61FBB950A4D993382
+
+In1 = 0x2D6E0F41861E66848F282D643743FE24BA5B0392AB1C42A8EB0EECF16991B8B67F47F88566DE0B7507B7593F7A58E236
+In2 = -0x7365485F828A086E19F5DF820718B90760B28C461197BB185094D64AEC39009F9F
+Output = -0x147A6A1E5B660BA7CA8692F974B4B0A53D4598762B05B21D5942BEC883E32EB3CBAA56363EDC76813BBD902D6681650DEA3FC124B021FF1ADBDED8E6108525C25FA0BEEA86EECAAA309A04CB9037B4098A
+
+In1 = -0xBF6928C38E0D7A886BD8F25E448578186510D8CE4D
+In2 = 0x410A74CED5334D47C69207AF3B4B3F48C547349E3B1263C00A7BA51A5474E6D4FE5BA3540EF19BD404A3853F6E440834
+Output = -0x30A184CB8B353D03F720DF8140B6784E8E3776D00ADA9467C4B83266ECBD97BBFDA9F23AAF3853799E025FC91222D04910BAF529D89582562B1E826F211CCD853D14F04FA4
+
+In1 = -0x1BDC3298C6CE0101BD56ECA54466DB2009A5DF49F2D9743F53BD1B12501D750BF9A824C0F62541B5FA2F
+In2 = -0x5A3F15B6601E5CBF674F9A5C0F6D1AA980EAC675F5409D1A
+Output = 0x9D2475712A5BAD847B37969C5940CD226E0BC8D703CA41403460569B1338F8AEACF6CE1299AD0027E25E7D917A94B4DE8F1478340B95D91A1BC3A63207DCDAA3BC6
+
+In1 = -0x108D97B010954BC30C97F41F9B2BE3604EE39C619400CD912
+In2 = 0xDEAFD5AD48C2EDD66295E707D1B20C71BE1C1CDA0F7D20FB01928702582834BEC8125C28ED220F4FB7EE4F99A06C1B5670303087B5517AB6FBF1D144220
+Output = -0xE66282663563AE0C6701E42896585EF8E5D77E3AEA8E97BC4E2BAA1BCF7B97471840396656E9A717E44595BB5F6C455A48C4D8D61D4FE605DB72D3AC0E609E1EB72461E079E1AD2BCF2F9D196A8FB407DB150F9C640
+
+In1 = 0x4AB9069FCE6B4A4A65BB8A7F191B5690EC140A0EB62FDCE7F06337D4A
+In2 = -0x3CD7F5A8685FA64F14CA75EF841DE19552CB23150CC4016FC24FEE4902EB13FEC309282CE74EFA7C19716C1D0ECDB36199D676261BF695DEC504A7C7EFBA4634
+Output = -0x11C266A63FD1E0D66974C13F9904BBAFDFDCE7C578FEDABEE2C70DE8FDD8238CC94212C055A8181AFCBB6AA1C7689DC9D8A37177249AED84C56EE58521297678D35525C9CD5E745C5E1EE42435A09B8E4A402BF3F7102EB66747BAF08
+
+In1 = 0x558D9B1E2226B0391CD0A9DE613C5297D9B02ABC04094E9BD6123719DC9CE9722B0590CC2BC006C79230A6736CF80BC529B483
+In2 = 0x6BD51C914E380ADC0
+Output = 0x24096833B4A89D843C7FFD803CD734E9B0C27685F63039176F6D1596687432F6AF1043D15C333129E91720513FD4AB2C2A05587A580823778C3E940
+
+In1 = 0x2690DBCD87AC52B537A547CA13EB85FD8A9841CEFC6CCAEA891E4BF01AAD8140BEDC8D4609DFFCC005448B19AF90963BA9D70AA64554114E725C408C0AC1
+In2 = -0xCCC81EDA10283A8CE840D074D800856F3B2F47C5D50C1AE65B0D439B19
+Output = -0x1ED994F9543BB0A5FCF4A137DEC85A2CD5ABB2E5CCA0D0D3AAE7A70976558C0C22B95B24BABB7A15254376923D8DE07F51900E651E35E7798B7189E6D3F292A7800647CD25D3008F0A7B54EC238AF795714E1EB45E3FE4B5B2E7D9
+
+In1 = -0xF056B548F9AF6F8DE2EA0214057E2ED5297F1588A056F1081DB0AC50F65DCEE8B384B02DB420BB978BBD2B103D5AE6E5D97B6EF9D2DF026F91AFBF888C
+In2 = 0xEF0BF9322ECC7
+Output = -0xE06C30EC5E70699D2C0A6E7FDA5BDD8574F2B7EE052350B21F985AAB32D98661A857F0F5189EDD9A37B1117256C15AEFE70F931B9AE8F934B040BD43A957B90B65C34D4
+
+In1 = -0x1B3BF21D6FA3AFEF4E7F3BF8345D3D16A5E62768BE665847D23BBEBAF4327F47666954D61CF4C56B8C095BB06690DEFC8EFE554D64C58D3EE14BF9FD667144D
+In2 = 0x4DA91A30F9660632271CEDAD857A9DCD6A84A1C150F9953F8DD55E643D72310B1D4BBA17324149D85DB686E231A4
+Output = -0x843052EFC5F7ADF8502434F4F6D457B0718196B3E81FF36DE4CBA34924DE02B92466B349DF6533B9C6357141EEACF947E42FF7871725DE713A1269FC594AB9D587915BE5E1767EECC7D3DA285B9C96ACC52E6E39A991F468D42DA637EDED89F099A60C4CCB48EDFDCD4EE5BE54
+
+In1 = 0x1728EA6059B02F1F7AA518BAB0F44EAD25DC2329A563BA0AA674FC73312625B74E11192741C7C53B6DDEF51ED3
+In2 = 0x234B78A0ED214751DBD0
+Output = 0x3316BF19360E706EA7B145B20171892ABF3FF09D56FF43A3E5F6E8C9BDEA9E047548188E50AF04325CE1FE5E3954527B31E4F1E4A8C70
+
+In1 = 0x37E143072FC0C5906CAE3882433C1FABBABA02D26F8E5BA49594A97892DFE26A41A5F07066B701
+In2 = 0x7E539D529F574D4302FD6041EE55F437B73EC74864CD6708D7D62FDE3
+Output = 0x1B931F5D73E03460481891D494134409BF8FDC6469C807392D796DA9ABD6620E3FBD0680F2ED34DF9955DC4C3E521A25E3433B482489E7A33C84D41259B2D83B95242E3
+
+In1 = -0x2E4A99C5B35F2AD35B2DF5547FC34B8C828B029EBAF3E6CD633A7440E1F185A83
+In2 = -0x2177DEF6E90DAB1DEC026469B59C32DECD5C4A7D1AB6D34D5E19DB7DB0B5
+Output = 0x60D4AD14E3339F908BA27AD8C2C7FBE059AB4C4E9F1C15FE0EF9FF1CF0BAE792073312B8C19DFE4BAA12463A96B110F9CB526B696FB5008FC879FD690E9F
+
+In1 = 0x5757F6D35AEED2F8BE2B76C1F65C9DD537F9123647A81CA542233CE1
+In2 = 0x10F0FEB6606BF4075933A343E3076B48D938B440E1D7A5545967A87B9B7E80F46F87A2CFE
+Output = 0x5C7B8CC1C292D26B5BAC01E2D381CCB7C9A23EDB98D4326E98E6CDC201DE0E7DB1A12AC771F3F7E3B7E3B2D9E93C5A8F477B9CCB5F06B226E5A84FA0A8A7133E
+
+In1 = 0x7256C81379A7601D8F47188E70D172C733529288928AE64ED71DD6D41024B6927B8EA5E53E0DEAC56CF353EDDCC6BD00214788B3C276F2B984E1859
+In2 = 0x5063C2F61C2ED5EF0F349C65055124E21E8F332123AB2C60529C0BEA6A23C33A86873123358692C33B2FA94000CDA21FDCD5BF0001EB605308EABD728D81AC15
+Output = 0x23E7AD292525C7B234F72157B119BACACEFFFBD27C8B7F9841539EC5E96B8B389F855A01B6DACDB7C11C2E7E1E5DE7B10221D444DC69A974AA1F8D840C98A52EBD4E5EC677447AF6FE431067248034A8CE800094EB61D06747425E63B432E83C7BA6972CFCCCC53D39061DB87BB8622995B15CBF9E2B84D409CCB4D
+
+In1 = 0x2D7C9B
+In2 = 0x511304D37488A38400EB81D442428A70835A36196F44919B122916AA57124668254A3C19D25F9E534B9F
+Output = 0xE67CE2605D47E7C231AC473CA114EAF1F689ABC4BA2592D4D76E8E1CC8985F279A12B1998E05785398002CD45
+
+In1 = 0xFC92ECFC6218E9F5C5CEE8518DEB7B10E5E75644B333F8E62A165D9B64DB56E9663BE5D844D7C60A9
+In2 = -0xEBE541C99DF3587B69BC469CFB54FE
+Output = -0xE8BD0FE1E52EF8393E81036CA38D5FAFB8ECA5B96E6887E77EB5C918F64F3003BD0D31184000771176243265EE8C9351CCF80C172D25BAE
+
+In1 = -0x3B6E4E1BB9D40A9F5609648857BC5B8BC4C5BFA7
+In2 = 0x19959E286378177828AA51D787338B149C1529F4AB6A7A17403ACB849ECE08E863AF00E717205737CAB90F51F4927E78A7907D5B02FF6A4B1A45DFA113E09
+Output = -0x5F0818B9FD1B7D5C9D9FAEDF5EF9CB9E23FCFDD83DBA40BF49DABAA8F540675EE121791FAA64CA8AC5597BD4A979D31FC0571D26D4F07548E20C2FD74B9715C3E0ED4A8DA9449933ADC2EF50DB879F752EDF
+
+In1 = -0x27A67AB37F0915ED8760819FE0EB511AE453450EF1AC7C9AD66A42453C33CFE3E23ABF4143D536D345B0633E8BB451801F8E7F013AFBA4195DE6569
+In2 = 0x62A168DFC5145559D1A8C60684CCB8EC087D050AF56DFA891D36CA3394309CB752051797996CF06B9538F01A84A9868DA78C179D7991A696C77149DC22E514
+Output = -0xF46BAEA2BE86FB8F8E6E87C5F6DC565F38151B5B2DC40479D9AC00519ED1DAC6CECEAFBE9C3D54D971068D45BA10D95BD810602CC4763574859EA892972C483E08459A5EDFABE33840B461BD63FEA1CC6CE2164F7A72FB87D99567C857A6D5FA9519FAE2242E9611267389201A0FCC1F9C0216A582D05A08D934
+
+In1 = -0x1A78FC6F1FDC0E117022759157F08600
+In2 = 0x719A820AE158385E601413464E
+Output = -0xBBF61A778210C63D181E023663D6D699866B2373046B421A681ECD400
+
+In1 = -0xA2BED87EA8F8C54786543A59DA78D88894133A70CED72BC63491A0BC5E9681
+In2 = -0x2D4
+Output = 0x1CC43BC4635DF8DEE47E635061DDDC46242C6614708F887CC8CABDA94BB81A4D4
+
+In1 = 0xDE20BC2B13A3F297B28EFAF3DC537F754B8CADBA839D113BDE4EE93C803C505F5C0E8A6F31FC86
+In2 = 0x238C0158E854D7DD20648B5A68296C23083A8CC3BAC8151A25A2241453221B362E1C8E1771E67411CA006BB2
+Output = 0x1ED7F4CC10D24A47F10227E558D210B9DD5DFBB1704F8EE61AA8DA8BEEED8D9E7AFD751C3B5FCDED020D063C87173C852D9960B10BB27DB062038530D71A0AFAADE6B72DDFE8F2B6FED83512F5E6E2F14D972C
+
+In1 = -0xAD4AB34D10F5884F944F9A9BF2BACCF903966510D0A03C382C9F892E81
+In2 = 0x3822FD0367CE02C06AFC1D44ADC4706A94188C026981146554973745221F6D8A3
+Output = -0x26000669CD49BC347D4975D6C3206E73CC2C606005415AEF2358805BAE6C546E6BE85DA96D79BFD1BA7DA32EE4791AAC046D1C82F718125C128A48B7423
+
+In1 = -0x5675C48CF6B5C4474E50B2FCA5E1997036C8632A20D2972E0E36A88541B5F457ABBA
+In2 = -0x64A2EF29693E791C3B1F7D540FB31DF15DBC4475EA53AB13D86C494DC3F487289777D001B64A9C71E81AC6774D6369
+Output = 0x21FD0813607A9BA3E3264AF5B3975ABD416ACE2FF2D06DF0662936CF72A223541F402C9BA565159C116D6977EA330E8EE3FD047313F69E86A000207F909CACE7C69DDA8D174AF3725B9D30462D3C505D4A
+
+In1 = 0x740A98DDCA8474C0B9021E343D386
+In2 = -0x4DC7DCC367BD8560AF
+Output = -0x2341C84938C97AD93DA19C2C0C1457043E98EB49D4DD89A
+
+In1 = 0x24302E6CC8AEE123053843CA9919801CB9F1472D07FF6E92AF6BBF560A40970E70BD634
+In2 = -0xD454745984B01C25C194329B9581B8AD713F381892F77E9D301D9BC8BB0F0A176B7660F826851DF0195
+Output = -0x1E03D6B3CE6DD79E804C78238EC54AD6AAB201061B327139D76C9884EAC3FFE0E535D9D4BFC1A8F52403802B3BC9CDFFE79F063799D6BBD28CF45339A05F91CAA084ABF47AFA985ED39105E044
+
+In1 = -0x38BF13F505BEC089F6EDAEBD1FCDA0D8852C6194AFBAB8BB8
+In2 = 0x218929E08DE5513D194E3AC02EBCB70C6B7C14393CECC659665AF12
+Output = -0x76F091CA4B571243534D60FDD7710B0F532A6531025732A92AD22D86372CA2A249746ED218EBFCC5DCAE8B43B589773E62A9AF0
+
+In1 = -0x1888C92BA95F548276290FE3A2
+In2 = 0x747E299922AF5A0D3DC5F0DAFCC179F3B0AF8D3979B862588CE44E3573B2D7E7318101D231DADF6EA1D0C81E92C11243711FFBEB
+Output = -0xB2A12776187C149E131BCBCCF378EA3B9408CAC28F3781A55BAD46905D480F2AB3E4F08F7A64D393D7460294E00C3013723F2CB058D2EB35D313890875863CBB6
+
+In1 = 0x1DBD1900384B4A7A0A1C140EAE72833CE18BACF9310969DD8628149981F280EE31996E69E5B8
+In2 = 0x76F55787D836A81BFCC0D6CC6BEF4309C7C5830955A241649552F38BE15F02204C51A
+Output = 0xDD1A9AA127DBD249BBA17FBA6E05741877EC9E9EA5E6A109D6340E23B5CAA924A40400CE1F22543D198626AEDCD2BA1CC98938ACFD7BF731160B51C7FF16EDAE7D1B5A36BB67ECB0
+
+In1 = 0x2B967FB644A63FF17898BB63
+In2 = -0x60D1F4157F1271EE75067CD28082A4D6AECCEA3A636A712711B019
+Output = -0x107C2F51B841646D470881071A6425C87A0FA61BCDE5FC885BD3C99CD84A4F66E53CE14E515CAB
+
+In1 = -0x3863CD446D6F7A196A5589D2248013FED088779C7D132A8A92DE7CEF62428D12A65A6703C9F125245E9F0E7B2
+In2 = -0x31A6A0F92E9A42004CEA2A79D3F8EF77A1C1A107E89143082395CC8C06B43F78DA60F1887A
+Output = 0xAEFCE7676F2A211BA43AEC26309EDC7F46448969951490384DDA7E99A7C8618A6A7174E952979462610315A8B2D1FFD9AA7EE39AE06D6A84FDE1BC8098750FEE5D85C55F432BB9E10F868AA9DA5676FAD4
+
+In1 = -0x1F15069789259C5E378B4A78B21177D7852E1E2A67E5983C2F497F04275768166CEDAE7514CAD44B561F44
+In2 = -0x18AFBB61B46A7FDE5165F70D14418D18686400FED1EE2DC682F71B
+Output = 0x2FF4EBDEF222ED5DDA641D105B32D9923E208377CC765DE2C83C4491286A155B287488EE971823BD55ED39454A5EB50B2B2DB04E410519E904BF316777CE8AFCDF282C7E82C
+
+In1 = 0xFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000
+In2 = 0xA3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000112AC1C9A
+Output = 0xA3FFFFFFFFFFFFFF5BFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF5C00000112AC1CA9FFFFFFFEED53E366000000000000000FFFFFFFFEED53E3660000000000000000
+
+In1 = 0xFFE32ADE79F13069CA8FEBE1CDC589F26EADFC7F479E31A8CE3A817D6067397F
+In2 = 0x17AE95CC69406271F51D96DD95F0C25365BBDA81E6DB59D36172A931B21CC8F1
+Output = 0x17ABEAFCAA59BB51CCCE3ECFD0796AA817E5F81E8FD76151EFE17CB21B9ABE1CC421EB978EFBD8E21756BE4EABD32DF1C6008FFCB6550088834103EBFDFC588F
+
+In1 = 0x3BB501782D8513D46AFF72C5C1147E0DE6A0103FD4FA3EC985740D25C9B1AF8A
+In2 = 0x17ABC5C512534C3FE776699AEA22A5D9BE0C6891A32C028CE9EC9491B1E93A27
+Output = 0x585532A080F20C1554C3EC2E8EEACF75B539FFE15F3AF18912B4CBDB0175C3171C37ACB8A725DF5E64EF671831BBEE8359B4C1C8B09F3B31BD932B52A710206
+
+In1 = 0x80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+In2 = 0x80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Output = 0x4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+
+In1 = 0x80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+In2 = 0x80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
+Output = 0x4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+
+In1 = 0x80000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000
+In2 = 0x800000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+Output = 0x400000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000000
+
+In1 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+In2 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+Output = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
+
+In1 = 0x80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000
+In2 = 0x80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000
+Output = 0x4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000
+
+In1 = 0x80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000
+In2 = 0x80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000
+Output = 0x4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000
+
+In1 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD42119822E32EC61A1EF372CB3E2DD28C259C527F939A26A86D2127DA5EF377DD69CD3EA474
+In2 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF781FC8EA7C4BD4EC2C350A3ED4A9E8FAF38E1E0CCCCD41D7214B8BB616F898A8470DE49CB67F32
+Output = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF781D0AFC146EB81AF24F293247752728C61A43A91F4CD57147F3FA4BCE53614D687F223374FCDB2CF91D886CBA2C2E62A577DC266D1804AD45CC2E28ACEDA9A2C5496B7989261D73220FB0E74FA2F09B6F1224B8BCE5D34B67CB93457E824A9CDB2D8BC449AAA8
+
+In1 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF781FC8EA7C4BD4EC2C350A3ED4A9E8FAF38E1E0CCCCD41D7214B8BB616F898A8470DE49CB67F32
+In2 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD42119822E32EC61A1EF372CB3E2DD28C259C527F939A26A86D2127DA5EF377DD69CD3EA474
+Output = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF781D0AFC146EB81AF24F293247752728C61A43A91F4CD57147F3FA4BCE53614D687F223374FCDB2CF91D886CBA2C2E62A577DC266D1804AD45CC2E28ACEDA9A2C5496B7989261D73220FB0E74FA2F09B6F1224B8BCE5D34B67CB93457E824A9CDB2D8BC449AAA8
+
+In1 = 0x100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+In2 = 0x1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+Output = 0x1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000000000000000000000000001
+
+In1 = 0x1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001F
+In2 = 0x8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+Output = 0x90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000106FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+
+In1 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007FFFFFFFFFFFFFFFFFF
+In2 = 0x1800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Output = 0x17FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BFFFFFFFFFFFFFFFFFE800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+
+In1 = 0xFF555A18F82239DD165C52A4C5210B64D70E18EDDE4D833EFE6529627A6D485ADB0C4CF74F38A362C786CA2C04CFA815C3253E5DEEEACF317E2F621BD015DAB9FF555A18F82239DD165C52A4C5210B64D70E18EDDE4D833EFE6529627A6D485ADB0C4CF74F38A362C786CA2C04CFA815C3253E5DEEEACF317E2F621BD015DAB9
+In2 = 0xF4AAFBA87A45D7AE7C217CF11731C1B247EFA7CBC325B72EE4B7BF8A2141CE088BD11C6C42C2D98F3FF36CEC51CA2971F579243CDD97C249612583D8D1738649F4AAFBA87A45D7AE7C217CF11731C1B247EFA7CBC325B72EE4B7BF8A2141CE088BD11C6C42C2D98F3FF36CEC51CA2971F579243CDD97C249612583D8D1738649
+Output = 0xF407E38E5A63579D70CABA83FD8FFE4A59FAEF258BDF3ADC17F12CECBA6A3CA774BF1628E4DB2CB885E2AE694A2F05A32E932AF0D435AB4C5D0280D43C9C460B2A917EBCBA2EDF555BD0D0A9125AD110978DB3931DA25C5786B63A60EFF323E09E0815C203C1F790DE59AE13F20AE5B5B1FF96673A3BA0E0C15D12FC8A0BC0D4790B52CE6533B7D2654171C62C05A742212A99B597A7081AC598EDFBB0A791CADDD2E90958F268F82B0B50EC0588BA81D845ABFBF7D63FDC6BB2A37C5E42AF8B4281B7A00568301A7A3B5BA1173AD47BE397D54805E3E69F56D3E0877B1EAA91B489E9703A0B9E1FD29451415DACDA6F54D9408591D04A480758115410D334C1
+
+In1 = 0xB55045785BA285183DE830EE8CE3E4DB81058343CDA48D11B484075DEBE31F7746C0E52A75BB7E6ABAB9B72EA7BA2FE7718D7AD155907246A93AA171114CA298D77F89EA0CAD907E7AE7FEA23E2B0D8148DB67D4C11AEC1ADA089D6D4F28ED906AC0E52A75BB7E6ABAB9B72EA7BA2FE7718D7AD1558FF7F12B66644E25754566AE667360748F62562B31BB3248CBD16E670B50AC3ECD8C0EE2CA6D500A9B0EAFFA9B9DDF17749E376D185FF93B7DE68C95A5DB1416572A409484006A2B61268E8C372EEEC38456EFEE31ED7E9784A8C89F356C1B4B572D05BD45D740A755408F069B9DDF17749E376D185FF93B7DE68C95A5DB14155DA49612583D8D173883DF4AAFBA87A45D7AE7C217CF11731C1B247EFA7CBC325B72EE4B7BF8A2141CE088B93F1AD58A448195454648D15845D0188E72852EAA6F8DB956C55E8EEEB35D6728807615F3526F818518015DC1D4F27EB724982B3EE513E525F76292B0D7126F953F1AD58A448195454648D15845D0188E72852EAA70080ED4999BB1DA8A9B8951998C9F8B709DA9D4CE44CDB7342E9198F4AF53C13273F11D3592AFF564F157C9646220E88B61C892E7A006C48219736A5A24EBE9A8D5BF6B7BFF95D49ED97173C8D1113C7BA91011CE1281687B573760CA93E4B4A8D2FA42BA28BF58AABF70F9646220E88B61C892E7A006C48219736A5A24EBE9A9DB69EDA7C272E8C79B4
+In2 = 0x85AA822BC2DD1428C1EF418774671F26DC082C1A1E6D24688DA4203AEF5F18FBBA36072953ADDBF355D5CDB9753DD17F3B8C6BD68AAC83923549D50B888A6514C6BBFC4F50656C83F3D73FF511F1586C0A46DB3EA608D760D6D044EB6A79476C8356072953ADDBF355D5CDB9753DD17F3B8C6BD68AAC7FBF895B3322712BAA803573339B03A47B12B1598DD992465E8B73385A8561F66C607716536A8054D8756A94DCEEF8BBA4F1BB68C2FFC9DBEF3464AD2ED8A0B2B95204A42003515B09347461B977761C22B77F718F6BF4BC254644F9AB60DA5AB9682DEA2EBA053AAA047834DCEEF8BBA4F1BB68C2FFC9DBEF3464AD2ED8A0AD9524B092C1EC68B9C3CA74AAFBA87A45D7AE7C217CF11731C1B247EFA7CBC325B72EE4B7BF8A2141CE088B93F1AD58A448195454648D15845D0188E72852EAA6F8DB956C55E8EEEB35D6728807615F3526F818518015DC1D4F27EB724982B3EE513E525F76292B0D7126F953F1AD58A448195454648D15845D0188E72852EAA70080ED4999BB1DA8ADDC951998C9F8B709DA9D4CE44CDB7342E9198F4AF53C13273F11D3592AFF564F14739646220E88B61C892E7A006C48219736A5A24EBE9A8D5BF6B7BFF95D49ED97173C8D1113C7BA91011CE1281687B573760CA93E4B4A8D2FA42BA28BF58AABF70F9646220E88B61C892E7A006C48219736A5A24EBEBBBDB69EDA7C272E8C7590
+Output = 0x5EAB77976B4E7C0A37D0E6F8EEF415A517036AF670328114EB0623BF495DE3E3036F8DD0322B4AAD0BDF4A3DB5EFBE71FE062C28E89CA974173C5674BA013FC4DD80F4CB1AEFFC3AD580E9445255316189CDA522AB9AFC90EA88C20403E8F09119A2548861732F0B05A1DA83CD0D07FB6109727FF10F70F4D64F87973F58544B7A6852E4763DE77EB038BDF650A2BDF5FD61026B172253D85063260E07A4C1FA8CA5375EADE524071E22F9B2B720E18DD6A604869DFF4F060048C711FB2480E12009139FB06B729BF563EF4DFF7618E6192A4281FEE11C74A9EB4C1A08B3C942D8D516F5CC6B3B0B3AFFBDC10DC9C8EC716E1AA88FD9311BECEE17A04C529192839E7D82CE795393EEB4227B0F0BC0663227DADACFCDDD1D1A1066A5F052D5CBE913BE4AD8A558024883FE02E155CDC4D25EC9E187E2CD6E70FF4E57F65EA88B84E6656A7B4FFE4A8CA7F81029A1203C3F594225508A69BE69C907D8C4F49C15E46424E2EA5050731AB13C73D029B781BE954537AAA69F7EB3646872ED8FC4949E02F8A11A13FF61F08ED8BD1E3B369A6CE00DCC34F37AAD6EC962C28B72BC32A4BBA3FC43D2E540A687EDABE3CEB58BCBCF8EC364A99196431C02C0A85C6295B0411DBBA073E441F9B5E464CAE471E87815C10DA1D553688D81D2C98AB5D2150CB406E4B00BA582BA40DABEA8A13D13783E8DC43E95A9DAD5991D339D3F227F8930A5712C29C6E49145C7E65965025E80F4884C437E1F20973FF00A429F6BA61AC8A7B135AF30E0C21CB5CAD4A1CF743DA9F3A1B3CB4626494D6DB1113E41BC94EC6E6DBE882132549554254720FE5E5DCA099B2CF27044FEE0391A642073741EA0A222009B62C136DF90B9CF637575C677EE37EA252E00355D35D72842B41A648BD6067798C968233DBABE50D2D56F4CFB10FA49D151F4E8219F71E7F7A6A03968A7BCA081937B2C5D513E918E937DCC2893C7393621C4271B186801ACD89787A499F82EC69EB3F8E5AC76011B252E044ED51061C797B41DE1367E38CE8106D08B6EE0D94D2FEA786278195EC8137DDD8EC7006CD84EB32CD7E45D35AD9761F3F941016D905F6F27EE044BEDD3C8B1FCC63A842171724E81B2F894EA27E55CD29796B7948DCD7F358C29E9D3389BA725C4351AA3BFE7CA0CC678445028EE24BFDB0891B1AB8A0C1408C9648F3EFB9A8FB67C9B3AC14D40DC4B81A38061F7D1D28827729FC58CF42467140B57EB41F85E181174A3C3B62C6C697FDE2DC778495E060E968EAD073DFB9F279F0D5BD449E7AD05285200534A06BB73C46D7B4A358B63B9C3C2F79F7DAACAC35EC674CA3C0B6E7CFC33333C87030D08C87C7850615BF16F26E4001222EC96CFAFF47943D21998E8DD24CC5F7F4747350ED56A656F6ECCF7A3E8565DA3FEA23C5DD05A5BBCA2759C02D2FF45703102B6D4913B940
+
+In1 = 0x1756B56CE57F64C2126D870BB3747422527219980FB5B3194E10862FBA086918DE0C51BF3E332A088E3220250220E45C09D4C3AC34BBD02EC676821AE25608F93B9675AA92C20EB
+In2 = 0xA2AB2077B4DCD709754E597599535B2D141EF2CCB40DDB463E0D24BFB61156EB5AB20AFEE3F23E7F31AB70358298D36062D2186B0B6E3F4B555BD08F65F175FD
+Output = 0xED478AFD970F5D8E22B1E85E2C186CD98172870A148C78475D57F7B524BD7752FD6F779A440CCE75981160644EC06357C057BF0BF3B880900F38AA0DE6E8B7EFCFFEE2AFE75243A1C03AB249BEF09D30817B42FD55292F8F135757359B858488BDBCF8846E0A0B8F51E9B14930649541EA6BB22AB2CB38DFE6A0666675EC48E07D92B70FE2EF3F
+
+In1 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+In2 = 0x4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
+Output = 0x4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+
+In1 = 0xFFFFFFFFFFFFFFFAAAAAAAAAAAAAAB00000000000000000555555555555554FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF555555555555555
+In2 = 0xFFFFFFFFFFFFFFFAAAAAAAAAAAAAAB00000000000000000555555555555554FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF555555555555555
+Output = 0xFFFFFFFFFFFFFFF5555555555555561C71C71C71C71C6E438E38E38E38E3A9C71C71C71C71C7238E38E38E38E38E001C71C71C71C71C6E38E38E38E38E38FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAAAAAAAAAAAAAAA71C71C71C71C71C38E38E38E38E38DFF8E38E38E38E38E3C71C71C71C71C7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000071C71C71C71C71CE38E38E38E38E39
+
+[Square]
+Input = 0x0
+Output = 0x0
+
+Input = -0x1
+Output = 0x1
+
+Input = 0x1
+Output = 0x1
+
+Input = 0x8000000000
+Output = 0x40000000000000000000
+
+Input = 0xFBC09CE6C7753664
+Output = 0xF793449845751B9B8A4F0BEA3AF65710
+
+Input = 0xFFFFFFFFFFFFFFFF
+Output = 0xFFFFFFFFFFFFFFFE0000000000000001
+
+Input = 0x3FFFFFFF3FFFFFFF3FFFFFFF3FFFFFFF
+Output = 0xFFFFFFFA000000030000000C000000130000002A00000021000000180000001
+
+Input = 0x3FFFFFFF3FFFFFFF3FFFFFFF0FFFFFFF
+Output = 0xFFFFFFFA000000030000000A800000178000002E800000261000001E0000001
+
+Input = 0x3FFFFFFF3FFFFFFF7FFFFFFF3FFFFFFF
+Output = 0xFFFFFFFA00000005000000060000000E0000002400000019000000180000001
+
+Input = 0x3FFFFFFF3FFFFFFFFFFFFFFF3FFFFFFF
+Output = 0xFFFFFFFA00000008FFFFFFFA0000000A0000001800000009000000180000001
+
+Input = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+Output = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE00000000000000000000000000000001
+
+Input = 0x80000000000000000000000000000000FBC09CE6C7753664
+Output = 0x40000000000000000000000000000000FBC09CE6C77536640000000000000000F793449845751B9B8A4F0BEA3AF65710
+
+Input = 0x8000000000000000000000000000000000000FBC09CE6C7753664
+Output = 0x4000000000000000000000000000000000000FBC09CE6C7753664000000000000000000000F793449845751B9B8A4F0BEA3AF65710
+
+Input = 0xBD0195D16E7CCFAECBAEA99C93AF0BD7
+Output = 0x8B8B5739C0749D94995991A47AC664214DA95AA566D243C0826ECB521A7E2E91
+
+Input = 0xCDE6BF0C9E537153D5784F7718F6EC90
+Output = 0xA59B5DF60ED1F64FA35F16EF3BDF88FD5D1C21AA1A318B56050008667F59D100
+
+Input = 0xCC1B05F112A67F4D0EF8A4389E60CFCE
+Output = 0xA2BB145276B697C049EDF608F44309FFC4EF6B4A93F16FAADDB67F3ECB2EC9C4
+
+Input = 0xF047C0A0B6B0EFA1D8B47490FE62DB56
+Output = 0xE1869D49C0A28E62A916ED0A94CBCFBADB6BE0913A62BBFA53B5022B51C440E4
+
+Input = 0xDCE99F85EA38416FFC953675A9F5F410
+Output = 0xBEA25F61EFBCA9DEAE023B52967834AB9A4E8AF06763B076293E7F2A2F4E8100
+
+Input = 0x9836531F6B1705CFA8E091FF3931A950
+Output = 0x5A808E3C7B69E7E9164A3CD6D343CC596184436E884551BE8B831467E09AB900
+
+Input = 0xE8B538496B78657A89704090991CEE6B
+Output = 0xD388F64DB6FC6440BC8F27389A3FA2CE51637C690CB33AB636F550A0EB7320B9
+
+Input = 0xAFA871FFA1C6B4E8A55CBACCFE843667
+Output = 0x7887BAB15175AC389F3B2457B4625759536AD3FDFD3355D69ED7006489C79D71
+
+[LeftShift]
+Value = 0xE739A1CCBDB501334F332ACE8B16B81C6F5EB6802F2CC1966B7522BBB3A6EB1BE00DE71EC26851919BFA61A691
+Shift = 0xCC
+Output = 0xE739A1CCBDB501334F332ACE8B16B81C6F5EB6802F2CC1966B7522BBB3A6EB1BE00DE71EC26851919BFA61A691000000000000000000000000000000000000000000000000000
+
+Value = 0x72376EA96BE400981D34608D400A621785BFADAF9B3BBF0AD4D28FFD7AD5EEEC8DDC1678C216115F4A71EC0BFA5022018FCF30AB8AEF355F42C45D3C1B4D
+Shift = 0x74
+Output = 0x72376EA96BE400981D34608D400A621785BFADAF9B3BBF0AD4D28FFD7AD5EEEC8DDC1678C216115F4A71EC0BFA5022018FCF30AB8AEF355F42C45D3C1B4D00000000000000000000000000000
+
+Value = 0xB0C043282220B913876FAEDD80EC831D9DDD45B252AFE051E5D52B8A1153BE41148169362123C8A812778692648A2F81
+Shift = 0xA4
+Output = 0xB0C043282220B913876FAEDD80EC831D9DDD45B252AFE051E5D52B8A1153BE41148169362123C8A812778692648A2F8100000000000000000000000000000000000000000
+
+Value = 0x2D00BBDA306021108EC0E7CEE5A618F96754E0362803F9BA755EC0C95B524DB86AE99A9351BBABC
+Shift = 0x70
+Output = 0x2D00BBDA306021108EC0E7CEE5A618F96754E0362803F9BA755EC0C95B524DB86AE99A9351BBABC0000000000000000000000000000
+
+Value = 0x1E5E48BD54D24BA
+Shift = 0x6A
+Output = 0x797922F553492E800000000000000000000000000
+
+Value = -0x3010FC160FCB335EACF8C7B6CF44823E90640D401DD9B8D921AE71FC5A1CC6CA2CC3E0BB0F151ABB
+Shift = 0x3F
+Output = -0x18087E0B07E599AF567C63DB67A2411F483206A00EECDC6C90D738FE2D0E63651661F05D878A8D5D8000000000000000
+
+Value = 0x58089F86A0242B6AD790827A22DDD0B3D171C4F949778E68B8EFD9F2813A2D993AB527EAD94355B8DBC02306A60BAA7F656768B6EEFF2F9FDF019
+Shift = 0xC3
+Output = 0x2C044FC3501215B56BC8413D116EE859E8B8E27CA4BBC7345C77ECF9409D16CC9D5A93F56CA1AADC6DE011835305D53FB2B3B45B777F97CFEF80C8000000000000000000000000000000000000000000000000
+
+Value = 0x47EFAD9FB55F9D358BFC1D908411EF93BA1C74760198093D2B2244455B579CDB3F3A7B0C8228421E1C57B69869964C1BAAB891C440AAF
+Shift = 0x18
+Output = 0x47EFAD9FB55F9D358BFC1D908411EF93BA1C74760198093D2B2244455B579CDB3F3A7B0C8228421E1C57B69869964C1BAAB891C440AAF000000
+
+Value = -0x1AEB4830D3884941BD0B4B168AD9CEDCE7CFCC05607C6F06DA6876FCC254793DBF426D94CA37558842211FCC7A6D2A633DF6E71EF3
+Shift = 0x57
+Output = -0xD75A41869C424A0DE85A58B456CE76E73E7E602B03E37836D343B7E612A3C9EDFA136CA651BAAC421108FE63D3695319EFB738F798000000000000000000000
+
+Value = 0x2C2FF2FE35A12E015C3B4E395E149FF1D98263FD298804179B136A7718426485715884A67932A8D56E768F4C0A2F
+Shift = 0x5F
+Output = 0x1617F97F1AD09700AE1DA71CAF0A4FF8ECC131FE94C4020BCD89B53B8C213242B8AC42533C99546AB73B47A60517800000000000000000000000
+
+Value = 0xE463D99C664854ED736F
+Shift = 0x6F
+Output = 0x7231ECCE33242A76B9B78000000000000000000000000000
+
+Value = -0x1A164C1E5E313
+Shift = 0x8F
+Output = -0xD0B260F2F189800000000000000000000000000000000000
+
+Value = -0x6A29D6A56B8FB08A7C4BDBFD59EE394C5F526C12C7791A4D5EFC2AB16490F58EB9
+Shift = 0xB
+Output = -0x3514EB52B5C7D8453E25EDFEACF71CA62FA9360963BC8D26AF7E1558B2487AC75C800
+
+Value = 0x483257AA698C5255677C031FCE49C53B3D666D42DF3BDFC6CD7AA91C3F595C088B3432744085C9A781CC46CF160C0B53F2F796D233F51A8070C39C309C
+Shift = 0xD3
+Output = 0x24192BD534C6292AB3BE018FE724E29D9EB336A16F9DEFE366BD548E1FACAE04459A193A2042E4D3C0E623678B0605A9F97BCB6919FA8D403861CE184E00000000000000000000000000000000000000000000000000000
+
+Value = 0x1FA0055D8231B4ED1D8BB55C0BBB377E5D7EA7217AE0547BF3C672301EBA2E96723BE40C5D98F
+Shift = 0x6B
+Output = 0xFD002AEC118DA768EC5DAAE05DD9BBF2EBF5390BD702A3DF9E339180F5D174B391DF2062ECC7800000000000000000000000000
+
+Value = 0x61C17EEC735A468B7E327D20F0A9602D530502E1823025218DFD31FF44F864BEA9DB9B2D25F9B0A
+Shift = 0x7E
+Output = 0x18705FBB1CD691A2DF8C9F483C2A580B54C140B8608C0948637F4C7FD13E192FAA76E6CB497E6C280000000000000000000000000000000
+
+Value = -0x2FE1ADCB94BF37ACD24F319555BB1A6FBDBF093FAEF07ACD35BF2B686A9E9D7A80434E1CF28DC9DCB50B722ACE8C8A8C43ABB402A436C
+Shift = 0x5B
+Output = -0x17F0D6E5CA5F9BD6692798CAAADD8D37DEDF849FD7783D669ADF95B4354F4EBD4021A70E7946E4EE5A85B9156746454621D5DA01521B600000000000000000000000
+
+Value = -0x77B652B8F78F33CA1710904B09766C8C896F5F499380FE9115F7F6C41C4ACB53019D0D782DBF43C4CF541058CA7C64D3
+Shift = 0x98
+Output = -0x77B652B8F78F33CA1710904B09766C8C896F5F499380FE9115F7F6C41C4ACB53019D0D782DBF43C4CF541058CA7C64D300000000000000000000000000000000000000
+
+Value = 0x16CB01B68A0C9783D669216A79D6C465E12FD04E81F4C7F5AD955074CECDE2
+Shift = 0xD8
+Output = 0x16CB01B68A0C9783D669216A79D6C465E12FD04E81F4C7F5AD955074CECDE2000000000000000000000000000000000000000000000000000000
+
+Value = 0x32C693253F1FAD5EC3032FBDB6A45F3D361530B27C317F31CA7863327F86AC12CC41380CDF65EA
+Shift = 0x4E
+Output = 0xCB1A4C94FC7EB57B0C0CBEF6DA917CF4D854C2C9F0C5FCC729E18CC9FE1AB04B3104E0337D97A80000000000000000000
+
+Value = -0x35AB812469C4DD191C4248667529BE91B2B045D4E2638A83A968A0F
+Shift = 0x6B
+Output = -0x1AD5C09234E26E8C8E2124333A94DF48D95822EA7131C541D4B4507800000000000000000000000000
+
+Value = 0xFB9571AE7949D845E2E5A351570AC9DA5CFB44E77D13ABACCE046932D78F6E433CDFE1BE19D1F404B
+Shift = 0x45
+Output = 0x1F72AE35CF293B08BC5CB46A2AE1593B4B9F689CEFA2757599C08D265AF1EDC8679BFC37C33A3E809600000000000000000
+
+Value = -0x18787A2E277E69E5AAF6D8A13359A33203
+Shift = 0xDE
+Output = -0x61E1E8B89DF9A796ABDB6284CD668CC80C0000000000000000000000000000000000000000000000000000000
+
+Value = 0x15F08E19EF16A909D37C6ADF61
+Shift = 0xD2
+Output = 0x57C23867BC5AA4274DF1AB7D840000000000000000000000000000000000000000000000000000
+
+Value = 0x254FEBF0CEE267DCFD66918F2683A52A00AB70A79BC5592DACFBEBF0CFDA1C252A002DD0FA75B5E7FC4F6722E3144CEBAFB58B3
+Shift = 0x82
+Output = 0x953FAFC33B899F73F59A463C9A0E94A802ADC29E6F1564B6B3EFAFC33F687094A800B743E9D6D79FF13D9C8B8C5133AEBED62CC00000000000000000000000000000000
+
+Value = 0x3D7AAD27059D540794499A892A2A5961C3B1A55F5DAC2DE9650C53484FED6F8C691D
+Shift = 0x19
+Output = 0x7AF55A4E0B3AA80F289335125454B2C387634ABEBB585BD2CA18A6909FDADF18D23A000000
+
+Value = 0xF9D36765FE12D67DCBF0C31273746BDE3E7E84E0007FC6C666A69AD7BDC95F381DC61D1CD9F39925E5
+Shift = 0x91
+Output = 0x1F3A6CECBFC25ACFB97E18624E6E8D7BC7CFD09C000FF8D8CCD4D35AF7B92BE703B8C3A39B3E7324BCA000000000000000000000000000000000000
+
+Value = -0x87396E735D99D52848308640C7C752114D4DDC186C04AE64075FA2ED9F69C627A3B51B01CEF0A89621AED66977297A44F5585C62DB0B46E2E9695189D21830
+Shift = 0xE1
+Output = -0x10E72DCE6BB33AA5090610C818F8EA4229A9BB830D8095CC80EBF45DB3ED38C4F476A36039DE1512C435DACD2EE52F489EAB0B8C5B6168DC5D2D2A313A4306000000000000000000000000000000000000000000000000000000000
+
+Value = -0xFA2A0F80DCE385AA37E667C1253078A3FDC7A4E83DDF520B63C63AAD19406693726E144F41A1E991985952B581DB517F93066FC
+Shift = 0x80
+Output = -0xFA2A0F80DCE385AA37E667C1253078A3FDC7A4E83DDF520B63C63AAD19406693726E144F41A1E991985952B581DB517F93066FC00000000000000000000000000000000
+
+Value = 0x140511E1D6E3AE41176789E6354B60950ABF20C8840231D0515FDD06D35E3C08644DE9BA31987BC77F06
+Shift = 0x4C
+Output = 0x140511E1D6E3AE41176789E6354B60950ABF20C8840231D0515FDD06D35E3C08644DE9BA31987BC77F060000000000000000000
+
+Value = -0x378F419372F8143E383FE5BF25AA16232FBA8945FC163484CA303302A10E7EC095C07408B08036F8B82CA7FDCEB
+Shift = 0xB9
+Output = -0x6F1E8326E5F0287C707FCB7E4B542C465F75128BF82C690994606605421CFD812B80E81161006DF170594FFB9D60000000000000000000000000000000000000000000000
+
+Value = 0xEF7A273859AAB9EA24CDE209CF14A8C884AF61A17C574C2481724205AA8B161B853D53DE688C498C5AAC95A9403E72456E53E6EA2B
+Shift = 0x1
+Output = 0x1DEF44E70B35573D4499BC4139E295191095EC342F8AE984902E4840B55162C370A7AA7BCD1189318B5592B52807CE48ADCA7CDD456
+
+Value = -0xD685A0F9021D409A6BA34F65EAF307080AB3A68CD1A535D8AE61BEA47295B2C81B
+Shift = 0xB0
+Output = -0xD685A0F9021D409A6BA34F65EAF307080AB3A68CD1A535D8AE61BEA47295B2C81B00000000000000000000000000000000000000000000
+
+Value = -0xCABB664B0A5943F07BAEEB496A2E0F4CFEDE69063E65AC69DEA016E5E
+Shift = 0x66
+Output = -0x32AED992C29650FC1EEBBAD25A8B83D33FB79A418F996B1A77A805B9780000000000000000000000000
+
+Value = -0x161F3FCF8DEBAB85F30133663F9D26102D93CCDD22AF1F4E9A51BD7DB2F441699380B821EBE4275FE5D946A4F66CB4257F0103A1B0A1
+Shift = 0xA7
+Output = -0xB0F9FE7C6F5D5C2F98099B31FCE930816C9E66E91578FA74D28DEBED97A20B4C9C05C10F5F213AFF2ECA3527B365A12BF8081D0D850800000000000000000000000000000000000000000
+
+Value = -0x7E14D1CF8B82F649AC06CFFCE296552705202EDFB7D721D572D3B00C4C31980AC46AD950
+Shift = 0x18
+Output = -0x7E14D1CF8B82F649AC06CFFCE296552705202EDFB7D721D572D3B00C4C31980AC46AD950000000
+
+Value = -0x6CE6BB7CED94F095C8E67B2
+Shift = 0x45
+Output = -0xD9CD76F9DB29E12B91CCF6400000000000000000
+
+Value = 0x7AE95BC60E53
+Shift = 0xCA
+Output = 0x1EBA56F18394C00000000000000000000000000000000000000000000000000
+
+Value = -0xB0AC35E7B076BC6F57E19A0568E00767E7F59AC407558326445BD0B247810FF7AE445FDE3A1C4F917DE916E64A1ECD3214E8779B
+Shift = 0x4A
+Output = -0x2C2B0D79EC1DAF1BD5F866815A3801D9F9FD66B101D560C99116F42C91E043FDEB9117F78E8713E45F7A45B99287B34C853A1DE6C000000000000000000
+
+Value = -0x378E9A5091EFD9896933F3547045A0A02CE3097900A2A575BD475ECB2AAD0FE23DA9B24E998CD7823F4C562F11F6CFBCDB59B55BFB5B5039A3AE054D5D9330
+Shift = 0xA4
+Output = -0x378E9A5091EFD9896933F3547045A0A02CE3097900A2A575BD475ECB2AAD0FE23DA9B24E998CD7823F4C562F11F6CFBCDB59B55BFB5B5039A3AE054D5D933000000000000000000000000000000000000000000
+
+Value = 0x5FEB82D33EB057134EAE546F547260344CA822D9DED9318150AEE82E2549DEBD2561A06C29E77F689DDBDFE25E381E82E8316CB7129E30734D38996A72783F9
+Shift = 0x5F
+Output = 0x2FF5C1699F582B89A7572A37AA39301A2654116CEF6C98C0A857741712A4EF5E92B0D03614F3BFB44EEDEFF12F1C0F417418B65B894F1839A69C4CB5393C1FC800000000000000000000000
+
+Value = 0x12F938788BBC7D18F2C
+Shift = 0xC7
+Output = 0x97C9C3C45DE3E8C79600000000000000000000000000000000000000000000000000
+
+Value = 0x66436D80FC86FF21776C5B4F62C582E87F54D7B067B5BD0F772
+Shift = 0x2B
+Output = 0x3321B6C07E437F90BBB62DA7B162C1743FAA6BD833DADE87BB900000000000
+
+Value = 0xF82C84951E0609661B
+Shift = 0xB8
+Output = 0xF82C84951E0609661B0000000000000000000000000000000000000000000000
+
+Value = 0x6A4173A90A400C0E8A1F2FF03466F492E8838743F019EBF0149E5681079B4732
+Shift = 0xD5
+Output = 0xD482E7521480181D143E5FE068CDE925D1070E87E033D7E0293CAD020F368E6400000000000000000000000000000000000000000000000000000
+
+Value = -0xB82886F5F5A972FC6248BEA3F5B6E6935F9234DCD6D662DE38CB89AB151DBDCD46
+Shift = 0x55
+Output = -0x170510DEBEB52E5F8C4917D47EB6DCD26BF2469B9ADACC5BC719713562A3B7B9A8C000000000000000000000
+
+Value = -0x344320075AFC40367C2907E552A862E46878CEB548F67C25A8898D6BFEA2035465A2DABF1F9A759B447C8196
+Shift = 0x86
+Output = -0xD10C801D6BF100D9F0A41F954AA18B91A1E33AD523D9F096A22635AFFA880D51968B6AFC7E69D66D11F20658000000000000000000000000000000000
+
+Value = 0x180F0D38B97987F35EAB73DBD7F4FC10EB96BE7D5C0959B8B065F98A64D457FB63E3341DDC3B903BE683173E
+Shift = 0x61
+Output = 0x301E1A7172F30FE6BD56E7B7AFE9F821D72D7CFAB812B37160CBF314C9A8AFF6C7C6683BB8772077CD062E7C000000000000000000000000
+
+Value = 0xC2A502857481389B835ED20720FC4771AE15
+Shift = 0xE5
+Output = 0x1854A050AE902713706BDA40E41F88EE35C2A000000000000000000000000000000000000000000000000000000000
+
+Value = 0x22946A4F246B19CE940DE1650DFD11CDA2E6311DAD222E3FD21681511691FD513E47B062BACA295EC012B3DE0FC593CABBC
+Shift = 0xA5
+Output = 0x4528D49E48D6339D281BC2CA1BFA239B45CC623B5A445C7FA42D02A22D23FAA27C8F60C5759452BD802567BC1F8B279577800000000000000000000000000000000000000000
+
+[RightShift]
+Value = 0xE2001D3DD54A53C2BE0EC9BBA26AF4205943F6E88367B35AAC9227D6D7303D3A305BF685254BC8E3D8921F
+Shift = 0x47
+Output = 0x1C4003A7BAA94A7857C1D937744D5E840B287EDD106CF66B559244FADAE607A7460B7
+
+Value = -0xB66DF12F1D32958A1CA0FB8BC5
+Shift = 0xB7
+Output = 0x0
+
+Value = -0xB66DF12F1D32958A1CA0FB8BC5
+Shift = 0xB8
+Output = 0x0
+
+Value = -0xB66DF12F1D32958A1CA0FB8BC5
+Shift = 0xFA
+Output = 0x0
+
+Value = -0x1BC9894E685B695947DF9A844A14F404A453E6D7C7C004DA11F0808A4EC47D9A9E06E91E5A4A6F9A220A2
+Shift = 0x4D
+Output = -0xDE4C4A7342DB4ACA3EFCD42250A7A025229F36BE3E0026D08F8404527623ECD4F
+
+Value = 0x14B61F50366E84EF0FA8C87842CC67EDD20DD3B2EDEF08637F831DCFE2F292FF98A257CF08ECAE109D6698D04B00DE1506A9D7E4A0E050107B5DD85
+Shift = 0xAC
+Output = 0x14B61F50366E84EF0FA8C87842CC67EDD20DD3B2EDEF08637F831DCFE2F292FF98A257CF08EC
+
+Value = -0xFC109764A4D53E1EAD685C337F70DF5D94E2CA1379FFE23263C964A85B8B19C7BBA1445876727733EACB67625C4
+Shift = 0xAF
+Output = -0x1F8212EC949AA7C3D5AD0B866FEE1BEBB29C59426F3FFC46
+
+Value = 0x19D88C299C3070616A090E7C529709612D14447D0A029A2E8A432
+Shift = 0xBF
+Output = 0x33B11
+
+Value = -0xF082CEF7E44C49DC674D3F2A1516A53F08D7BB4D26FE931FDDDCE9C4CDD8AB
+Shift = 0x84
+Output = -0xF082CEF7E44C49DC674D3F2A1516A
+
+Value = -0x1F4532AA54F61A4755DE72E3BD
+Shift = 0x5C
+Output = -0x1F4
+
+Value = 0x14E1DBB92AA6EA1E55AC85660A580ACE320B7D9AAAC941787466DBE144E37FB845DAF26F02DD8D578A92BD15EA47E39C526137FDABF7769FDDD1
+Shift = 0x74
+Output = 0x14E1DBB92AA6EA1E55AC85660A580ACE320B7D9AAAC941787466DBE144E37FB845DAF26F02DD8D578A92BD1
+
+Value = -0x1BA7A1849F7E04
+Shift = 0x48
+Output = 0x0
+
+Value = 0xAD
+Shift = 0xC7
+Output = 0x0
+
+Value = 0xFA36051EAFCA0F0031
+Shift = 0x95
+Output = 0x0
+
+Value = 0x713B97FE86653D75798958A8BE1CF2F299DE3432783601A6E0DA365C52C5930502AA04088FC17D0A4BD532897125FC0B0431BCFBE6BD
+Shift = 0x24
+Output = 0x713B97FE86653D75798958A8BE1CF2F299DE3432783601A6E0DA365C52C5930502AA04088FC17D0A4BD532897125FC0B043
+
+Value = 0x197295F9F6F0ED0F45DA6DF257BCCBA18EF04BDB7693F75BA33DD535FD
+Shift = 0x56
+Output = 0x65CA57E7DBC3B43D1769B7C95EF32E863BC1
+
+Value = 0xFF07A05DB24538D07FC527A
+Shift = 0x12
+Output = 0x3FC1E8176C914E341FF
+
+Value = -0xE49687C2917266A75DDD94604EBCCAE62455226E3DAE2E1E026193E6D53AD83A50E0FCE253E30A30C11F108FDB5AF58030186E6D469D0B49FE1F30D5
+Shift = 0x68
+Output = -0xE49687C2917266A75DDD94604EBCCAE62455226E3DAE2E1E026193E6D53AD83A50E0FCE253E30A30C11F108FDB5AF5
+
+Value = 0x2DC0C4A0B3D6609073E091ABCD856D43B6D965A366CB80BC3A56EC
+Shift = 0xD7
+Output = 0x0
+
+Value = -0xE2DA24B2713630D9B221545DDD3540BB4FA84267FAAB36B79983235CF96E3BFC4078AEB1AED7835900DF96EE04EF9954A7E3B49296E352387675857FEBC
+Shift = 0x1D
+Output = -0x716D1259389B186CD910AA2EEE9AA05DA7D42133FD559B5BCCC191AE7CB71DFE203C5758D76BC1AC806FCB770277CCAA53F1DA494B71A91C3B3A
+
+Value = 0x345B5E1B9368
+Shift = 0x40
+Output = 0x0
+
+Value = -0x894B89D9331F9DF608134696E25215FAFF7988CD44F43D062C4C8B2A4B87E2D4DB64A60E744404845F431B31AD11349
+Shift = 0x2F
+Output = -0x1129713B2663F3BEC10268D2DC4A42BF5FEF3119A89E87A0C58991654970FC5A9B6C94C1CE8880908BE8
+
+Value = 0x14C
+Shift = 0xDA
+Output = 0x0
+
+Value = -0x3A322180154456EF2DDCC5F05600A2F311FB55ED38CC04DBBDDFAD04E8299F7A53B8F2790D5950333E1633842EC6774
+Shift = 0xB9
+Output = -0x1D1910C00AA22B7796EE62F82B00517988FDAAF69C66026DD
+
+Value = -0xFB3F01BA6BF18DDBB684A7F33D673420019254DD0D8B2AC732699A8
+Shift = 0xC1
+Output = -0x7D9F80D
+
+Value = -0x23ABFF93022515162A23EF1DEA170909242
+Shift = 0xBE
+Output = 0x0
+
+Value = -0x78B1D340767E11487B9BE6197602BF05939E1C728E5CA6E58911DD29C7558640865A817C59124554AD2C6D24ADAD2AC0CBC5B25B2259C0ABEA1E55
+Shift = 0x19
+Output = -0x3C58E9A03B3F08A43DCDF30CBB015F82C9CF0E39472E5372C488EE94E3AAC320432D40BE2C8922AA5696369256D6956065E2D92D912CE055
+
+Value = 0x48BE4A30AA166D8562B4AA44
+Shift = 0xD2
+Output = 0x0
+
+Value = -0xD2FE65846C02400C0B1B58A6695259F8009C9DFA293514E860315CC670CD00DBBB86502790902B93A3744A04CE9BFCD72092D159D7E
+Shift = 0x40
+Output = -0xD2FE65846C02400C0B1B58A6695259F8009C9DFA293514E860315CC670CD00DBBB86502790902B93A3744A04CE9
+
+Value = -0xDD2A6F1FC78124B1A42DADBC536C396A516BA08530CA6E8768A7B0716142143F6C835E340602652AAE13E6
+Shift = 0x68
+Output = -0xDD2A6F1FC78124B1A42DADBC536C396A516BA08530CA6E8768A7B0716142
+
+Value = 0x59A3BCB5252C4A9FC227928FC523B
+Shift = 0x39
+Output = 0x2CD1DE5A9296254
+
+Value = 0xD49DC351115205AEB59A89FEA07FCA01544FBF4A4AC5E60E6F279AACB8A82E854DE1F65F33F3FDF99677F046FFC2584C02179654D57C634
+Shift = 0x21
+Output = 0x6A4EE1A888A902D75ACD44FF503FE500AA27DFA52562F3073793CD565C541742A6F0FB2F99F9FEFCCB3BF8237FE12C26010BCB2
+
+Value = -0x1117777A6E9658BDE591C6AD22350219223D077AD4C2201943
+Shift = 0xDC
+Output = 0x0
+
+Value = -0xC46F4A2E589D1C61FFAB8D270DE194151F9ECF4F673A44A712D4CB22097ED0C5EE22F44EB010B8B7C43DD
+Shift = 0x23
+Output = -0x188DE945CB13A38C3FF571A4E1BC3282A3F3D9E9ECE74894E25A9964412FDA18BDC45E89D6021
+
+Value = -0x2B8B4E43133842D547A40802EEF89F016855BE206DCE14134103A92872AB0EFCB65D404A150220DBA7285D16A0FC180A5356A9C025
+Shift = 0xA
+Output = -0xAE2D390C4CE10B551E90200BBBE27C05A156F881B738504D040EA4A1CAAC3BF2D97501285408836E9CA1745A83F060294D5AA70
+
+Value = 0x14E4F24EEE784021120CA263A1B7E4D04E7B4F18844A328FA054A83CB32CB0A001BADEE82
+Shift = 0xC7
+Output = 0x29C9E49DDCF08042241944C
+
+Value = -0x803920E81EE
+Shift = 0x23
+Output = -0x100
+
+Value = -0xAEAC803C060E062819953809A6467EB20A6820CA5689351731B1AE0BB8E34FD79FD80BA5E621DDF7BEFDF16D4C68174EC0480936C93
+Shift = 0x20
+Output = -0xAEAC803C060E062819953809A6467EB20A6820CA5689351731B1AE0BB8E34FD79FD80BA5E621DDF7BEFDF16D4C68174EC04
+
+Value = -0x160B67743EF96C5C323BA10C57377676881346426FC340FA930A99958A9
+Shift = 0x67
+Output = -0x2C16CEE87DF2D8B864774218AE6EECED1
+
+Value = -0x451AFEC0C20ED5A2A4F574F46FB766C00CF881383F6BFEECD6EA18FD15CCDE5A66DE9B2A6CF0
+Shift = 0xC2
+Output = -0x1146BFB03083B568A93D5D3D1BED
+
+Value = 0x4F80C1069085354E50D7B83017E5504AF02465CC07F22738CA3AF4CA20F3083093C94F1446746A97441AC763F027AEE83C0CA4440EC38
+Shift = 0x7F
+Output = 0x9F01820D210A6A9CA1AF70602FCAA095E048CB980FE44E719475E99441E6106127929E288CE8D
+
+Value = -0xC58D6456C18FAF48FA8A7D811DE78E5BD5A1CFFAB2E6501A6AA5653EEE
+Shift = 0xC5
+Output = -0x62C6B22B6
+
+Value = -0xF1ADA1C80F346B638BF26F1BF79C3FC6E291415CB01496E1AAB412EA3ABDCFBC53718C5AA
+Shift = 0xBE
+Output = -0x3C6B687203CD1AD8E2FC9BC6FD
+
+Value = 0x1EA6175FD9C8F8CC18A8673A47D9897ACD911E7F9D4ED7D1297171E7A3DD7851048FB0DDD829AA70D1922A196CB314B9C432B8E18010B3
+Shift = 0xCE
+Output = 0x7A985D7F6723E33062A19CE91F6625EB364479FE753B5F44A5C5C79E8F
+
+Value = -0xEC64FCAF91225CF00E84C1957089642BE6AEFC3CD858101E45363089555432C9B12F716A39CE52405B13D5CB9D41EF8BE0FBC0C14BD0E
+Shift = 0x1C
+Output = -0xEC64FCAF91225CF00E84C1957089642BE6AEFC3CD858101E45363089555432C9B12F716A39CE52405B13D5CB9D41EF8BE0FBC0
+
+Value = 0x3F68893912729DBAEC
+Shift = 0x9B
+Output = 0x0
+
+Value = 0x46007C61B396CC5FB076E4CDDA1994A3B6F106A4CF1
+Shift = 0x1C
+Output = 0x46007C61B396CC5FB076E4CDDA1994A3B6F1
+
+Value = 0x1E8D7B5
+Shift = 0xC5
+Output = 0x0
+
+Value = -0x1B51DF7BF8C44F8EB406FF03BE2314A27F609F0EE0DCF48B5FC9A7F
+Shift = 0xD9
+Output = 0x0
+
+Value = -0x3639
+Shift = 0x60
+Output = 0x0
+
+Value = -0x2C74CC8EB77FB260B99B22CF68FA5DE561B0F1D3D6248FD4FC9A32814AC773D5
+Shift = 0x28
+Output = -0x2C74CC8EB77FB260B99B22CF68FA5DE561B0F1D3D6248FD4FC9A32
+
+[Division]
+In1 = 0x100000000000000000000000000000000000000000000000000000000000000000000000
+In2 = 0x1000000000000000000000000000000000000000000000000000000000000000000000
+Output = 0x100
+
+In1 = 0x100000000000000000000000000000000000000000000000000000000000000000000000
+In2 = 0x1110000000000000000000000000000000000000000000000000000000000000000000
+Output = 0xF0
+
+In1 = 0x1A923B3406CBE81B093CE418F6A73107F504502B2E3D1B200762FCF6062723DE405CAB0AEA00000000000000000000000000000000
+In2 = 0x184F03E93FF9F4DAA797ED6E38ED64BF6A1F010000000000000000
+Output = 0x117D3DB34AD005954459BE9ABEDD0E5DEB4EA0000000000000000
+
+In1 = 0x38643020ACA9585367FC9BAB0D8049169F1C3F7B7183
+In2 = 0x3
+Output = 0x12CC100AE43872C677FEDE8E59D56DB235096A7E7B2B
+
+In1 = 0x119F4F0A35F4EB9A107EF0A5743816D711B8D3D69378F
+In2 = 0xD
+Output = 0x15B06147A4DEABD14F61282E18E29243C70ADD56DCE3
+
+In1 = 0xA11E405D5B086A12DFF64F0D4B25631C0FBE6C3C1FC2
+In2 = 0x5
+Output = 0x20394012ABCE7B9D5FFE0FCF756DE09F365948D8D326
+
+In1 = 0x57074977A639D9AFF8381B
+In2 = 0x10000
+Output = 0x57074977A639D9AFF8
+
+In1 = 0x57074977A63A30B741AFC139D9AFF8381B
+In2 = 0x80000
+Output = 0xAE0E92EF4C74616E835F8273B35FF
+
+In1 = 0x1427C4642AF7240C990FB083C197CF3A4C383AC1407CCD9DC7504EA1A9DC227
+In2 = 0x80000000
+Output = 0x284F88C855EE4819321F6107832F9E749870758280F99B3B8EA09D4
+
+In1 = 0x19C78AD6545D90CB8DFB4FD910251B1BF276C99786
+In2 = 0xB3CAF67425466
+Output = 0x24B4D4D3A1022312FC40FB0CFF23D
+
+In1 = 0x2A1640FDEBDA73842CF7B19B61F0F8D89AAF836250C2798CD3E0AF43FC9863A6B6BC94AA8F003EAC17E83781E9285273D7E5DE28A857BD84306CD82CFD33D
+In2 = 0x3BE860667770952B887D5B1A56937CC26B6AA0941AF0599F20BE6F55ABBB215F9391B623024B4E92C8B9B5174529E9A094924
+Output = 0xB3D8F5CB2C424527D33FE642
+
+In1 = 0x261C8EC385F6104B934409C2B4FA061EE8DB73CC9C0684C22AAFC1E0EB341291
+In2 = 0x320D4D417E520
+Output = 0xC2EDB7A2F54A6070A271E78FF0F8D709EF85517EE726CDF4A41
+
+In1 = 0x46F35C58F66F6DB728ECC04A8C1A721F1F516EC698D5B0D7CB229E575287B4D87B1131F1001EA9288A
+In2 = 0x1AF19784E4B6A33625EA4F7A9BA6C5BDC41D104D516848E119BAE2B6
+Output = 0x2A21F4DA223687CDE8BE2C6A4F8
+
+In1 = 0x2C076C243BF9E49F9A7DA27A48BDF687B98A362A4C985CCCC62D1314417DB8AD04A452BE9EB6DE3AB3
+In2 = 0x2134FC3FAA
+Output = 0x1536DEB82307BA5A1D1174E68BF94A9E249FF362B61184AC975C44DDC9F2C2EAD82E989A5
+
+In1 = 0x77C55D6FAC38455D8A8D84648FA4BCB88121D637FD5635F9E13A985D541FE09BD545FB897E38D710D6637D4E08221E9943E4D9315B0F2B3439C
+In2 = 0x2985EB7A11C8C8155A3E4E294F1C9CBC72ACDE893E1276175BB12E7EFD505A86E63E090FEEC125410F6B7A56901F0B0
+Output = 0x2E26AA7620F96DCE4F66B
+
+In1 = 0x1EB83432AFEAB82C503A3AE7D1FE2145A657
+In2 = 0x1B74132E23B88B83C49AC3B59E226ED254
+Output = 0x11E
+
+In1 = 0x292F05B8C913CE450FD5046705032AF2B4E97F9A0A4A992B22D9BB62E277425B9650147773DAB473BFB8D2B4C3FDAF68EF2
+In2 = 0x312F971B41C948DC01F583751BBD5B9B8452D9301915ABA6
+Output = 0xD659BAA5FA96F2630831645948BAE893178767A0B31578A1032
+
+In1 = 0x4ABBC62DA19EBE450C99EF70C30B5239B8FC155EB752D4210E188FC682EFB2CCAB79794D18381224520395160E67CE47E4E3A59CB57A3D43134C0A153CBC
+In2 = 0x11E737DAB5CE92C773E44A887B59
+Output = 0x42C9F96E5358F9978E2F3C314F4DD6F8A9648379787AD2EBED1D376A46AE88A0FB608FDE2F2F0DD08AFAC6ADF7A64238D
+
+In1 = 0x2FE0852D84F82D2E73FCC933E71F80A73E0D27936EC5657EAA3D8A3B3B81894379F668F6EE9E156A82F6AE720637193C3
+In2 = 0xB8CF930E2D09B07AA3FBAE257CE9A77362AE59F0D3D48BBA7AFDB8AA0EE4EE47BC715DD99B0E444F01FA6C7EE413F
+Output = 0x4251
+
+In1 = 0xA6323676EB6AA6A4E484A45C68BA886BD3AE9F24FD8405D339CF330D613B61876E177E5A81A47F67292443915ECB7CB27B9BD6799FDBCCD82C01658D
+In2 = 0x1C4615AA5D13855FB70546E02989F188D4EE3B500A9149AAED1703
+Output = 0x5E0CB691315D8A1BA26E1BEC607412F81C27E7B3D9016855910F3152F5FBC06EF25
+
+In1 = 0x3637DB115B99DAF7986FE330C2F60F1C1FB7008B797DBCACC5B52BCAFEFA10D6B1EB670E0542069E32E9CEF4E05D128015910C8E0F48BA547DE51F7DE12FD313
+In2 = 0x1A3B21A07D273FAF910E25F16BB67280487E8ED647492BC4304A4291F995A49450C6B44E6DF3FDFE81A2F16C59E36CA1E2FA782A4523EEF4ED
+Output = 0x21123C809108296
+
+In1 = 0x1468D7B66C0E9A675B3D51E03911AFE7E09FB35D8534A6794F8E5E38EE9B2D828306B8701454D76F1129504A3A80B19A2065F7A5191F9EE7AD7D201C98
+In2 = 0x2E9F1D54D78DE72C6557BC8E270748A738E2479D5B6D36F90C1FA7893F43230DE240E03BCDC867B220A4C0C7AB09EE
+Output = 0x7011BC6B1BDADE59E1E5B9B75C69
+
+In1 = 0x23D9EE1E700E1A0A33C31A9CC0332CB086315F75180931552030EEF8C9A35DED753C03F5322DFF65E90202B9453761C
+In2 = 0x360B93088CA61DDEA9AA4EB54583949DD6D45CA9F6BCA0554D41016194777ECA83915210396F6EE29A
+Output = 0xA9D1C9CED75E1
+
+In1 = 0x1747CEE3BF59D337EB9DE03F8AFCB3C0EF9812EDA996796A373A10275D16B3265D83899CDC5D53487B340806B0BBC6A0D3580EFD6E
+In2 = 0x1768A6C1F7CD208D82C5EA854F08E12C5B2A
+Output = 0xFE98D30B3AC973EC041908A962E8F596D6599A5EE2F41E0C561B20E088FD01553F9D49
+
+In1 = 0xA112BC364C0D2E6D7DDB6015F8A2DE2F3BCB7D9D020F2191E662C61453B0FEFCBB933AF7A07175264CD53C45880A7CBBCDEA6
+In2 = 0x4D7E19269CFE527D440D8CB4D846E709C06E2013D36DE59845E6BF12231E38311C5157B8CFAA
+Output = 0x2141CB2E602A21842D49A46AF7
+
+In1 = 0xD0F58C290879C932C39847FAF4207A67648D0D34203B1DD4A112ACB4D2B0F824A705CC2FFD96E0C12F283DA348B78A2D4518616553FDB97411E5A9
+In2 = 0xB972207BE27D3ED266BCE671A76A43EBF5DC8ECA2E0CD8835
+Output = 0x120758D6FC233DC23860F341F5411427755EFE35D390B94F42DE9558AB21F07D1C7501
+
+In1 = 0x1069ECB445354CF5A9DDBCC642FB8EEA6004EF6DE2F681AC4B8651966C269FAC0F8D62D3422ECA6B0C0733CE0341B9E3462A512921
+In2 = 0x355EBD92682C64CA2F2DBAF55AFF103F95E1001115E8452186818C13941628C16CD
+Output = 0x4EBB59E2A2FBAF16D00725624A9450DE8484FD9
+
+In1 = 0x18D3EA9252FC65F1DD0A7DE2EB11DDD4BA6
+In2 = 0x39E62C0C71B953C5C2BF609326
+Output = 0x6DC6956A1
+
+In1 = 0x53180BAA3E5A97A22C1D747F8FCD21EEE0E836210A7C89F5704D9992907A97A382A355B10DE5533212EF91AAACC38995A3CFBEA63448A3A
+In2 = 0x1E3D4F1EA7E6DA22922FEB802546B2382653D2DB1F4470D31C2771508814FD0652442CF232F72CB5271845446F0F6C8D5B376
+Output = 0x2BF73DADEB9
+
+In1 = 0xC042193E472757D40488972335EAC6B22FDE7BA27BCA82A98349D79C87DE30D820620E6F79664B75EEEA991CC56FCEE54E42AFA2152A4390743B34F40175D
+In2 = 0x61D7D2A94938E4CF1FCF583CA4C803920E4E29B85B5403FBC83F28B440A
+Output = 0x1F707F47101937EB82EC1F20CCCC0ECEE6E4CE9FDC14764A619923141282889490A
+
+In1 = 0x2CC0F67F9EBE05FDE1DA7AA112D58C9CFB3671A62C72F19F04C82E901CAD91117E8F79055D8EF34F617DF87C3B752146B392ECE01DC67F229E95C2A34B5
+In2 = 0x1CB9FB25CF40C4DA882E3880AA8C05CBC2C966A7A1747E10A704CE51A809CD4CBBB07293013F5D89559E12081A27C
+Output = 0x18ED44788218404336AB090CE854EA0
+
+In1 = 0x4FAA3BFE1958B338AB22EE7843C3CB4F5855F09994958BC83E01889D42050552AFBFD049198401C426F03EE8340A390DDEA9A6743FB23DFC
+In2 = 0xB3459A764A20C8FADF99C3789E
+Output = 0x71C2EFFF66072DF507D9E6BD92DF077842EA28B3A41CB8385D751E0B37191F4BF27425D896535007F994F0
+
+In1 = 0x1C61703693CE50464424022B5DA3E8A615A77CA2B0F5168FDA4C9DA0979BF1741D71A2A937F2EF842ED9AF749
+In2 = 0x3982AA34F975DE88C6C687EA10
+Output = 0x7E5523DAAD238C3E40BD11827830E2A43F9B7120C20EE5B666315F00D35024F
+
+In1 = 0x3262F9708D2474DE0DFC64FCDC788DFEE77D9DAB4C462AB8BDFA0E493C165A4EF754BE8578B2E30530C702
+In2 = 0x2410F8CA80D2A5559717F91AEF9A07736B6D1842EA5C2349E7618A3266026B2A1353FC9C1E91F1CDA9EAD8998CD014E04D252
+Output = 0x0
+
+In1 = 0x2D4AFB1CF50DA7B860942F42B7D3226E3D0131B54E501EBC6243
+In2 = 0x7C29AFBCC87C548A3BB554CF3B560A2F718
+Output = 0x5D62A17758C3DB650
+
+In1 = 0x123F71E77499975C79EE4C4F7B275A4410863CEDC3E244724D5AF83A8A2DD73C5D5913E9EAAB3664A182C424A21
+In2 = 0x78B294AD98589FDCC2D53FCB0FC9F0E70E4E30323832D5669F66E15
+Output = 0x26B426C03F76F97048D5DE0B8D9DBD02F4DC
+
+[Modulo]
+In1 = 0x9
+In2 = 0x7
+Output = 0x2
+
+In1 = 0x7
+In2 = 0x9
+Output = 0x7
+
+In1 = 0x2261331
+In2 = 0x3406DE
+Output = 0x1DCE85
+
+In1 = -0x5
+In2 = 0x7
+Output = 0x2
+
+In1 = -0xE
+In2 = 0x7
+Output = 0x0
+
+In1 = 0x0
+In2 = 0x1E8D2D00
+Output = 0x0
+
+In1 = 0x0
+In2 = 0x1E8D2D00
+Output = 0x0
+
+In1 = -0x1E8D2D00
+In2 = 0x1E8D2D00
+Output = 0x0
+
+In1 = -0x23BFD0990E34C4
+In2 = 0x1D
+Output = 0x0
+
+In1 = -0x5
+In2 = 0xBE38C5D
+Output = 0xBE38C58
+
+In1 = -0x8
+In2 = 0x7
+Output = 0x6
+
+In1 = -0x7
+In2 = 0x7
+Output = 0x0
+
+In1 = -0x6
+In2 = 0x7
+Output = 0x1
+
+In1 = -0x5
+In2 = 0x7
+Output = 0x2
+
+In1 = -0x4
+In2 = 0x7
+Output = 0x3
+
+In1 = -0x3
+In2 = 0x7
+Output = 0x4
+
+In1 = -0x2
+In2 = 0x7
+Output = 0x5
+
+In1 = -0x1
+In2 = 0x7
+Output = 0x6
+
+In1 = 0x0
+In2 = 0x7
+Output = 0x0
+
+In1 = 0x2A4E282493E8C041BFCFD375ED5924B8D68C120E1CE0BC3465997F2F8AC33CE5216521BD35E20EE5B9D26B973388480A0C5A003942CC6DA85DD4DFD8B
+In2 = 0x84D5D161F78E97D98585836FE912A3795AA58DACB5B
+Output = 0x197AE594643E817C634C8794AF9B76DB02BFAFA2B69
+
+In1 = 0x1A5BE98A2D712E25B94F634859714B
+In2 = 0xB9BFBE360FA4EE3D1AE1E1D389899E4793F9311EA6
+Output = 0x1A5BE98A2D712E25B94F634859714B
+
+In1 = 0x381C7C4C0034D95CDA4D7A3DAC384544C36AFE4C0E4B6B44454AB99399132DD12FA99D2F5D788C
+In2 = 0x784586F5713EBAB503A5
+Output = 0x5187C976436B2161C929
+
+In1 = 0x35D
+In2 = 0x6341A1F8572C7FCDCD9A35E293
+Output = 0x35D
+
+In1 = 0x1B25908A724DD9AC8
+In2 = 0x6761AFD189EED4897D0EC650E7A991387E08D6C93F9FA2F1F82A199D87B3E56F9495C11E04962781A46D510C176244166A9A5F29
+Output = 0x1B25908A724DD9AC8
+
+In1 = 0x324DB51EB03558BFC598BAE4E9FEE42C447B8C0B92A51
+In2 = 0x76ED7E7C0C68AF8C3AE54
+Output = 0x24F0AF8CFA1163A3A7D1
+
+In1 = 0x7A9B406D9A4B4D87E70AE11CBBF7A4EFAF0B38635BCC422BF34F3686A32E7FDDCABFCAE48B18EBF2A2CD0FDD45B34D753E85D89A529A45C56AFA
+In2 = 0xC0E2A4C6B748B37D817CEC40BF01299CE574E1CCC0CA126267340EAB9AAE686B89052
+Output = 0x7870A16EBAB941FBDA4A1749D0E2C941326F43D38E92DB128C5DB96C9363460956374
+
+In1 = 0x30A7C6392C4AC6F1BE87F8CCDA5A64CCE13CC4405A18
+In2 = 0x1C889B7AB36165D55ED5FCA40FA9EE559B2DDC94FA386E5F05CF1CC910F5627D7EFDF7325FDC873DB205E141AE50964A7EF35EF82C4D58B01D
+Output = 0x30A7C6392C4AC6F1BE87F8CCDA5A64CCE13CC4405A18
+
+In1 = 0x36DA73B4B2D7ADBC8A7A27D88E5779A635A8628E8DD9BBEA04F5E109162F658C89D8C13CB16FF9BBEAA09479
+In2 = 0x37
+Output = 0x8
+
+In1 = 0x2C736E692A4DA93DF58B4CB781C3F0C3659
+In2 = 0x3506FA2167819E3738BDE7CD533448B1AD6B075EA904D9F5CC5BC1BD17275
+Output = 0x2C736E692A4DA93DF58B4CB781C3F0C3659
+
+In1 = 0x4040E116526FD4449A68BBE5AC53CD9C50E36E52BE659ED61
+In2 = 0x8E14582730A5E771870DCBEED2187142D476EF203C83811FE1E3D66F6
+Output = 0x4040E116526FD4449A68BBE5AC53CD9C50E36E52BE659ED61
+
+In1 = 0x35CF035F1AC16BC3C6642F9C43CF3B8B61712E9E9685EA2233CA5CD5D6DCA1ECA3B533C67697823
+In2 = 0x43B1D15F6914EADA8601792C97635EC325BBA0F4805
+Output = 0x40425D111DF2C6F95E8D91AC3CECC1FEA32B8AF4672
+
+In1 = 0x31ADA3A5C325E4ECA4BF9D86E3370BCF32A6E6783021DF2D7892874EEA76A5DDA4C90368EEE8D4132872198B29A45B5B
+In2 = 0x2BC153FAE33429DB4630A9
+Output = 0x1477783F9D2644A98D6BA5
+
+In1 = 0x1A6DE4C010FECA8DD719C9949FD4C9EBCD58C753EF31517F7D99C35
+In2 = 0x3F655EC40C3D908C4CFC35A96E51C3B85010578C656402A4D7963BCF71D70630BCE37448A184D56D820B1870DCDB292D6B0139D0653BF4BC
+Output = 0x1A6DE4C010FECA8DD719C9949FD4C9EBCD58C753EF31517F7D99C35
+
+In1 = 0xC34264A2C65A7E1295F587DFC08FFC
+In2 = 0x3C158C9E4D1C05D4A158A0D860BAB
+Output = 0x3BDB46A30912B7CD3AB072E0C3CEB
+
+In1 = 0x6CD4C4A9AA91F9D20BE5535BEA
+In2 = 0x2886BDF02B32BC09AC6A6B1D3BB633B6CB5A742F9516C8B4B3F17B012F19B75F98655FBBA00BDD447E3869AA06A558C9FFC4E99CDBAA5
+Output = 0x6CD4C4A9AA91F9D20BE5535BEA
+
+In1 = 0x3F61B265AE5064462BBAFCAE2FF391AC941403068A3079B04D9F5BCF2E4AE42D2B17925968779F93B11DC1E090540E25E711AA73C1
+In2 = 0xCA30FC37EDFF148449E735C314CC428ECD7DA899A3B1A6E493F56DA69499C0EEC
+Output = 0x9D047BD22108F1403FFD114B80BAEE69D05EFA3D72A9EDD65737E8A5568241D2D
+
+In1 = 0x57AE837700D4CB592771FDD80
+In2 = 0x4FDD3F88F7E97407842A3696E676356
+Output = 0x57AE837700D4CB592771FDD80
+
+In1 = 0x3C875D742770EAF61FAF5618D3B50953B5DE5A7A743
+In2 = 0xED529449DA23D1D89A42228F1A6407A8146923894AB1459A4780F7ACA7207015F184
+Output = 0x3C875D742770EAF61FAF5618D3B50953B5DE5A7A743
+
+In1 = 0x1330F0F55812F77E076CF7F7B23FDA6EA8EA72EBF1C3EB020084BAADD93E9
+In2 = 0x6C679459B7A75135B6BE3DA6686590DF0E735202751DD5772E6A29C44B686FAFC7F
+Output = 0x1330F0F55812F77E076CF7F7B23FDA6EA8EA72EBF1C3EB020084BAADD93E9
+
+In1 = 0x2B4DAD5D1AC8900057EB7FC530A27671B76EDA0480EAA44EF51A
+In2 = 0xF235C6D2F1F2219F503BE760BB404CBA857C5DFB6E95E94999EA353FB82BD82CDF1F7ED1121FF1E1
+Output = 0x2B4DAD5D1AC8900057EB7FC530A27671B76EDA0480EAA44EF51A
+
+In1 = 0x4C801068F41CB7559BB59D93072
+In2 = 0x283269A4E71EECB7BD9EFABAF69C3304ADB784C61888D2D7DE669D64199C9A39DEFBDEBE02CB75C062888B691CB66DC275E2988E63636649C9FBBDDB8850156
+Output = 0x4C801068F41CB7559BB59D93072
+
+In1 = 0x1435711E75AB8C0A2F6A4006C9A289298D9FD0C497B0C83B928677E5C0EBF6E422E7039793
+In2 = 0x82143F9E049C38452EC91
+Output = 0x1B77DFB3F3FA00D5D7BD3
+
+In1 = 0xFBEF3DFE8C1F6CF626D9
+In2 = 0x1BD7622A7438950EB60F0C5F015CA7A0181504B6418026FEFE339DEB2AC3C5369CA7DF90DFF59F9705AB7686879E
+Output = 0xFBEF3DFE8C1F6CF626D9
+
+In1 = 0x200893F161539F78251C88FC
+In2 = 0x8E413E9CE
+Output = 0x6310EEAE4
+
+In1 = 0x3F6DCA9603E629D35ECC84EEF17B085AB583AEB1F62C6F5447F6F9C5E88DA6C7FAF15E7DD808D13754D526C651AD2107B05039A77C287C439EF58887
+In2 = 0x23304FFD222EFBFAB5CD320AA3D750F505727CB54235DDBE5D5A02FC508B04533BD3D0DC02CCD7379A89C03FE012B465
+Output = 0x2041CA9D0DDA3B3A333377296801D220260E8E9DB138DE40A491E46D0D53EB14BCCD9A051267BAB158371779373FB8AC
+
+In1 = 0xD0E2C9E95EBCA60722A070B823F521A964
+In2 = 0x93EA1ACE369B39DD253492823C4F8858E62E3CA88EAEC2A5C254DD147F6B55035D77C984130
+Output = 0xD0E2C9E95EBCA60722A070B823F521A964
+
+In1 = 0xB40F6E5C321DD06770A72F1C13932120A130A238C9D1B80D2B069A084C36CDF846345C704234EFBACC0ED6F79A001
+In2 = 0x44B30B27BF28C1BFFAF2
+Output = 0x35602611D3A62D94F337
+
+In1 = 0x5AD40A06D6D80591BD9285D9641D3E4DA612F34E3A3E207A0CF4B91F56B109A19CFBB073D
+In2 = 0x2DFD79588352CC98991A46AC0584E64BA55848B2017018C271B25F6D62CB3920D0C2995C0D4DE4A6683B4275B048C
+Output = 0x5AD40A06D6D80591BD9285D9641D3E4DA612F34E3A3E207A0CF4B91F56B109A19CFBB073D
+
+In1 = 0x2E076E4F899FD12FADF37286F92FED6A7BBE7171
+In2 = 0xBDFA2612A8FA10E1E5B7BAB63EAFA6C8ACD1BB7410DBD3B3C2BA537699628AD77CA8E21D9302FF78BABA36E16
+Output = 0x2E076E4F899FD12FADF37286F92FED6A7BBE7171
+
+In1 = 0x2723DCB53EBFE695D3E173733DA80D12482255E46AF95130A3DE28405C16B4243911D9F6D1C08CA5A3
+In2 = 0x21196029
+Output = 0x734E7BF
+
+In1 = 0x5C0BEC752AB52E1E967B6D0317F10B0BA76A2EB86E562D9FB59E2
+In2 = 0x397F5DEBC49E2A8C70D65E5240C60911
+Output = 0x16FAAF0D8839ADFE3B65ABF4E2638D88
+
+In1 = 0x50DFE538B59BE3AAED8769
+In2 = 0x2
+Output = 0x1
+
+In1 = 0x1576BBE1F040D4C5293C26F3D9DD
+In2 = 0x2B2ABFB0BE86EFCD75A75FB
+Output = 0x1A328B8A12B2E86BEB00911
+
+In1 = 0xDB956956207CC553042CBB576078699179E8FC390A3EA34BCF1BFBDB479D52233ABB71533056B6347B6993DBE9F57553EE61A4E0A
+In2 = 0x2
+Output = 0x0
+
+In1 = 0x30DCD7CE05C38C1487894BD5BE1B3228386B14A2ACC30C
+In2 = 0x62000B450EC7560FF7336647B82AD34CB25D97081D33BA45EA26D88D529C1A341C25
+Output = 0x30DCD7CE05C38C1487894BD5BE1B3228386B14A2ACC30C
+
+In1 = 0x7856EF78E91BF
+In2 = 0x1335F67FD20FC2D09E7294E7FB48ABF5F96BB357E7A2EEC0C9F4AE418340819675F716C786D89925CB2E8CC7F6B8BDF0
+Output = 0x7856EF78E91BF
+
+In1 = 0x55BE14CF1F90117C54D7D4476AAAD726F256A50BD5B40489CAB787365A4B7D67F1923F113A4095871061CE730C9DA9F6FC4
+In2 = 0x6F2D20B075BCDB6EAF4192E6191201BB0493DF8C6C519208B9C252
+Output = 0x2809E9E9F70DFF2FFFF7C921E5D946B43CFA4ABA1C6584387F7FDE
+
+In1 = 0x57A76F3D623AA8D890FDE3578D44160CEC548245949D62BA308E99DCFC8D8655B5751218AF
+In2 = 0x3AF04038D497
+Output = 0x21F9246B33A3
+
+In1 = 0x31388A950A23886231EACCD8BB47E606AEF3F0FB37BDA88C6206EF8B18D1CEE889D87E94FB86F62DF1C386
+In2 = 0x18AEC3439E0
+Output = 0x1347FE86C26
+
+In1 = 0xB2612136E5B946C4F5A30F32C36532BA0CC360833AF7E86FC0E70
+In2 = 0x3E2BCA81EE33B31D196463EE520ED5A4C242DF645FA2D4D2E5C4CB4D8D925663C618F
+Output = 0xB2612136E5B946C4F5A30F32C36532BA0CC360833AF7E86FC0E70
+
+In1 = 0x32622690F0E39C8C73459EEE1518E9DC3A8CBF7B61EFD0857B915
+In2 = 0xA2789271A3049043FD6BC089F70E10E52B21C6FF5C53CEEFBD96C04312619A3CD234B67
+Output = 0x32622690F0E39C8C73459EEE1518E9DC3A8CBF7B61EFD0857B915
+
+In1 = 0x64A0249BEB74CDA60EDDAE0B4899ACC4DC5ED672E1BC9A820A2BAD095EB5D10B6DE59F49725CFF7132B594834731581398269E61D338F3ED5CA8E6BB6EBFBEC
+In2 = 0xCA55E1E1FA32DA8D5DB3D511276B92DFEDFBC70C2FD6C985A1D770D8436CC58D42A8703D5ACACAB7FD2148A40CDA8479D7CB0586A34E
+Output = 0xC68D2BEA911B6841D9AECFB98F6D0AE8DC92641E6DAB6EC6FD446EAFE74204E130B024E8DC74553C75B47704F91866A428FBC634D8CC
+
+In1 = 0x14D772D895E6CE2E8A9505D25BA65BD931FEA121B465CED036491638BB86B031DDA389748AD722156EA66849CC43A2FD42459EF6
+In2 = 0x6
+Output = 0x2
+
+In1 = 0xDADA69C24686EA2393C127121A12C275FCE8E2EED58E84ABB90D7A6BBFE2BD8AC51F5D0BAE3F273200564C1A61168865FF7344DCF1D970CADEEB2E8
+In2 = 0x55D421A2FB76A699B5DDC3CE2427D8953E58F32DDC47F2E61973A8F066C7874C93A0EF8F179E10E563F4A398147
+Output = 0x37C6097CE62640A1CA0C78B50B6C067E38650009F004609B356DE53AAAD714268D6CC6B2B56F58DAA7BDFFEB078
+
+In1 = 0x47F36D12BC7CABB1331D34E84515D5975728DD
+In2 = 0x2E57F04FBE70CF2D175E34F7C583C0E15B8B946EC567AD59B8F2CB2665410A0B91025B5F731A8CA260D992265D530F90EEA41FAC03B515D4B7D10B151A0
+Output = 0x47F36D12BC7CABB1331D34E84515D5975728DD
+
+In1 = 0x18962EF4CE1D7BF49682495D47DB840AAEAD25E0CF28D6C1395F25A09D2485F5CAACEA88DA7E756108B6B6409
+In2 = 0xA4A4338EF6919AEA9E
+Output = 0x80A82C6CD5ADAAEC3D
+
+In1 = 0x6183E904BA8
+In2 = 0xFBFECABEB11F0D3E79F3A1E0F8CC955427BFF6EF75279542071C5AC5ACA56E282439E6D6D873
+Output = 0x6183E904BA8
+
+In1 = 0x6365BDCC94EEF7691EFA970D21816FA75E00D908673E85856715B7AE4843AFAC296D79BD5CF128F9EC3F860F40F6369EF61027DD
+In2 = 0xCEAC6335411BE409DE14350881AFC55DA16DD60E2DDC1D6DD3548C4BE3B32933DF0DE7A0A7CC2986E05F8EE10FD4BE30C1153EEEF2DBDC46AF
+Output = 0x6365BDCC94EEF7691EFA970D21816FA75E00D908673E85856715B7AE4843AFAC296D79BD5CF128F9EC3F860F40F6369EF61027DD
+
+In1 = 0x1303523812A77
+In2 = 0x147DD1D9D7364410D783866DDA9195059F1F7F3630352D1C38387668431DD12F83CAE962F13583D0C1023E9B93C3A142EB1081135D963F8DC6ADF629B3DF3
+Output = 0x1303523812A77
+
+In1 = -0x1B50EB5449F45B22930B8A14B346E499DBE0946107F3C1558E21029C4FF46AAECC71666823947E898E2CFAA80D84F558B83FD1FA117858326D4D4A3D5DA0D59A5662316FC70512323BE83EA1767DCE52393B2B16B8A8D53287036D2D61E659B13165B3CFB44B1059AD8DF575FA65C20FE5613F1F0C27F3A05A922DBA856E2EB8
+In2 = 0xD32737E7267FFE1341B2D5C0D150A81B586FB3132BED2F8D5262864A9CB9F30AF38BE448598D413A172EFB802C21ACF1C11C520C2F26A471DCAD212EAC7CA39D
+Output = 0xD0DD7834F118FE11F3F27D938D153D2843CB2CADB9FA28BA1AE784808DAAE4E915B47E10884383350ACD1690E1CA12C3F92C56A95434D11BD615E3225A2AAE9C
+
+In1 = -0x184DCE99E95ED3337B516B39BFDBAA8320562AF079102030166F7CE4A176E71B5FC501B1F2759D8AEEEFF1BC52D441BFB7B0D26B6FC9FB9C2C3C00F526DF965B
+In2 = 0x962EDDCC369CBA8EBB260EE6B6A126D9346E38C5
+Output = 0x3CCD9C977A3248C5FB141B3F0EF3ACA391B3914B
+
+In1 = -0x40147F79DA93E8D3F21A11E66D2F08F445BABB7AB7C3C2EF1B94312E6CBF347DC65831F7C49EE202F8E6F77233FB3EF7E462D5E4D3C81DA2CBC9335F9B1A7F51
+In2 = 0x962EDDCC369CBA8EBB260EE6B6A126D9346E38C5
+Output = 0x34889A4853583C9FC0163C085D8B74A1
+
+[ModExp]
+Base = 0x1
+Exponent = 0x0
+Modulus = 0x2
+Output = 0x1
+
+Base = 0x2
+Exponent = 0x67
+Modulus = 0x96
+Output = 0x8
+
+Base = 0xF53
+Exponent = 0x17C
+Modulus = 0xFC1
+Output = 0x1
+
+Base = 0x5EBDAA
+Exponent = 0x86CA74C
+Modulus = 0xAB17B43
+Output = 0x4760F28
+
+Base = 0x8466D0C17
+Exponent = 0x67CA63635
+Modulus = 0xCAAD20657
+Output = 0x4484225E9
+
+Base = 0x7DF406A87
+Exponent = 0x508DF4A9D
+Modulus = 0xFD2785061
+Output = 0x16FAB14EE
+
+Base = 0x153014C3EDA6813C33
+Exponent = 0x3F015
+Modulus = 0x107A2F9D441C723BD789
+Output = 0x1511E0BE0F7631CF62
+
+Base = 0x2
+Exponent = 0x400
+Modulus = 0x77E8F1591092967F286A46030CCDE683
+Output = 0x4C2C52EB1054E501720FDCC043CEB086
+
+Base = 0x2
+Exponent = 0x1000
+Modulus = 0x43729A4BE70
+Output = 0x466BDEBE40
+
+Base = 0x2
+Exponent = 0x1FFE
+Modulus = 0x81E644685F4B7EE718F2E18F84195651CBB7B27
+Output = 0x3EFEF820185A68AEC5F04D44FA3B0906721CD1A
+
+Base = 0x2
+Exponent = 0x10001
+Modulus = 0x1B63761AFCD7F89A44714FB1ADDFA28668B5808ECAEDFC5930FE44965503F5B517D0430C9612BE6FC1E4EC2275F0FB6A05F729AC0B
+Output = 0x175E1C5F2E9B222B6F98898B694DEB7D5F0549130A24850B7A1B4E78D3CC6B791C1F8F2F7934DBEADC3DBAFE3F91A21E7D563269C3
+
+Base = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+Exponent = 0x5000000000000000000000074AED6FE50A167FD03000000030000000000000058ABD6FE4C24510367A7E36EECF121FF58ABD6FE186725FF0000000067A7E36E4C24510304CD23FF2000000000000000000000001B98192F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001
+Modulus = 0x18000000000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
+Output = 0x11A0D334E187609000A94A5C70A9BE6023C0E37127FB8CB79DD822C3D9969692CA8241937C6A5AE6F818B16056838E58702C4081908C35FA33D9380F2A91B9C943CC8930337EFAA6D146B26030FA7B3FE07D5ECFE08B9F5D0DB25439AC232DED14CCC30CFE06D389B6D9A1B7B9EA0BB1B8A5D3CA15F3006A0D232A3F7CE1C3E9ADE55965C75A896D2F1EBF45E3C3A28D368412AED6E90C0D4E71D882197AFD52C3D22C8ED705AC096E55E3D6EE1E5A6E91C7C0175377E4094589D65201507D6EC493D9B5D807F720CF029EA958EE5B33656DE875E973AC607F9F93E687582A5104DF8FF8EBE247B4B27EA37AAB82989CCEE5126D49D6A9886A8EFFCA57379890504D04FD4D79F539C6D0ABCC44C851EAAC381CACA826487A56D0FDA8824BCC86F96A04C34A07B024B0E1186F2ECE5E24420619836D110AA9C23A917F7978AE9839
+
+Base = 0xDF2F1FE817
+Exponent = 0x61FC837F5533B6E7B2EE3F52AB56F5C0589498D2D4B71A7A671167C770C04
+Modulus = 0xDA22C7614016834D35447546DE13EF75CD9FC5DB3C1C288E2AAD327C1CADDB
+Output = 0x467902F517D87B73F3E80886FBAD58A2EB5802357332E5E5F2A29A3AA65225
+
+Base = 0x3E1
+Exponent = 0x5978AD6F0C41D9E6A18E639644703285F96C10C679486F4D548B82624EAE11
+Modulus = 0x6E8E5805A00D7013542D3E31F8A52B0591C09CD8C8267DB275A667329BC931
+Output = 0x2B31F1B1C994C95C92261D2BF3798E95BC4B3CA33ACD8622622CA200B6F6FB
+
+Base = 0x16CD
+Exponent = 0x1412029F7
+Modulus = 0x74FA74286E240E3DF02A518674E31B66AA1ABE2038C311C437802BD2C4DF30E9
+Output = 0x5B3617148E895F7D63F3216FFE940197D3A564EE652A1B7EE1F84EEC7D84F016
+
+Base = 0x2E2C
+Exponent = 0x329A5581DDF9C439EE1D22B176255CB7AA672728CFCEA12F531D9889ABEF
+Modulus = 0x19DB2CD3ED192BDB3BE14B52A22078F4AE69448B22FB3C47B803A2535B3F762D
+Output = 0xAC89E841A0426615B950D0C1CE728E85717E6BF49E9A2BAAC4514E9CC8A6BBD
+
+Base = 0x138615
+Exponent = 0x2127B4E1C672A6EF82093E16728A170D8A99E179ADE1344572888D783E52
+Modulus = 0x567E4E7DF343DF0314D70D9C43635E4CA8D9FE41BC3901C8EE05C4A4F479
+Output = 0x4F775AAE8BABA7A2AA1A91CA86FC8EC9315F26443D0952F64CECD24B768F
+
+Base = 0xA96CAEE6F99D9055DDCC9A67E1AAACCCBEB40D2AFA23565D2AAD14A0E696
+Exponent = 0x247
+Modulus = 0xC34845CD0DA4F10377B4C6E5A4623C8EE57203AD6115781D3C5923E974F5
+Output = 0x8EF8B5D459374F77917BF2A7313839A48E2431D19B298338A589CD8EBCED
+
+Base = 0x1675F91BEA439A713EB30C74808BA9DC66ACA3434F174D2E5FEBBA71AF65CB
+Exponent = 0x2D2B8E04C242812E51B344CC0C2A98237007F9ACD0DE78DC468A9CFF2D49BA
+Modulus = 0x5F35406DFB34FF909E03EAC32CB6DB15E5CEFA0E59E988865FF1252A58DDCB
+Output = 0x5CC3F888B0EE4B4FE58BFA4DB22C208E263D160A61D7525E0BA1A96A6F89D
+
+Base = 0x16424C11E95C77C77A2BDAFC609AFE148
+Exponent = 0x1234184727EED9852361FAFCAC391BFBE
+Modulus = 0x1A16EB76865E864137D7C72C34A3FA2DB
+Output = 0x151AE807B0CE712C115FEC5951E7E9F0B
+
+Base = 0x12051528C4525101CF07EC5E3FE9EF476
+Exponent = 0x3BD6BA22DE280B77FAEDD1A70CE82C2B68BD
+Modulus = 0x6E34D5DB17775C0817A89867EBF663ECFA79
+Output = 0x65A6609E9463D28CACEA2E0C8557B93DE15
+
+Base = 0x2FB5C95D5702990E91A7F439800C51988530BFB
+Exponent = 0x81721C65F5D8F9C6206549E5C8606509
+Modulus = 0x4A98FB939327EE13C11013A1C352F4C047A9D0B4B874D7B387D6BD795BF73BE778A92C5297BAB409F3A14DC993197
+Output = 0x1CEEF3177FFD9880EC503660284939B934A122CD5E92880B36B5E86B7D3D7A6C327FE047CCD74FEA3D444F4340FF7
+
+Base = 0xBF791361D54005F624FEB32A5EECAFFD2243C3088F8945569ACE8E0E0D0B00489B4ADA19F5967B82A098DB97
+Exponent = 0xA9F22D3362DA654FBA8F884C4B386ED27D5F419684B8D56C5C95CBE65C05AAB9EA74D8EC41C0D79FC089A86F
+Modulus = 0x101F513C66DFB89F1ED0D03E0ED1F2FA3FE1AC6B86DFDB352D2B5979154D2C22C763101997DB94E91D777B3B7
+Output = 0x79998AC2C00348A5C5C166D5948805AFC5F4B7A85C14312842830FF93EC7B678CC59E21DAD6C531BA5E2142C
+
+Base = 0x2D76D19D8AB4D88E3C1D0286DCE731C4BE9CA39BA0A329256A2BFBC9F6994A061424FCD955AB996196F8BD0DE0344
+Exponent = 0xC428A6F75C999585FBBC7CF9F6926D71D30DEEC76886FEEDF49CCB0D95FF46101C217551278455BD26675CD50E0
+Modulus = 0x796AC6B1AF58EB618DB5C07DF2901A45B07E36FF5AB7E2F531D8F21A337BE4750617CF632BC6360A0B7A9219D3089
+Output = 0xCB92647CAB4D0ECDED534799957780D7617C3EC6C9834B2A829A13CC0E861EFC3529B056CC9FE05CE52F96B851F2
+
+Base = 0x1EE84446B082ADEA57DB1981FA4615E5F3
+Exponent = 0xE20B04652F017DC01EBC1C57E6FC598E9E
+Modulus = 0xFA7C9F013AFC6FBC7E4A1F3EAF8DFABE8F3DE9292A4E8CCAB4621DDB24E20E25E8289E3D79B484643B1E9ECCC74E79
+Output = 0x70D1913C72834BAFDBBBCBCF7A856DA47D1277359A668891D2022E3DF4A723A8D10ACA7C7D5FF3021EAAF5DD34B02E
+
+Base = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+Exponent = 0xB69B09104B6014D160140841309969A4
+Modulus = 0x8DFA80DF945656CAF186B302053E2F1CE6642A2CEC217CC4FB3714CE0EE5E3D11EA777115F24F3F53EEC9A1A18613
+Output = 0x8CC7007D059A8C83BD42518EB540E1218BE0E0F1AAC1687F31A0D1472E16F379C7C1CE0096AD5FB47501426DDBE1A
+
+Base = 0xAB155850CDCF1D13A6FE80EC25C8D17A4F5
+Exponent = 0x280A08AA00A220AA002A20A0800A0008AA2
+Modulus = 0xB0AF5E718307F0F558FF91A5DC7578F9E2D
+Output = 0x9907A436B00B46A54D393E428D2B42E742D
+
+Base = 0x40147F79DA93E8D3F21A11E66D2F08F445BABB7AB7C3C2EF1B94312E6CBF347DC65831F7C49EE202F8E6F77233FB3EF7E462D5E4D3C81DA2CBC9335F9B1A7F51
+Exponent = 0x2
+Modulus = 0x962EDDCC369CBA8EBB260EE6B6A126D9346E38C5
+Output = 0x51ADA2F6C0DD379DEA6F45A50B91E9A7A3481EA6
+
+Base = 0xFFFFF80000000000
+Exponent = 0xBFE01FFFFFFFFFFF
+Modulus = 0xFFFFFFFFFFFFFFFF
+Output = 0x8735B122788A46DC
+
+Base = 0x70000000FFFFFFBF02
+Exponent = 0x1FFFFBBFFFFFFFC002
+Modulus = 0x800000000000003FFE
+Output = 0x609529A3F5345D0A1A
+
+Base = 0x3D80000807C000180F
+Exponent = 0x7E037FC10007FFFFF80E
+Modulus = 0x80007FFFFFF8000007F0
+Output = 0x24F01062C097A00AE0C1
+
+Base = 0xBE0000000000000007FFFF
+Exponent = 0x7000FFFFF800200000
+Modulus = 0xFFFF8FFF000003FFFFFFFF
+Output = 0xD34CC02D9BBB5F1B3FD65E
+
+Base = 0x7F7FF007FFFFEFFF00000079
+Exponent = 0x8000000000000000003FFFFC
+Modulus = 0x807FFFFFFFFFF000FFFFFFFF
+Output = 0x3A298451F401ED3F361B3E83
+
+Base = 0xFFE0000FFF80003F00000000FF
+Exponent = 0x7FF7C00200
+Modulus = 0xFFFFFFC00000000000003FFFFF
+Output = 0xCAEB2FF794C6783C4F1F06E684
+
+Base = 0x7FFFF8FFFE00FFFBFFE000003FFF
+Exponent = 0x3F8FFFE00FFFC00000000006F
+Modulus = 0x8000070001FF0003FFFFFFFFC001
+Output = 0xCCAC1B86140C6F650017FE6993A
+
+Base = 0xFFFF000007FFE00000000003FFFFFF
+Exponent = 0x8000000001FFFE0001FFFFFFFFFFFF
+Modulus = 0xFFFFFFFFFFFF0000000000000000FF
+Output = 0xE6E68CFB5864CC3EC011E84DAD071
+
+Base = 0x7EF80009FFFFFFFFFFFFFDFFFE00020
+Exponent = 0x81FFFF000000003FFFFFFFFFFFF3FF3F
+Modulus = 0xF8007FFF8000000000000000001FFFE0
+Output = 0xBF5C09CB4AAFFE50A5598A04E403D9E0
+
+Base = 0x7BFFFFFFBFF7900003FFFFFE
+Exponent = 0xFFFFFFFC0000000007800003FFFBFF
+Modulus = 0x800000000003FFFFFFFFF87FFFFC000001
+Output = 0x1729F5569C1B022EBDF418F5A084D6D069
+
+Base = 0xF9FFFFF000000FFFFFFFFFFFFFFFC0000000
+Exponent = 0x83FFFF000000000000000003FFFFFFFFFFFF
+Modulus = 0xFFE007FFF9F83FFFFF8F000FFFFFFFFFFFFF
+Output = 0xA917797602DADCC854BD67D27E86BB1D6575
+
+Base = 0xFFFFFFF1FFE001FFFFFFF80003FE003F000000
+Exponent = 0x8003FFFFFF80000FE7FFFFFFFFFFFFFFFFFFFF
+Modulus = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFF07FFFFFFFFF
+Output = 0x36682C1F5E90D6D5712AC9FC7B481712F4869E
+
+Base = 0x800000000000001FC000FFE0000018000000007F
+Exponent = 0xFFF8003FE0007FFEE07FFFFFFFFFFFFFFFF
+Modulus = 0xFFFFF000000001FFF8000E000000000000000000
+Output = 0x668BDB42A0C65BF8FC180536CE5E3F7EFDFBF7F
+
+Base = 0x3FE7BC00000FFC3FF000000000008007E203F
+Exponent = 0x7F80DFFEFFBFFFE1FFC3FC000000000007FF7F2000
+Modulus = 0x80000001803FFFFF003C03FFFFFFFFFFF80000E000
+Output = 0x4497E331510C7847F3B94C2895DB2CB27A56F0E001
+
+Base = 0x8007F8001FFFFFFFFFFFFFF80000000007FFFFFFEFFF
+Exponent = 0x7FFF3FFFFF7F000000FFFFF0403FE00100000007FFF
+Modulus = 0xF80000000007FFFFFFF00000FBFC01FFF00000000000
+Output = 0x309851910F469EAC10CE2C89DD67AB75C8CFF7000FFF
+
+Base = 0xFF81FBFFE040000000003EFFF07800000078400000000
+Exponent = 0x7DDFFFFFFE0403FFFFFFFFFFFE878001FFFFFFFFFF0004
+Modulus = 0x8000000001FC00000000000000F87FFFFFFFFFFFFFFFFF
+Output = 0x5CF3691E622CEA16CD28273AB3D4F9D33FCC54A97E85C2
+
+Base = 0x6000000000001FF00001FFFF00009FFFFBE09FFFFF7F8001
+Exponent = 0x8000FFEFF003FFFFFFFFC00000003FFFFFF0000000000000
+Modulus = 0x9FFFFFFFFFFFE000000000007FFFE000001FE000007FFFFF
+Output = 0x8E4EF10E5B661384C8BA9ECDE5AE104E02D9C7EF486AD30D
+
+Base = 0xFFFFF000000030001FFFFFFFFE0000000007FFFFFC0003C000
+Exponent = 0x8000001FFFFFFFFC007FFC007FFFC001FFFFFFFFFFF8003FFF
+Modulus = 0xFFFFFFFFF3E00000000000707FC0000000000007FC0000001F
+Output = 0xB8690A8A111DB3591C6B02D9D3463448AB37422D531FA3077B
+
+Base = 0x1FFFFFFFFFFE0077FFFFF01FFFFFFFE04000000000001FBBF10
+Exponent = 0x1FFFFFFFEFFE0078000FFFF000FE000000001C0001001FFBF0F
+Modulus = 0xFE00000000001FF87FFFFFFFFFFFFFFFFFFFFFFFFFFFFE0040F0
+Output = 0x4C1881916DF2041653435A6308B2CB25776897D3819AF96FF0A0
+
+Base = 0xBFFFFFC000003FFFFFFFFFFFFFFFFFFFC0000000000000000000FF
+Exponent = 0xE007FF7FFFC07F00403FFFFB0000000400007FFFF000007FFFFFF
+Modulus = 0xF1FF80000003FFFFFFFC00000FFFFFFFC000000000000000000000
+Output = 0x64443A290825E9F4273313C7645C19A4AA3AD639630B06FEFEFEFF
+
+Base = 0x800000000000001FFFFFFFFFFFF8000000FFFFFFFFF801FFFFC01FFF
+Exponent = 0xFF020000000000000003FFFFFFE00000000000003FFFFFFFFFFFFFFF
+Modulus = 0xFFFFFFFFFFFE00003FFDFFFFF801FFFFFFFE0000FFFFFFFFC0000000
+Output = 0x2BC072CD65F3E361FEC49EBA9DEEE19FF78B478A881BCB81BC3FDFFF
+
+Base = 0x7FF1EFF0000003FFCFFFF000000004000003F000000003FFFFFFFC7
+Exponent = 0x7FFFFF1EFF87FFC03FFC007FFF8000023DFFFFFF03FFC00C3FFFFF7FC8
+Modulus = 0x800000E0FFFFFFFFC003FFFFFFFFFFFFC0000000FFFFFFFFC000000038
+Output = 0x6D1FE72839A39A6E282F75B2EC5C2CC1D17A10360D55752AB329E4C4E1
+
+Base = 0x1FFFFFFFFFFFFFFFFFFE007FF000000001FE0000009FFFFFFF81FFFDA
+Exponent = 0x3FFFFFC0000003FFFFFC001F7FFFFFFFFFF80FF007FFFFFFFFFFFFFA
+Modulus = 0x80000000000000000000000000007FFFFFFFFFFFFFFFF800000000000006
+Output = 0x47656C2ADD3BC161766375765531FCF58EA1C0FDA475E72B820FD9601234
+
+Base = 0x800000000003FFFF800000FFFFFFFFFFFF00000000000007FFFC001FFFFFFF
+Exponent = 0xFFC00200000000000FFFFFFFE000000000000FFFFFFFFE7FFFF801FFFFFFFF
+Modulus = 0xFFFFE000000000007FF80000001FFFFFFFFFFFFF00000003801FFFFFFF80FF
+Output = 0x74CD627EB2CD33AB6736FB5C029829E0D244C7F253DDB5707A6112871CE0A0
+
+Base = 0x7FC40000001F9FDFFFFFF9FFFFA03FFFFFFBFFFFFE803FF801FFDFFEFF80007F
+Exponent = 0x800FFFFFFE3FFBFFFFFF80000001FFFFF8000000003FFFFFFF800001FFFFF800
+Modulus = 0x801FFFFFFFE00000000007FFFFE000000000000001FFC00000002000FFFFFF81
+Output = 0x44262BD7BA76592D178007849E1A6943DE5F4126BD7D146AC772673FA896A101
+
+Base = 0x3FEF8008200FFFFFFFF41000000007BFFFFC00000000000000040000000C3FFF
+Exponent = 0xFF3FFFFFFFE00000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0600000007FFFF
+Modulus = 0xFFFFFFFFC0007FFFE00000000007F000000000000003FFFFFFFFFFFFFFFC00000003C000
+Output = 0xE2D9F1BEB4A2377627FEE48CAF7E8A60AC1B23FBC7643D730B04E084005DA545FB1B3FFF
+
+Base = 0x80000000000000000001FFF0007FFC3FFFFFFFFFFFFE00003FFFFFFFFFFFFFFFFFFE00000001FFFF
+Exponent = 0x3FF78000FFF000004003F803C000000000083FF8200FFFFFA08FFCFC01FFFFFFE3EFFFFFFFFFC43
+Modulus = 0xFC007FFFFFFFFFFFFFFFBFFFC3FFFFFFFFFF80000000000003F800303FE0000000000000000003FC
+Output = 0x4E7350C0D263B3A8923534935AB64BC9914DD861609EAF082B32D0C9903374A76955F06FC75FAD7
+
+Base = 0x80003FFFF800000003FF0000003FFFFFFF003F0000000000000FFFFFFFFFC00000000000000000000001C000
+Exponent = 0x807FE00000000000000000000001FFFFFFFFFFFFFFFFFFFFFF00000000001FFFFFFFE00001FFE00000000000
+Modulus = 0x8FFCFFFFFFFFC0000007FFFFFFFFFFFC001FFFFFFFFC07FFFFFFFFFFFC007FFFFFFFFF000007FFFFFFF0001F
+Output = 0x12679788B2C8B8C0D09EFBDE858EE1235270B2373F27B1D811A45CAF6FBBC3BBBA35C99149F914FCF2ADA660
+
+Base = 0x7FFC077C000000001FFE3FFE0000041FFBFFFFFFFFFFFE00000000000007FE00007FFFFFFFFFF80000000003FFFE785F
+Exponent = 0x7FFFFF7FFFFFFC001FFE4001FC0004007FFFFFFFFFFFFDFFFFFFF0000007FE3FFFFF80FC1800000800000003FFF60040
+Modulus = 0x8000007FFFFFFFFFE001C001FFFFFC0000000000000001FFFFFFFFFFFFF801FFFFFFFFFFFFFFFFFFFFFFFFFC0001FFC0
+Output = 0x592094A5FDA8387B13A317EF896ED8E1E8AA3C36B4E5E7E5334845376489521DAF768B1534495D171A0DF85507F61801
+
+Base = 0x803000000000007FFFFFFFFFFFFFFF000000000007FFFFFFFFFFFFF00000000000000200007FFF001FFFFFFFE07FFF0000000000
+Exponent = 0x8000000001FFFFFFFFFFFC7FFFFFFFFFFFFFFF80000000000000007FFFF81FFFFFFFF0007FFFFF00000003F001FFFFFFFFC00001
+Modulus = 0xFFFFFFFF87FFFFFFFFFFFFBFF801FFFFFFFFFFFFFFF70000FFFFFFFFFFC007FFFFFC0000000001BFFFF000000000000000000000
+Output = 0x34D2AFF1DB9A1F67F6B4083C47C2828ABA440DD14A21EDBBF20DF1ECE3EBF1684D8607322B086099A2D000000000000000000000
+
+Base = 0x801FF81FE000000007FFFFFFFF8000000000001FFFBE3F8000000000000000000000001FFF0001E0000000007FFFFFE07FFFFFFFFFE00000
+Exponent = 0x80001FFE000000000000040FFFFFFFFFFFFFFF80000000003FFFFFF000001F8FFFFFFC1FFFFFFFFFFFFFFFF000000007FC000000000001EF
+Modulus = 0xFFFFFFFFFFFFF00000FEFFFFFFFFFF07FFFFFFFFFFFFFFF800000007FFFFFFFFF8000007FFFFFFFF80003FFFFFFFFFFFFFFFFFFBFFFFFFFF
+Output = 0x2139C366F0120E75AEABF87E75832BBB066455130867492F3CF6D188A7F858E30B2AA920EF5BCB318950364A2DF2ABC756556DCCB2FFABDB
+
+Base = 0xFFFE0FFF00000000FFFFFBFFFFE20003FFFFFFFBFFFF0183A00000010000000003FFFFE0000FFFE0FBFFFFF800000000FC000000000001FD
+Exponent = 0xBFF800F80000000E01FFFFFFFFFFFFFE00003CFE0FFFFFF1FFC001FE00100003FFFFFFFFFFFFFFFFFFFFC1FFFFFFFFFE0000000000000001FF80003F
+Modulus = 0xFFFFFFFF0001F000FFFFFFFF00000000001E000000000000003FFF003FFFFFFF00000000000000000000001F03FFFFFFFFFFFFFF03FFFFFFFFFFFFFF
+Output = 0x7727F4911C00336A497E651066ABDEE569D82E38513549E2A9CAA96E76F2B4528C37372B252CCFA5E590BC97ABDF318261371A3031FD80EB8DD3DDD4
+
+Base = 0x802007FFFFFF80007FFFFFFFF00000000000000000000300000003FFFFFFC00000000000000001FF8001FFFFFFFFFFF800007000003FFFFF80001FC00007FF80
+Exponent = 0xBFFF80000000FFFFC00007FFFFFFFFFFFFFFFFF000000000000000001FFFFFFFC07FFFFFFFFFFFFFFFFFFFFFFFF9FFFE000000FFFFFFC0003800000039FFE07F
+Modulus = 0xE001FFFFFFFE7FFFFFFFFFFC1FFFFFFFE000780000000000001FFFFFFFFFFFFFFFFFFFFFFFF0000020000000000000000FFFFFFFFFFFFFE00000000007FFFFFF
+Output = 0x82B649F8FC9C264B6C7B66430D72C5173A41993637EC20787D76441E256F75601F7B10BCB1D04EEAE8758295996FCD5BD245E76FBCF5690F35732713065C8A2
+
+Base = 0x7C0000007BFFF017C3FF800001FFFFFFF0007FFFFFFFFF7FF8FC02000000003F7FFF8000020FFE00003FFF7FFFE801FF7FFFFFFCBFFFFFFFFE3FFFFFFFFFFFC000000000
+Exponent = 0x3FFF8007C01000FC400000000FFFF800000000000FFFFBFF8FDFFFFF800003F860000000200050000401F7FF80801E0000000FC37FFFFFFFE401FFFF80FFFFFFFFFFFE0
+Modulus = 0x83FFFFFF83FFFFF03BFFFFFFFF00000000000000000000000703FFFFFFFFFFC07FFFFFFFFE0001FFFFC0007FFFF8000000000003C000000001C000000000000000000000
+Output = 0x6BB8DDCA44AB7AB7F8366A6D5609F6E0355CBCBA00187267A6A38B58C00DBBB867AE93D1FFED34149713400FF717AADF21E07D3AAC73276759C000000000000000000000
+
+Base = 0x807FF9FFFC003C000000000000F0000001FE000001E003FFFFC00003FE0000000000000001FFFFFFFE000000007FFFFCFFC0000001F8003F80000007FF8000000060007FFFFFFFE0
+Exponent = 0x800000000000001C0FFFFFFFFF0000001FFFFE1FFF000000000000003F00000000000007FFFFFFFFE00000021FFFFFFFFFFFF80000FFFFFE0F0000FC00C0000000000000000000FF
+Modulus = 0xFFE00000007FC000007FFFFFFC7FF800007FFFC0007FFFF800000FFFFFFFFC000300000007FFFFFFFFFFFFFFFF80000FFFFFFFFFFF8000000000007FFFFF00003800003CFFFFF000
+Output = 0xEB1D27428AC4C0CC2D15DA2AD8CB20494BE894AF70BB7C27315DD2B307F254FE25EE95B0E144B41D34DB252CD79E87CF01736208F22AF16252D08B5328764B5091C901B7B496B000
+
+Base = 0x8000000000003FFFFFFFFF83FFF00000000000000007E1FFFFE001FFFFFFFFFFFFFFE000007FFF801FFFE0000000003FFFFFFFFFFFC0FFFFFFFE000000000000003FFF00003FFFFF800FFFFF
+Exponent = 0x3FE007FFDFFFFFFCF017FFFFFC0FFEFFFF1FFFFFF0003FFFFEE0FFFFFFD003E000000000000FFFC0000FFFFFFFF007FFFFFEF0803FFFFBFFFFFC0200003FFFFFFFE0007FC000021FFFE00001
+Modulus = 0xC000000000000003FFF0000003F0000000FFFFFFFFFFC00000FF00000030001FFFFFFFFFFFF0000000000000000FF80000000FFFC00000000003FFFFFFBFFFFFFFFFFFFFFFFFFE0000000000
+Output = 0xA85809BCE693852116D4DA77C8AE85A370644796496A5A76241DFB3352C15C39BB421D6C22742030292E0EAA139C911A30717AA86905492B5B51BC74E731F049283FC32D432385FF800FFFFF
+
+Base = 0x7FF9FFF1DC0803F800363C1000380000031E000000007FFC1801FFFFF8000001FFF1FFFFFFFE7C080005FFFFFFFFC000400000FFFFFBFFFFFFE200000000006FFC00000807FBFC000009FFFC1FFFFFFF
+Exponent = 0x7FFEFFF1FC07FFFFFFFE3D000001FFFFFFDE07FFFFFC80000001FFF7F8000081FFF6000000027C07F001FFF80007C0403FFFFFFFFFF800000002000000000003FC00000007BC00000002003C1F000000
+Modulus = 0x8000000E03F800000001C3FFFFC000000001FFFFFFFF800007FE000007FFFFFE00060000000183F80001FFFFFFF83FFFC00000000003FFFFFFFE00000000000003FFFFFFF803FFFFFFFE0003E0000000
+Output = 0x698DC6CF7802014D6822BD83019B061421DA654DDC2ADBCE67266FE57EB3A7508F856F54EF9AFF1D4FF6D36D1B654131CC18B1B5DB275EBFEE085BE640FF656EA1598A5D1090A790FAF5FAF7E0000001
+
+Base = 0x80001FFFFFFFFFFFFFFFC00001FFFFFFFFFF007FFFFFFFE00000E000000000FFFFFF0001F80000000000FFFFFFFFFFFFC3C0000000001FFFFFFF0000003FFFFF80000007FFFFFF0000FFFFFFFFFFFFFFFFFFFFC0
+Exponent = 0x83FFFFFFFE007C0000000000000003F8000000000030000001FF80007FFF801FFC00000000000000000000007FFF77F803FFFFFFFFFFFFFFFFFFFFFFFFFF83FFFFFFFFFFFFFFF00000003FFFFFFFE00FFFFE00FF
+Modulus = 0xC0003FFFFFFFC0007FC003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3FFFFFFFC001FFFFFFFFFFFFF800000000007FFFC0000000000000003FFFFF800000003FBFFF0000000003FFFFFF83007FC0003FFFFF
+Output = 0x597C0682DF9AAD7775F93C4C9405EE5CBC971E4BDC69A332A0B55D1FDDAFDBAF48C58ECE105F5CBB46C680CE0841375F3E7BEEEA324337329A82458E746459AA34DA0F1FB597DF2DD9CC67FE6AD635CFE9A7119F
+
+Base = 0xFFFFFFFFE0001C000FFFE03FFFFFE0000000000000000FFFFFFFFFFF80001F801FFE1FFFFFE000003FFF800001FFFC000000FFFFF80FFFFFFFFFFFFFFFFFE0000000000007FFE000000001FFFFFFFFFFFFFFFE001FFFE0FF
+Exponent = 0xFE0000000007FFFC0000000000000FFFFFFFFFFFF07FFFFFFFFFFFFFFFFFF0000000000001FEF003FFFFF0000000003F00000000000043E0000000000000000000021000000000000003C00000000FFE00000FFF60000FFF
+Modulus = 0xFFFFFFFFFFFFF80000003C00000007FFFFFFF800000007FFFFFFF800000007FFFFFFFFFF1FFFF8000000000000000000000001C03FFFFFFF8000000001F8020000000003FFFFFFFFFFFFF800001FF000000407FFFFFFFFFF
+Output = 0x3435861A22F99DCC3CBA79B8AA4E9DA0CD0F2429AF34FE6D1F3FC23206D43454941DF8AF56DA5EAB218C670B9077C649425901757456404A0071F6535A8CDFDCFC8E4E4A13D2F01D994E0C0D463B15D5E4950A8CE9B9AD3C
+
+Base = 0x7FFFFFFF01FFFBC0000002000001E001FFE000007F87FFDFF00000000003FFFFFF80004001FFFEE00013FFFF7FFFFF000000801FFFDC0000000FFFFFFFF003FFFF000080006FF1FFFEFFFF800081FC00FF81FE8001F80400000FFFFF
+Exponent = 0x7FF7FFFF41FFFFBFC00001FFFFFFFFFFFFE000007FFFFFE3FFFFF8020003FF00778001FFFFFFFF00200FC001FFFEFF00000FF81FFFE7FF8FFFFF819001EFFFFFF004007DFFFFF0FFFFFFFF8000800000000000FFFFFF0200000FF1EE
+Modulus = 0x80000000FE00003FFFFFFE0000000000001FFFFF8000001FFFFFFFFFFFFC0000007FFFFFFE0000FFFFF00000000000FFFFFFFFE0001FFFFFFFFFFFFFFE0FFFFFFFFFFF8000000F000000007FFF800000000000FFFFFFFFFFFFF00000
+Output = 0x61125975FC3F157468F5490517DD7E946E70E726E9BC6E6E08ACE1D290659A99AABC330800905ADF82426B2B29319136519135DF5F3E0AE9C361A7140F9180F80BE7E08EFC35C430D3DE040928CDCD91BB24436F8B6064788E00001
+
+Base = 0x8000007FFFFFFFFFFFFFFFFFFFCFF00000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFF800000000007FFFFFDFFFFFE00000000000007FFFC000000000000000007FFFFFFF0000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8000000000
+Exponent = 0x1FFFDDFFFFFFFFF9FFFFC3E00407F800BFFFFFFFE001FC0003E3E200007800000FFFFBFFFFFFFFFFE0002020000003FFFFBFFFFFFE00004000003E7FFF000000000007FFFFFFFBC00000423FBFFFE000001FFE002399FCFF7E3FFC000010000
+Modulus = 0x800001E0000000007FFFFFFFFFC000000000000001FFE03FFFC1FE1FFFF80000000000000000000001FFFFFC000000000003FFFFFFFFFFFC00000018000FFFFFFFFFFF8000000003FFFFFC1C000001FFFFFE001FFFFF8000000FFFFFFFFF0000
+Output = 0x3257A23017477DE2FAE3DDEDE992B98E9D42A5F87D276844E0F8D36DA9FA64F9BFEB2E0B92D46ECF69ABA882BBF0C004EC83306B0EF7D8B19340600542178696E5C07A064F2637EAED3EE690A4F92CF271888F7A65430C05EDFF76A820660000
+
+Base = 0x8000000000007FFFF8000073FFFFFFFFFFFFFF9FFFFFFFF00003FFFFFFFFF0000E00000FFFF0000800000000003FFFF0001FFC01F80001FFFFFFFFF000000003FFFFFE0FFFFFFFFFC000000FFFFF8000000000000007FFFFFFFFFFF0000000000000000F
+Exponent = 0x7FFDFFFC0000000100000001FFFFFFFC7FFFFFFC0000000000000003FFFFE00000000003FFFFFFFF8001FFFFE0000007FFFFFFFFF0003FEFFFFFFFF000000000000000021FF803FFFFFF8003FFFFFFF800000005FFFFFFFFFFFFFFFBFFFFFFF800000001
+Modulus = 0x80000003FFFFFFFF000000000000000380000003FFFFFFFFFFFFFFFC00001FFFFFFFFFFC000000000000000000000000000000000FFFC0000000000FFFFFFFFFFFFFFFFE0007FC0000007FFC00000000000000020000000000000003FFFFFFFFFFFFFFFF
+Output = 0x49558820C1AA22D9A9B960465DD0A20AA00BD38A7653E2ACBD17DAB86A7A99822BAB2A4CEAA2E545FDD8F47E1E8CD833D00D3D30DA929F5EF08BB759C18E420A4D6A3EBF1A3E5CBA83325C5566A53B4EF4E28EAC5156CE971A27FE07FA511531D4C8BAFA
+
+Base = 0xF0FFFFFF80000001FFFFFFFFC0000001FFFFFFFFFFFFFFF00FFE000000000001FFFFFFFFFFFFFFFFFFE000000000FFFE00000000C00001E00000000000000000003FF8000000003FFFFFFFBFFFFFFFFFFFFF00000000000DFC00000000FF8000000000FFFFFFFFFF
+Exponent = 0x18003FC7FFFEE0F8000087FC00007FFFF000003F7FFFFFC3FF980001FFBF8100000000001FFF00007F7FFFFFFFF03FFFFFC1FFFFFFF900000000FFFFFEFE0021FF80FFFFEFDF7FFFFFFFFFFFEFFF017FFFFF00000FFF800000007FFFFFFE800FFC1FFF000001
+Modulus = 0xFFFFE7FFC03800001FFFFFFF8003FFFF8000000000007FFFFFFFFFE7FFFE007FFF000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFF80000000000000FFFFE00000000010018000000000000FFFFF800000000000007FFFFFFF800000007FF003FFFFFFFFFF
+Output = 0x415F1FC7F724E22C8D0D62C121A370926391185B1B9F4D269DC4CE54DDE6F9BBC8745E9566E84B383303BC5D8B0635EF07595A2FDA8FCA8D5092C8C043BF696DE33BAA8B4E18B72D1C060448853D5CDF505FCCF6F67C868C06F1802372CD1008E89D704EED6D1CBA
+
+Base = 0xFEF00003FE000009FFFF8400000007FBFFFFFF001FFFC000F000800000000FFC3FBFFFFC1FFFFF0500000002FFFFFFFCFFF08000000037FFFFFFFFFC0000040003FFFFF3FFC04003FFFFF7FC03E00004FFF83FFFFFFF8403FB0000008000003FFFFBF83000800003FFFFFFF
+Exponent = 0xF0F83FFFF00000060000040000007FF400001F00000000008000000200000FFFFFBE00000000000100007FFEF8000000FFF00FFE3FF057FFFFFFFFFFF8007C01047FFFFE1FC03FFFFFFFF80003DFFFE100000001FFFF87FFFC0000000000003E0003F800007FFFFFFFFFFFF
+Modulus = 0xF00FFFFFFFFFFFFF9FFFFFC0000000003FFFFE0FFFFFFFFFF7FFFFFFFFFFFF000003FFFFFFFFFFFFF00000000FFFFFFFF000FFFFFFFFFC7FFFFFFFFFFFFFFFFFFFC000000003FC000000007FFFC1FFFFF000000000000780003FFFFFFFFFFFFC0000007FFFF8000000000000
+Output = 0x97A1AD196C092A892424299EB9A809AB0EE8E37608DC0AAFBC8200BCCDA199DA462DBA595F5A324C861AAADA659309445BF1E8BF453CCDFE6E1BF9FEC585E00510D5E33AA2D2EACCAF84A2E8A450D26A8CE033BA26737AE99AEB05DA876E7C77741D73C5FD77FFFFBFFFFFFF
+
+Base = 0x8000000007FFFFFFFFFFFFFFFFFFFFFF87C0000008000000003FFFFFFFFF0000000000000000000000007FFFF7FFC0007FFFFFF007FFFFFFFFF00000000007FFCFFFFFFFFFFFFFE0000000FFC7FFFFFFFFE3FDFFFFFFF000078000000000000000000000000000000000000000000000
+Exponent = 0x3E001F401F21BFFFFFFFFFFFE07FFFF8000000001FE7FFFE7F000003FFFFFFFFC0000001A000007FFFF20FFFFFFFFE0000003A8BFF81FFFFC40000001E40007FFF7FF00F800007FF00016FFFFFFFFFFFC0000000000047FFFFFFFBFFFFFFFFFC40FFFFEFE006801FFF000008E00F7E1
+Modulus = 0x80000007FE0FE3FFFFFFFFFFFE0000007FFFFFFFFE000000000FFFFFC00000000000000001FFFFF80000FF000000001FFFFFFC384000000003FFFFFFFE0C0000000000FFFFFFFFFFFFFFF8000000000003FFFFFFFFFFFC000000003FFFFFFFFFFC000000FE0007FE000FFFFF81FF07FF
+Output = 0x4F73952642495B9507F00515C47AC6131DC2272D6C88975A1D97F61C2F0D6688A42FFBC3237D76D1F025CB36F5DE4FB5DFA1BACD5AECDFDB048D2418DDA7166C26CF7965E652A6965279357B8910A281DB85DBE34659AA2E2E74D76FE2B6627F8B6180A5E7BF16D1C821D17DB7CD208F
+
+Base = 0x7FFFBFFFFF1FFD007FFFFFFF7FFC003E0000080003C0000001FFFFFFFFC00000003FE01FFEC0401FFFFFFFFFFF3F0073000801C0007F03FFFFFDFFFFF937FE00083FFFFFFFFFF803FFFFBF87F00FFF7FFFFFE000013FFFFC0000000000C0000006FFF800013803FFFC0000008000000FFFFFFFE0
+Exponent = 0x7F7FC00000001C017FFBFFFF7FFC003FFFFFFFFFFFC0000001FFFFFFFFC0000001C000007FC0400000000000003EFFFFE400003FFF80000FFFFFFFFFF8380000003FFFC007FFF803FBFFC007F00FFF00007FC00000400000007FFFFFFFBFFF80087FF8000023FFFFFF8000000800000FF3FFEFE1
+Modulus = 0x80003FFFFFFFE3FF800000008003FFC000000000003FFFFFFE000000003FFFFFFFC00000003FBFFFFFFFFFFFFFC0FFFFFFFFFFC0000000000000000007C7FFFFFFC00000000007FC00003FF80FF000FFFFFFFFFFFFC0000000000000003FFFFFF80007FFFFBFFFFFFFFFFFFFFFFFFFF00000001F
+Output = 0x2A083ABCCA20B39FB4A4CA6F70151794CC449B50A1862364FFFB853DE70612CE8BF5E61AA5B3DA192345D334133C4B2FB7B434A5AD57FC39A001F2AEDA04BC470EF7A023041C578D524B19D3EEA8B8DE36F155AEC9688C56873A33FCFD00F3B1C63B6B81231C99BE347618C32A5DF9CAF10B7BEB
+
+Base = 0xFE00000000003FFFFFFFFE001FFF01FFFFE00000001FFFFF01E0000000000000001E0000000000000FE00000000000000020000000000000001FFFFFC003FFFFFFFFFF1FFFE0001FC0000000001FFC00001FFC0000007F8000021E0000000000000007FFFFFFFE000018000000000000000FFFFF00180000
+Exponent = 0x9FFFE07FF8000000038FFF800001FFFC0FF001F0007FFFFC00000000000FFFC00781FFFFF9FFFFFFFFFFFFFFFFFFFFFFFFFFFE0000FFFFFFFFF0000FFFFFFFFFF00FFFFFFFE000000FF00000000FFF00007FFFFFFFF00FFE007FFFFFE00FFFFFFFF000000001FDFFFFF3F007FFFFC000000FFFF000000001
+Modulus = 0xFFFC003FFFFFFFFFFFFFFFFFFFFFFFF00003FE7FFFFFFFFFFFF8007FFFFFFFF800000000000000000000000003F8FFFFFFFFFFFFEFF8000000000600000003F001FFFFFFE007FFFFFFFFFE000007FFFE0000000000000000000000007FFFFFFFFFFFFFC0001FFFFFFFFFFFF800000000000003FFFFFFFF80
+Output = 0x67B0F58BDC821EEF185E3E96BF7DD8BCCD5FF00480E11DDBB15F36A02BF7484EE25902D19C85E2196FC711E93173584E1828CCFE58B074DBB51D5796F32DF1332C12F51F10CD826E0303905436E36CA182F6F143303583221D0EC7B7CE21982698AF751EE94BC77951773110BDA27DA2D14E17BEF6C0AA80
+
+Base = 0x8003FFFFFFFFFFFFFFFC1FFFFFFE0007E00200000003FFFFFFFC0000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFC00FFFFFFFFFFFFFFFE0000FC00000003FC000003FFFFFFFC00000000000000FFFF0000007FFFFFC0000000001FFFFFFFFFFFFFFFFFC01FFFFFFFFFFFDFFFFFFFF000FFF8000000000000
+Exponent = 0x800000000001FFFFFFF800000001FFFFFFFFFFFF9C000000000000000001FFFFFFFFFFFFFFFE0000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0000000000000000003FFFFFFFFFFE7C007FFFFE000000FFFFFFFFFFFFF0000000000001FFF80000000007FC001000FFFFFFFFFFFFFFFFF000000001FFFFFFFFFFFF
+Modulus = 0xFFFFFFFFFFFFFF8000000FFFFFFFFFFFF000000000000001FFFFFF800003FFFFFFFF0007FFF000000000003FFFFFFFFFFFE00000000F0000000000000000FFFFFFFF0007FF800001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC000000007FFFFF7FFFF000007FFFF000000000020FFFF0000000000000000FFFE
+Output = 0x15271EF5EE0756425952443C324591DE1118E7ADD7BFDAB99E20E3CD7C900A678952F3311152E727F93934E29FF191CFBF930AD162FF75A6E673C85241B8C0022FE27A408FBE90DD8BF5D5D6402E8475E81848617A1D0C5FC28D21B727EADF055829003C2B3745F4DBDD5FDD39AD920CF507583E2FCD42C7A88C19C6
+
+Base = 0xBFFFFFF02FF7FFFFE02007707E000010003FFFFF7F80003F01FFFFFFE207FFFFF00001FF60400003F805FFFF8000003FFBF310001FFFBFA000000FFFDFFFFFFFFFF00007E00000080000001FA08F00000007E0001FFFFFFFFFFFFFFFFFE001FDFE0000000FFFFE038000400000000000FFFE007FFFFFFFFFFFFE00007FFF
+Exponent = 0x7DFFFFFFFFF01FF800000000086FC0000000005FFFFFBF80005EFFFFF07FDE09FFFFFFFFFFFDE04001FFFFF00003C00000003BFB00FF2007BFBFFFFFD0001FFFFFF006000007E000000780000027A0100007FE0000FFFFFFFFFFFFFFFFFFFFE001FDE00000004E003E0380003FFFC0007FFF800000003FFFFFFFFFFFC007FE00
+Modulus = 0x80000000000FE007FFFFFFFFF80FFFFFFFFFFFC00000007FFFC0FFFFFFFFE1F80000000000001FC00000000000000000000003FCFFFFE0003FFFFFFFF0001FFFFFFFFFFFFFF81FFFFFF87FFFFFE01FF00000000000000000000000000000001FFE01FFFFFFFFF00001FC7FFFC000000000000000000000000000000000000000
+Output = 0x2F21EFB919A951E4F325D4653F72E1B31D22DD769BF247B99770ACAB0A54899E96F455F8B4DD71D08F26E12BA176A177B24508DE41413771580AF2FC8E09A1AAE93679F3BF2130B517A60AD32E5FE1AA52F25FA1BC0FFE0CA4558AA93A5649E4C2AEC93F50BECC9889807BA8DC330419A4634029174FB6B36CCF9C3C01000001
+
+Base = 0x3FF7FC7FFFFFFF0007FFFFFF1EFFFFFFE000000000080FFFFD8001000007900000000378000010000000001FFFFFEC7FFFFE000117FFFBFFFFF8000000021C0003FC500800FFEE08003FFFFF780013FFDFFFCFFFE00100000001EC0000007400401FFFFF87DFFC00000080007FFFFFFF7FFFFC000047FFFFF0003A0000000FDE10000FFFDFF80FF9
+Exponent = 0x47FFF0000000003FFFEF0FFFFFFE00007FC00080003F780017FFBFF8800000003F7FFFFFFFFF8000020000FF40000000001000003FDFFF808000001FC000001F00000FFFE00003FEFFF900003FFFFDFC00000008FE000023BFFFC00000000200000000003FFFFFFF000800007FFFFFFFC00003FFFFFE80043FFFFF10016100FFFFFDFFFF801
+Modulus = 0x80000380000000FFF8000000FF0000001FFFFFFFFFF80000007FFF0000007FFFFFFFFC07FFFFFFFFFFFFFFE0000003FFFFFFFFFF00000C000007FFFFFFFE03FFFC000FFFFF0001FFFFC000007FFFFC0000003FFFFFFF7FFFFFFE03FFFFFFFFFFFFE00000000003FFFFFFFFFF80000000000003FFFFC000000FFFC3FFFFFFFFE1F00000001FFFFFFF
+Output = 0x556890D25FAF8D55EDF0C9D7AFC96CD36A37D59A0D8866CF70A26CBD12D4DF43E4130E4955082C554BA53426BC35C6F76334FD3EC66AA01B18C89D8EF6E628E20B3A2B5792AC6917DA513563BE8C50A6922C681A9BF758101622AE0BB725C258E3F9FAD614592277769E6B68313CF7951C5375639A22BC08B12FD31D300BA83229D9F3FE13361C8E
+
+Base = 0x3F0003FBFFFFC180000000C00001EFFFC00004703E01FE3FFFE0010000007EFFFFFFFFF0007F0003FFFFFFFFFFC4007FFFFFFFFFFFFFFE7FFC000000000001FFFFFC1FFFFFFFFE8000003DC087FFFD8000000000000000000000007FF0000000FFA000007FFC00800000000003FF7FFC000000021FC0F6040001FD8107FFFF7E000000000FFFF9FFFF8002FA3FFFFF80
+Exponent = 0xC001FF9FFFFFFFFFFFFFFFFFFFFFC00000000000000000000000383E0000000003FE1FFFFC0FFFFC0000007FFE00000000000000000000000000007FFFF0FFFFC00000FFFFFFFF0007FFFF000007FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000000000FFF00000FFFFFFFFFFFFC0007FFC00FFFFFC0000000007FFF00FFFFFFFFFFFFE0000000000000000003FF
+Modulus = 0xC0FFFC0000003F800000003FFFFE0FFFFFFFFF87C1FE01FFFFFFFF00000000000000000FFFFFFFFC00000000003FFF7FFFFFFFFFFFFFFF8003FFFFFFFFFFFFFFFFFFFFFFFFFFFF800000003F8000007FFFFFFFFFFFFFFFFFFFFFFF800FFFFFFF003FFFFFFFFFFF800000000000000003FFFFFFFFE00007FC000001FF0000007FFFFFFFFFFFFFF800007FFCFFC000007F
+Output = 0x440AD9D7B67E2A01D133B413EDC27C5D0477ADC9E6ED9E36F39CF7823D497750672AC3A8561F88EDA807F7B07DFB2405325745F8E82B689352530BD635AF25A11B08B1870AB6EEE0D88B8FEA34C2C9362F894118436520A2378F4F1AB626A8714CFBA97BD94BE43F9AB08F15B306F5A7B41B8215DE236AD044DFD3D23419EF722C688F54C998B2A1714D6B6C92F75654
+
+Base = 0x7FFFFFE00FFF7FF0003FF04FF80001EF8000003FFFFC003A000F803FFF80022FFFC27FFFBFFFFFC0000000000000082FC007FFFFFFF1FC009FFFFDFFFFFE03F05FA080FFFFFFFBC07FC0FE304000E00EFF04006F0000000000000F1000001FFA0000000005FFFFBFFFFFFFFF00000FF0FFFFFFFFFFE3F02E20000038003FFF0001FFFFFC0000000FFFFFFFF80007FFFFFFFFFFFFFFDFC010
+Exponent = 0xF0100200000000FF80001EFC000000040000001FFFF7FE0010001EFF80203FFBFFFFFFFFFFFF800000007F0000000004001FC001FFFDE00080003F00FD000FFFDFFFC1FFC00FE023FFFE00F0000006FFFFFC40001800F0FBFFFFFFC00000000040307FFFFDFFFFE1E001030FFFFFFE0BFE3FFF0201FFFFFFFFFFEF80200001BFFC07C100000001FFFFFFFC00000001FFFBFC010
+Modulus = 0x8000001FF0007FFFFFFFFFF007FFFE0FFFFFFFFFFFFFFFFE00007FFFFFFFFE0FFFFE00003FFFFFFFFFFFFFFFFFFFF80FFFFFFFFFFFFE03FFE00001FFFFFFFC0FE03FFF00000003FFFFFF01FFC0001FF0FFFFFF8FFFFFFFFFFFFFF0F000000003FFFFFFFFFC00000000000001FFFFF00F00000000001C000FE0000000000000FFFE000003FFFFFFF000000000000000000000000000003FF0
+Output = 0x3F9775D79D633347A25E3BCADE21577906958F2B14B33C7108E611714BBF8EA45B605B07F34BCE588FF7FF33528DE89120ACA279EC2F7E31EEF3B9512E4BA97B2990783522F89DFB8351CA6B63BD206DADD602EFA36C357ABBC1BE41E21B1092075B4B8D1521E62AEC996279522851F14EF21FE566DC4454783BBE907C2503F0FE21B927982D4997B3CBE39BE3EAECC8538F92A5A8D65CE0
+
+Base = 0x7E0000000007FFFBFFFFFFFFFFE0000000070020000601FF80003FFFFFFFF80000000000000200500020003FFFFE000001FFFF001007FF0000000007FFF7FF00000200000FF600000FCFC000000000FFFFBF80000007F07805FFFFF7FFF800000008FFFFF7C7FFFFFFFFF009F000000001FFE0000007FFFFFFFE0803F8080F7FFFFFFFFFFE07FF8800007FDFFFFE0007FFFE00000003FFF00008000000FF
+Exponent = 0x7FFFFFBFFFFFFFFFFFFC3CFFFF1FFF0000004006FFE0000A01FFFE0000000003FFFFFFFFFF800001C071FFFFFF4000BE000003FFFF001003FFFFFFE0000000039EFC0001FFFFFFFE00000008001FF00000FFFBC0003FFFFC007809FFFEF80003FFF00F80FFFFFFC0000000FC0001F000000002003FFFFFFFFFE1F1FE0FFFB813FFFFFFFBFFFFFE03FFF80000000000020007FFFD003C7FC200000000000400FC
+Modulus = 0x80000000000000000003FFFFFFFFFFFFFFFFFFF8FFFFFFF9FE000000000000000000000000000001FF8FFFFFFFC00001FFFFFC0000FFF000000000000000000000FFFFFE00000001FFFFFFF8000000000000003FFFFFFFFFFF87FE000007FFFFFFFFFFFF0000003FFFFFFFFFFFFE0FFFFFFFFE000000000000000001F00007F000000000000001FFFFF8000000000001FFF80001FFFFFFFDFFFFFFFFFFFFFF00
+Output = 0x122081D508577940B6F36DD742BB259B7FEC2C7B8AFCE1B023119A4EB539B256FA5BD8266589DC9D31FF11894F3A2D29EECF9307590A2686F3FDE34990828A190310D3C204C281974F9FBB504CEB653681835D6F0B45442B78FE762769AD0579150A2336B2F0409A1AF858BD3291BA550C49ACABE8FFF5EFE4C120472E2BFD75FD606F8B9A7D6C6A6194AE2BB1C0362989BFFE0018D30197CAAF98F04E3FD001
+
+Base = 0x807FFFFFFFFFFC03FFFFFFFF000007FCFFFFFFFFFFFFFFFFFC0FFFFFFF00000001FFFFFFFFFFFFFF0000000000000000FFFFFFF800000FFF01FFE000001FFF80F87FF80000000000000000000001FF00000FF00000000000FFFFFC000000000000003FFFFFFFFC000000000000000000FFFC001FFFE0000000000000FFE00000000000003FFFFF80FFFFFFFF00000000003FFFFFFFFFFFFF0001FFFFFFFFFFFF0000000000000000
+Exponent = 0x3FFFFF8000003C0000007FFDFFFF87FF3F0041FFFFFFFFFDFFE08000000FEFFFBF800001FFE000013FFFFFFFFB7FFF003FC0000000007FFF80FFE00000007FC038007E40FFFFFFFF8003FFFFDFFFFE7F07FFFFE0608000FF81FC1C00000000003FBFFFFF8000F87FFFF80000000FBFE15FFFF40080000000FFFFFFFFFFFFFFFE4FFFFFFFEFFFFF80C0FF23FFFFFBFFFFFFFFFFFC878001FF4004E03FFC0000034000001000000000
+Modulus = 0xC0000000000003FFFFFF8001FFFFFFFFC0FFFE0000000000001F800000000FFFC07FFFFE001FFFFFC0000000007FFFFFC03FFFFFFFFFFFFFFFFFFFFFFFFF803FC7FFFFFF0000000000000000000001FFFFFFFFFFFFFFFF000003E3FFFFFFFFFFC03FFFFFFFFFFF800007FFFFFFF0401F200003FFFFFFFFFF0000000000000000300000000FFFFFFF3FFFFC000003FFFFFFFFFFFFF80000003FFC1FC003FFFFFC3FFFFFFFFFFFFFFF
+Output = 0x4DC68B41E2020FF625DD9CB58CD416C8559707D292D7D1E438A3BD6DE37BBF32D9279ADDAABC523DD8F4A825AE7267D0FE5E520918E1F068A84DCB9EB1B1DF43BD8F74098CB8B3163FEF8311E17F9D21BE6C05A7A09435CD9116F3BE8D09016A394805287B0A5F7BB7B601963E0DE16FF0CF4E577B05331CCE606EE5D35710402CBE58E5496714646E9CE6E2727485BF0EBE016F74C268EB40D2BE9FB08ED56D6AD2E02E69BE7588
+
+Base = 0xE0000007FC0000001FFF8000000000000000000079FFFFFFFFFFFFFFFFFFFF001FFFF0001FFFFFFFE007FFC000000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0000000000200000000000000000001FF81FFFFFFFE0000000000000000000000001FFE01FFFFFFFF80001FF80002000000003FFFFE00000007FFFFFFF80000000000FFFFFFFFFFFFFF8001F0000000000003FFF03E00000001FFFFFFFE0000000000000001FFFFFFFFFFFFFC3
+Exponent = 0xFFFF0000000000000FFFFFFFFFFFFF800000000F803FFFF800000000FF000003EFFFFFFFC3C000003FFFFFFFFC1FC000000000000000000000000000000000000000007FFFFFE00070000007FFFFFFFFCFFFFC00000000000000000FFFFFFFFFFFFFF8000003FFFFF0000001FFFFF8000001FBFFFC003E000FFFFFFFFFFFFFF807FFFF800003FFFFF00001FFFFC00007FFFFE0006FFC0000000000000FFFFFFFF80007FFFFFFFFFFF00000000101FFFF
+Modulus = 0xFFFFFFF80000001FF800000007FFFFFFF80000000000000FF80FFFFFFFC000000703F9FFFFFFFFFFF8000000000000000000000000007FFFF80001FFFFFFE00007FFF80007FFE00007FFFFFFFFFFFFFFFE003FFFFFFFFFFFFFFFFFFFFFFFFF0000007FFFFFFFFFFE000000000000003FF800000000000007FFFFFFFFFFFFFFFFFFFFFFFFF8000007FFFFFFC000000001C000000000000000000F000001FFFFFFF80000000000000000FFFFFFFFFFFFF8
+Output = 0x6D2B4BE8998DE20AFDCBD3617601257BD28D6D4131B7E7BF092C68FC863D477F0561A6818D14A08548B3AEB9027CF0C6712559D24B2CA6D69C12A0B9EEFB38AE64FD17D9D55179A64AE44229439F750E1264B683654CF6931EEB83CE27057E251C09A3A254090ED479D50422EEAF9B83711DDCC394351ABBD878EEB0B07E9C2A0347A702B813A1978C3134E0AED228DA8B15B8EC2F73E7F7F3D162CC50F73E02D39598242D746A9D0ADF8DAA4454918B
+
+Base = 0x30000F8007F000002FF90000FFFFFFFFFFFFFFBFF010FFFFBFFFFFFFFFFFFFFFF00000000039FFFFFFE2007B820003FDF03000803FFF2FFC4FFFFFEFFFFFFF70103F000001FFFFFFFE000040FFFFFFF82FFF800004FDC0000000000800000000000000001FE00000001FFFFF003FFFC03FFFFF1F0001FFFFB0FFF91FFFEFE0083FFFE1FFFFFFFFFFB1FFFFFFC00000402FFFFFFC3FFC1C020FFFFFFFFFFFFFFFB00000000000000B000000000FFFFFFFFDFFE3C1F00EE01
+Exponent = 0x8000000001FFFFE0007FFFFFFFFFFFFFFFFFFF00003C3F8000000000FFFFFE000000000FFFFE0000FFFFFFFFFFFFFFFFFE03FFFFFFFFFFFFFFFFFFFFFF80000001FFFFFFFFFFF1FFFE0000000000000001FFFFFFFFFFFFFFFFFFFFFE01FFFFFFFE00000001FFC00F0000007FFFC0000001E000000000000001FFFFFFFFFFFFFFC1FFFFFFFFFE000001FFFFFFFE0001FFFFF8000FFE00000001FFFFFE001FFFFFFFFFE0000000000001FFFC00000000000000FF8000000000
+Modulus = 0x80FFFF07FF80000000FFF000000000000000000000FF0000000000000000000000FFFFFFFFFC7FFFFFFFE00007E0000000FCFFF8000000FFFF00000000000000FF000000001FFFFFFFFFFFFFF000000000FFFFFFFFF003FFFFFFFFFFFFFFFFFFFFFFFFFFFE0000000000000000000000000000000000000000F000700000FFFF800001E00000000000E0000003FFFFFC00FFFFFFFFFFFE3FFF0000000000000000FFFFFFFFFFFFFF8FFFFFFFFF00000000001FFFF0FF0FFF
+Output = 0x53ADB642716328AFDCF24083C996DBB23712271DFC1598D5F79439031952B4D0716A520BE5684370048213AD6FDADA2B1852DA82132FF9A191A6F5EBE478D9F5EDFCD8439B3487A7F68F32ED1A6CBA1156C78A393D76EDAA9F6CBB3ECDF029E44692DC5B662FE4D0FAE09E2A496CB6B5B1CCB2095FD6955C7B6ADD53D6FEBDC51B715008260804D0873C89E95581723860F633494A56B4A0C53E918653D01E81A2D3A90509CCE977B490AE2C0BC64156F6C6711E2E351E42
+
+Base = 0x7F20000000000000006000000000001FF8001FFFEC3FFFFFFF8000000040003F001800000201FFBFFF800000200001FFFFD00010E2FFFFFFFE000007E1E003C3FF7FFE07FFF1FFFFF7E0000000000003DF987FF00000000004800000007FFF0080640000001FFFF000000000007FFFFFFFE1FFFFC0000000005FFFFFFFFFC000005C02000000000000000000FFFFD0000001FFFE001FC7FFFFE0000001600000007FFFFFFFFFFC0007FF00FFC3FFE000027FF7E87F7FFFC0009FFFFFFF800000
+Exponent = 0x803FFFFFFFFFFFFFC00003FFFFFFFFFF0000FFFFFFFFFFFFFFC0000000000001FFFFFFFFFFFFC003FF3FFFFFFFFFFFFFFFC0000078000000007FF000003FFFFFFFFFF8FFFFFFFFFFE03C00001FF0000000000000000007E0001FFFFFFFE001FFFFE00000003FFFFFFE1FFF801FC00000000000003FC00000001FFFFFFFF80000003FE0FFFFFFFFFFFFFFC00000000000003FFFFFFFFFFFFFFFC000003FFFFFFFFFFFFFFFFFC7FFFFFFFFFF800003FFFFFFC0000000000000003FF8000000003E
+Modulus = 0x8060000000000000001FFFFFFFFFFFE007FFE0000FFFFFFFFFFFFFFFFFFFFFFFFFE7FFFFFFFE003FFFFFFFFFE0000000001FFFFF0F00000001FFFFF8001FFC00000001F8000E0000101FFFFFFFFFFFFC1FE7FFFFFFFFFFFFFF80000000000000001C0000000000000000000000000000001E000000000000001FFFFFFFFFFFFFFFE3FE00000000000000000000000FFFFFFE0001FFE03800001FFFFFFF8FFFFFFFFFFFFFFFFFFFFFF800FFFFFFFFFFFFFE00001F8000003FFFE0000000000000
+Output = 0x65C52894E871CFDD4B97667137ED5E4C5D2BAEA815878B4A73345C063708822A907F5CAD87AE3B7452B4B191A1040B2C606D86CACDB4053C01CAA1D83FC9CB0F0A008474CD6C4BDBBDDBA286524B1754E8D0ACE1EC1CA1B31E8A3A214E5DA546A61FA7CB520E4E0DB19BDB35557B19588EAFA55087026421BAB2788F1A18C5E2F5E4837773991B09B7C085742FAE5A8AD788FA1456C7A98FC3BBD5064A54C31F6B04840D71916EB1FEDDBC0C37701D374B5A32C03E2974F36860000000000000
+
+Base = 0x80000007F0000000000000000000000FFFFF00003F000000000FFFFFFF1FFFFFFFFFFFFFFFFFFFFFEFF80000007FFFFFFFFFFFFFFF80003FC007FF8000000FFFFFF0000000000001FFF000001FFFFFFFFFFFFFE00001FFFFFFF00000FFFFFFFFFFFFFFFC0F00000007F000000000000000FFFFFFFFFFFFFFFFF000000000000000003FFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8007FFC3FFFFFFFF0000000000FFE0FFFFFFFF0000000000000FFFFFF00007FFF00000FFFFC03F80000
+Exponent = 0x1FC7DF810007FFFFFFF800003FFFFFFFC00000001000000000140000170008400007FFFFFFFFFFF80007FFFCFFA43FFFFFFC0000000038000007FF7FC027FFB8FFF803E3F000078011FFFE00FF7FFFFFFCFF400003FF40000007400000000004001B0000207FFFF800000000002801FFFFFC00000023FFDFFC00000FFFFFFFFE0FF400000FF80000001000000000000FFFF7FC00000000000003FC001000001FEFFFFFFFFFC00003FFFC00000FFF800009BFFFF8010000000003FFFFFFC00010FFFEFFFFFEF80001
+Modulus = 0x8000007EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3FFFFF00003C0000000000000000000000003001C00000003FFFFFFFFC000000000003FE0003FFFFFFC1C0FFFF87FFE0000000000000003FC7FFFFFFFC00000007FFFFFFFFFFFFFE3FFFFE0000007FFFFFFFFFFCFFE000003FFFFFFFC001FFFFFFFF000000001F003FFFFFFFFFFFFFFFFFFFFFFFFFFF0000003FFFFFFFFFFFFFC03FFF00000000FFFFFFFFFFFFFFC0003FFFFFFFFFFFFF8000007FF0000000003FFFFFFFFFFF00000000001FFFFFF
+Output = 0x14FF991227819E4A971213087695797991589DA6709E88E17ECB05C476C6770062B1C0E1123A4AB38C97BD3CDAA55A4C3FEF7C2001C0787ADF8CDDCCAB30D12F637192A6E42FDB01D23D07E4A3A154346AC344C754B825AFCAF21B6AC15E2DE051D1DF0DD64A5370848AA72C226B75F9853297A5BB2ACD532AFC7C0C8E2D92E39E79E6537B820923E87027C19861D29CA9CECD45F82CD038A1C90637E65079F30B3929C917F86753407BE81502CC8F490E1CEB77538E1135ADFBBDC2686D5EC03E34F0DBC6F04F86
+
+Base = 0x6FFFFF000401FF80C03FB08001FB83800107FFE01001F687F000000000007FFFFFFC0080000000001FFFFFFFFFFF8FFFFFFFE0F003FE0001F803FF8000001FFFFFFFF8001FEC801FFDFFFFFFFFFEBFFE0001FFF01E0101FFFFFFFFFFDFFFFFC00000101FDFE2FFEFFFFFC01C00208FFFFFFFFFFFBFFE10001FFFFFFFEFEFFFFF00020000011F7FFFFFFF0001FFFF8000007FFFFFFFFE000000007FFFFFFA7FFFEFFE00010000000001FFFFFFFDFE80000007FBFFFFFF40FFFFFFF80FFF7FF80004008000000001FEFFFE8000
+Exponent = 0x800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000FFFFFFC03FFFFFFFFFFFFFFFFFF800007FFFFF803FFFFFFF00000000000000008000000000780000FFFFFFF800000000FFFFFFF800000000FFFFFFFFFFFFFFFF3FFFFFFFFFFFFE00FFFFFFFF000003FFFFFFFFFFFFFF000000000000000000F0F0000000FFFFC003FFFFFFFFC0000000000003F000000FFF000000003FF000000000FFFFFC007FFFFFFFFFFFFFFFFFFE0000001FFFFFFFFFF000000FFFFFFFF000000001FFFFFFFF000000FE00000000FFFFFFFFFFFF
+Modulus = 0xFFFFFFFF800000FFFC0000003FC03FFFFE007FFFFF00000FF000018000000000000180000000000000007FFFE000000000007000000000000000000007FC000000000000000000000003800001FFFFFFFFFF80000000000000000000000000001FFFFFFFFFFFFFE01FFF000000003FFFFFFF7000000000003FFFFFFFE000000010000000FFFFFFFFFF007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8000000780000FFFFFFFFFFFFFFFFE00000001FF8000000003FFFFFFBF0000000000007FFFFFFFFF000001FFFE0000018000
+Output = 0xD2DADB40B8222FD024212EB1379943899F5A3E31E45DE2B846960D2CA500422E16768C4851CF9D3F5F27CA030D78649978B65A7113D25FE096013FA44FF7CCD33C14756C64407AB3B787298EF5C644BE8AA6DC9A1BBE29330548EABF39E3EF4AD498C3D47A7BD7E1AD0DA3DE68456D4F691AECA08A13E0173F61E6957E51D97D4A8DFE5AAAF6F0FE50DEE3E9125E2E3DC25A5E9C3D83E6F107F22DEDC4F8D4860DA07ECEE35BFD7334193C402469ECF392EEC9F441CA7B5A8928840A37A7F41AD7C9BF3A72958A96CCB6BA655E8B8000
+
+Base = 0x8000000000000000000000001FFFFFFFFF803FC000003FFFFFFFFFFFFFE000000000000000000000000001FFFFFFF80000003F000000007FFFFFFFFFF8000FFFFFFC3FF8001FFFFFFF003FFFFFFFC01FFFFFC00000007FFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFC000000007FFC0000003FFFF803FFFFF000F0000000000000001F8000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000003FF800003FFFFFF00000000007FFFFFFC000000FFFFFFFFFC00000F83FFFFFFFC0000000000000000000000000FF87FFFFF80000000000003FFFFFFFFFFF
+Exponent = 0x3FFFFE0FFDFFFFFFFFDFFFF00020FFFBFFFF80200000000000001BFFFFFFFFF0007E001FFFFFFFF80000000000000020F7FFFFFF9000001FC11FEFE00000001FF0000FE0007FE000001FFF8FFFFFFC2003FFFFFFFFFFFFD007FFFFEFFE07FFFFFFFFFFFFFF0000FFF8000007C1FFF800FFFC0023FFFFFFFFFE0FFC50001FFFFFFFFFE3FFFFF0FF0001FEFFEFFFFA007FFFFFFFF020200007FFFFFFE04000001001DFFFF00000003FFFFE00000000FFC00001FFE000000003FFE0007F000000000000000FFFF100000000FC1FFFF806FF80
+Modulus = 0xFFFFFFFFFFFFFFC00001F001FFFFFFFFE0000FFFE00003FFFFFFFFFFFFFFFFFFFFE0000000000FFF81FFFFFFFFFFFFFFFFFFFFFFFFFFFF07FFFFFFFFFFFFFFFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000003FFFC000000000000000000000FFFFFFFFFFFFFFFFFFFFFFF1FFFFFFFFFFFFFFFFFFFFFFFFC00000000000003800000000000001C00000F0000000000000003FF800000000FE01FFFF80000000FFFFFFFF00000000FFFFFFFE0000000000000001FFFFFFFFFFFFFFFFC001FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFF000000000000FF
+Output = 0x777FB3C902750B28A55A5465115C0AAE5362B241868C7DBC2C476C1453AEEC8ECFBB219787C75D068A7B8FF53E6D994BBB0334AD05A16F8C006764096ED539974D31E318288EC8552AEF67B0D431AB348A9A45CFE242444F1FB03E7F396AF1252CDC5FA8FD2827D1437EC8D53589D114B55EFC27DD3BCDED56D13D17E92122618A51F2F94252F17E3905564989DAE61419703C4797733B7F45ED7F6642E6F8A50BC058440601F96D65531954E6BB59F668BB8EA6DC5621B0AB7AA3EA167FF77587037DCC78B9A7B028D44D5938257FA0F4EB46AFEFD1674E
+
+Base = 0x7BC007FFFFFFFFFE07FFFE7FFFFFFFFFFFFFFA001EFFFFFFFFFFFC3C000000007FFFF938007FFFFFE003F80000FFDE00FFE00000002007FFF0FFF81FFFFFDE000000007FFFF000008000001000000000FF4086FFFFFFFF7F007FF8000013D8078041F680000E00007FDFF7F0000061FFFFCFFDF80C0008FFFFFFFC000000F60000000007FFFE080C07FFFFFE00FFFF00000007FFFB0387FFFFA03FFFFFFFFFFBFE000000020FFD803FFFF1FC03FE086FFF8002000001FFFFFFFF78000001FE00000009780000002FFFF7C0080017FFFC03FFE1FFC40801E000FFF7FFFFFF83ED
+Exponent = 0x8000000000007FFFFFFFFFFFC00FFFFFFFFFFFFFFFFFFFFFFFFFC3FFFFFFFFFF007FC0000007FC0000000000000000000000000020000000FFFFFC0000000000003FF83FFFFFFFE0000FFC0007FFFC7FFFFFFFFFFFFE00000FF80000000007FFFFFC00000FFFFFFFFFFFFFFFFFF80000000003FFFFFFFFFFFFFFE7FFFFFF80007FFFFC00000000000000000000000000000000000001F800000003FFFFFFE0000000000000000000000000000000001FF81FFFFFFFFFFFC0007FFFFFFF9FFFFFFFFFCFFFFFFFFFFFFFFFFFFFFFFFFC00FFFFFC00000000000000000000000000
+Modulus = 0x83FFFFFFFFFFFFFFF800018FFFFFFFFFFFFFFE0000000000000003FFFFFFFFFFFFFFFFC00000000000000000000001FFFFFFFFFFFFE000000F000000000001FFFFFFFF80000FFFFF7FFFFFFFFFFFFFFF007F81000000007FFFFFFFFFFFFC1FF87FC001FFFFF1FFFF8000100000001E00000001FFFFFFFF0000000000000001FFFFFFFFF80001FFF000000000000000000000000003FC7FFFFFFFC00000000003FFFFFFFFFFF0007FFFFFFE03FFFFFF8FFFFFFE000000000000007FFFFFFE01FFFFFFFE07FFFFFFF000003FFFFFE7FFFFFFFFFE003FF7FE1FFF00000000007E0F
+Output = 0x6D71C92B50240D6CDAE12C1043DF7C764E4E1F8966703BEB92DE64EFCBE6C21BAF6205485E9808FCA17FFBEEAF38A31765F61EA6DFA9F9E4E7CAD0B0F9E320B633E3237F80BE5A294EF093A2E416BDAA63F03A88B36A013AC2A926EEC89901CF169AB4FBD7B70F0767CFFC82214FDB9BC55EF29091ED595AFB0301186CD126B253C398D7A631BE6C21FA44E423BBD2E05C2D20130B46F2251B4053EE59B3AAB0573F7D78004D5D868261B1F5899BFA60D10C7C00858BBF84B92E9731DAED31D10C8F04B8016321C4D838B482AF9C5CC8BDB088541CA59885E7D2ED1937C5000E
+
+Base = 0xF0000000FFFF01FFFFE07000000000000000000001FFFFFFFFFF03FFFFF9FE0007FFFFF00000007FFFFFFC00000000FFFE0000000000F800600000FFFFF1FF000000007FFFFFFFFFFF00001F80000000000000FFFFF80000000000000000007FC000001FFFFFFE00000000C1FFFF8000000FE0000000007807FFFF0000007FFE000000000000000FFFFFC0FFE000000000000000FFFFFF00000000000000000000007C000FFF0000000000FC00000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0FFFFFFFFFFFFFFFFC00FFF00FFC000007F
+Exponent = 0xF000000000FFFFFFFF1FFF80001FFFFFFFFF0001FFFFFFFFFFFFFC00000003FFFFFFF07FFFFC000000000000001FFFFFFFFFFF8FFFFFFFFFFFFFFFFFFFFFC7FFFFFFC03FFFFFF87FFFC7FFFFF0000000000003FFFFFFFF000000007FFFFFFFC1FFFFFF8000FFFE003FE0007FFFFFF000000000000000000001F003F00FC000000003FEFFFFFFFFFFFFFFFF80000FFC0000000000000FFFFFFE00007F800FFFFFFFFFFF8000000001FFFFFF8000000070000FFF801FFFFFFFFFFFFF80FFF83FFFFFFFFFFFF00000000000007FF00001FFFFFF80000007FFFE0000018000FFFF8001FFFFFFFFFFFFFF
+Modulus = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8FFFFFFFF00007F000003FFFFFFFC00000007FFFFFFFF8000000387FFFFFC00000003F8000000000003FFFF0003FC0003E0000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFC0FFFFFFFFFFFFE00000000001FFFFFFFFC000FFFFFF800FFC000000000000000000000000000000000000000001F80003BE0000003FFFE0003FFFFFFFC000000FFFFFFFFFFFFFFFFE00007C00000000000003FFFFF800000000000BFFC00001FC00003FFFFC1FE00000001FFFF800001FC000000000000001FF000000000000003FFC00FF80
+Output = 0x1C7E02408C172D7234F1E9DB136C6996DFCE626DB73A487DA13ACCFF1E8CA94A431AB2555B77CB311A7378D6A30EAD260FF6A49AE58FFDFDA555F4EFE6E7F464BC0EB776E37B5536FD0E4F9E1440B5F8BE020081A0DC7598AC9E469C2D88E5B5C089C8EE871FD638D848D8A5C5D45308A439F67644A61568B2BE70201B405043760A1E2B52FBF154545C86259DBA414256A8D9C20136AA41284B9DD8DB643CFAB59934E8C8544BAC9DCF0C608B4616CD8FFADE0A78164A1BDE8D158D3B1E40C28AC7E7A37B2CD6A0EB24051E05D5DC9D5D0C76530B873197BA2A267E40B5698D2CB023C98673C07F
+
+Base = 0x87FFFFE00000000000003FE000000003FFFFFFFC0003FFE00000001FFFFFF0000000001FFFFFC0000000000000000000700003E07FFFFDFFFFFFFFFFFFFFFFFFFF80001FFFF0001FFFFFFFFE003FFFFFFFFFFFE0000000000003FF007E0FFFF80000001FFFFFFFF8FFFFFFFC00000FE00000001FFE00000000000000007FFFFFFFFFC010001FFF8000001FE000000001FFFC0000000007FFFF80001FFFFFFFFFFFFFFFE0000000000FFFFFE000001FFFFFF8001FFFFFFFFFFF8000000030200003FFFFFFFFBFFFFFFFFE001FFFFFFFFC1FE000000000000000000000000000000000007FFFFFFFFCFFFFF01F800001FF
+Exponent = 0xFFFFF280000000FFFE007F810000001F1FFFFEFFFF600004000000FFFFFFDFFFFF0000007FFFFFFFFFF7FF80C00007FFFFFFFF000001FFC0040000FFFFBFFFFFFFFFFF00003FFEFFF807E080001FEE01007FFFDFFF9FFFE80FFF7F8000001FFFFFFFFF00601000FFFFFFFE81FF00000FC000007FFFFE00000000009FBFFE00C05FFFFFC183FFF87800000207F0000CFFFFFFFF0007B01FFFFFFFFFFFFFFC011FFFFFFF00005FFFFE40003FB8000001FFFFFFFF7FFFFFD0000003F8FFFF7FFFFFFFFFFFFFFFFFFC00077FF1780007FFFFFFFFFFBFF801FFFFFFFFFE80000000F000FFFE781FFFFFFFFFFF0081FE1FFF8
+Modulus = 0xF00000C7FFFFFFFFFFFFF807F00000000E0000000001FFFFC0000000000001FFFFF000000000000000000007FFFFFFFFFFFFFFFFFFFFE003FFC0000000040000000000000000000FFFFFFFF8000000FFFFF80001FFFE0001FF000007FFFFFFFFFFFFFFFFF9FF000000000007E00FFFFFFFFFFFFFFFFFFFFFFFFFFFF803FFFFFFFC00000007C00007FFFFFFE000FFFF00000000000003FE000000000000003FFE00000000000000001FFF0003FFFFFFFFFFFFFFF8000003000000007000000000000000000000003FFFC7FFF87FFF800000000004007FE00000000007FFFFFFFFFFF000187E0001FFFFFFFFF800000007
+Output = 0x4F6758EEB3999FBF494AEECEAB5F4FF110FC3E746F28ED43F9A7382EA3FEDD249E40D060AA0EE938511FE326F8648663200BF6B68E7C1C92264094A27E7FEEB928264123EB95EED0D794803CCB5EEF06769E258B0CD9BA939BFCAFD0C5794D709C86DB643EF2EDD43E8B44CB2AA27B8C561E093F717166AA5C27D1736A4BE301E5C1B4B6D89E7580A07DA6F5247A0065077ADA4065DF3AE2444EA73F4C16819B1238AFF421638E5685F97179C47D8F34044A03FD08EC7CEED4FE0E5BEC6B2B2E732DD7131D4913201B5D3AFFD0BBBD9745A87AD48B02E64D647C670438BEF6BEC4749C7F6BBE413C00BAADD625927A42
+
+Base = 0xFC000000000000000001FC000007FFFFFFFFE3FFFFFFFFFFFFFFFF03FFFFFFFFFFFFFFFF00000000000001FC3FFC000000000000000000000000000000000003FFFFFFFFFC00000000100003F800000000000003FFFFFFFFFFFFFFFC01FFFFFFFFFE007FFFE00000000083FFFFFC007FFFFFFFFFFFF80000000001FFFE00000000000003FFFFFFFFFFFE000FFFFFFFFFFFFFFFFFF807FFFC00000000000000000000001C0000FFFFFFFEFFFFE000000000001FFC0000000000007FFF800000000FFFFFFFFC000003FFFFFFFC00000000000003FC00007FFE00000003FFFFFFFFFFF80000000000000FF80003FE00000000000003FFFFFFFF
+Exponent = 0x8FFFFFFF000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FFFFF9FFFFFFFFFE1FFFFFFFFFFFFFFFF000003FFFFFFFFF80000001FFFFE001FFFFFFC1FFFFFFFE00007FFFFFFFFFFE0000000000008002007FFFFE00001FFFFFFFFFFFFFFFFFFE0001FFFFFFFFFFF800003FFFFFFFFFFFFFFFFFFFFFFFFFFE00000000000000000001FC010000003E00000003FE000000000000000FFFFFFE07FFFFFFFFFFFFFE0FE00003FFFFFFFFFFFFFFFFFFFFFFE1FFFF8FFF00000000000000FFFFFF801F80000001FFFFFFFE0003FFC1C00000000FFFFFFFFFFFFFFFFFFFFFC0000000003FFFF0000000003FFFFFFFE000000001FFFFFFFF
+Modulus = 0xFC000000FFFFFFFFFFFF8000000000007E000000E007FFFFFFC07FFFF00000FFFFF8003F000000FFFFFFFFFFFFFFFFFF000000077FFFFFFF0000FFFF003FFFFFFFE007FF07FFFFFFFFFFFFFFFFFE03FFFFFFFC00FFFFFFFFFFFFFFFFFFFFFFFFFFF80007FFFFFFFFFFFFFC0000000000000200000000F00001E00000FFC0000100000000FFFFFFF800000000800000000F8000000060000000000000F80000003FFC00030003FFF8000FFFF000000000FFFFFE00FFFFFFFFFFFFFFFF000007FFF8FFFFFFFFFFFFFFFFFFFFFF00000003FFF00000FFFFFE00FFFFFFFC000000000000000000000000FFFFFFFFFFFFFFFFFFF800000000001F
+Output = 0x570BAF35927C3CEC2E6B6813B2DF401724E05D1F042C6370929BEB8B121F2955910F3F0C519202D01F14822EF950A7D9A06543B411E13647F8D2A72E16545725FF618FF846A7319A2E853203A82557163F7F2B8367D70CBEE031C599B281ED04295EF26B70A02BCB01707BBB0B5F8C0CBE550B665F2317871C2C749781C546288B9F94F8F242250D88C12077E95BB786ACAA7B625251E5B4A457A2FEEEB6561606EDC3BAC3E7565230B73E98E91BA59EDDDFDBF0542D76E515EBA11DE6CDAE6F059627C1DB8329601E92BCEF6EDF13ED7BDA996D986EDFA1406569F5F3E9FE900FA4C9E21A444DBD98FEDD0E6F18030AF5335B3158FB75E
+
+Base = 0x1FFFFF7FE7FFFFFFFFFFF00020001C000000000003FFDFFFC00200038EFFFFFC007FFFE01FFFFFFFE201FC000007FFFFDFFFFFFFFFEFFFFFF000000023FFFFFFEF040FFFEFFF80000000004007FFFFFFFFFFFFFFFFBFF80F8007FFFF800000007FFF800027FFFFFFDF800000000000E01FFFFFFF7FFFFFFFF000000000000100000021FFA000001FFEFFFC07FFFFFFFF1C00000000000000FE0103F6000000020000000000003FFFDFFFFFE09FFFFFFFDFFFFFFFFFFFFFFE00000008FC00000018007FFFE3FFFFFFFFFFF80060803C000000000800001FFFFC00000781FFA0001000FFFF9FFFF8007FFFFFFFFDFFFFFD0FFFFFFFDFFFFFFFFFFFF803A001FFFB
+Exponent = 0xC00000003C00000000F800003FC0000000003FFFFFFFFFFFFFFFFFFFC000000000FFFFFFFFFFFFFFFFFFFFFFC0000000000000002FC0000000000000C0000000000000003C000000003FFFFFC00000000000FFFFC00000003FFFFFF83FE07FFFC0007FFFE00007FFFDFFFFFFC00007FFC0000001FFFFFFFFFFFFFFFFFFFFFFF8000000003FFC0000000FFFFFFFFFF80000007FF80000001FC3F8FFFFFFFFFFFFC0000007C000000040000000C00000003FFBFFFFC000001FFFFFFFF03FF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC000000000000001FFFFFFFF001FFFF81FFFFFFFFFFFFFFFFFFFFFFFFFFFFC1FFFFFFFFFFFFFFFFE0003FC00000003FFFFFFF
+Modulus = 0xE00000001FFFFFFFFFFFFFFFE00000000000000000001FFFFFFE000000FFFFFFFF80001FE00000001FFE01FFFFFFFFFFE0000000000FFFFFFFFFFFFFE000000000FC000000007FFFFFFFFFC00000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFE00000001FFFFFFFFFFFFFFFE0000000FFFFFFFFFFFFFFFFFFFFFF0000001FFFE0000000000003F800000000E3FFFFFFFFFFFFFF01FFFC01FFFFFFFFFFFFFFFFFFFFC0001FFFFFFFE00000001FFFFFFFFFFFFFFFFFFFFFFF000000001FFF80001FFFFFFFFFFFFFFF9FFFC1FFFFFFFFF80000000003FFFFF800003FFFF0000000000000000000000001FFFFFFF00000001FFFFFFFFFFFFFFFE0000004
+Output = 0x2E1A36FF2ACECBD16C4E8450396A749E6592747AB0229805016DE3CFBE779CED331513B68770BDA1697E8F6CB95BC0DBE141A8729E6219393896C91B732C95552C2935DC87B35EC6202662D32BC2CC9FED99DF75D417307216F33F91CED1179B596BB230AF6EEEB9A219C746370C64430DBFDA67C5185E626D000C2A0C9995CF41F8F13F42DEEB61C29387B7A667EEBF332C67430410C35B271BFE39510222E309862C4C3758F6DDA1B0683C09255A4F755D0CED4B5DE1595941FF7375CCBE374AD2F69A45C0C75AEB2039EB3E4AA4C20B24E2099E012C5E9685666BE872B3584F4E795209EF4EAAA0F0BE42CB90AF46C02DCBE3883EFFEBAF9BD61F291CEABF
+
+Base = 0x800000000FFFFFFC00007FFFFFFFFFFFFFFFFFFFFFFFE0000FFFFFFFF0000004000000000FFFFFF80001FFF800000000000000000FFFFFFFFFFE0000007FFF800000001FFFFFFFFFFFE000000FFFFFFC00FFFF800FFFFC0000003FFFFFFFFE00000007E00FFFFFFFFFFFFE00080FFFFFFFFFFFFFF00000FFFFFFFFFFFFFFFFFFCFE000F8000F03FFFFFFFFFFFFFFE00FFFFFFFFFF000000000003FFFFFFFFFFFFFFFFF800FFFFFFFFFFFFFFFF000001FFC03FF800FFFFFE00FFFFFFFFFF800000FFFFFFFF0000001FFFFFFFFFFFFFFFFFFFFFFFFF0000000000FF81FFFFFFF0003800FFFF000000000000000FFFFFFFFFEFFFFFFFFFFC003FFFFFFFFFFFFFFF07FFFC00000000000
+Exponent = 0x8000000007FFFFFFFFFF8000003FFFFFFFFFFFFFFFFFFFFFFFE03FFFFFFFFF000000000007E00000079F000007FFFFF801FF000007FFFFF007FFFF8007FFFFFFFFFFF00000078000000000000800000000000000070000000003FFFFFFFFFFFFFC000007FFFFFF000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000000001FFFFFFFC0000000003FF803FFFFE000007FFFFFF80FFF0000000000000001FFFFFFF8FFFFFFFFFFFFFFFF00000007E1FF8000000000000003FF80000001F80000000007C00000000001FFC000000000000000000003C000000007FFFFFFFFFFFFFF87FFFFFC7FFFFE00000000000000000000000FFFFFFFFFFE0000000DFFFFFFFFFFFFFFFF
+Modulus = 0xFFFFFF80001FFFFFFC000000000000000000007FFFFFFFFFFE1FFFFFF3FFC00007FFFFFFFFF0000003FF800003FFFFFFFFFFFFFFFC0003FFFFFFFFFFE2000000000000000400000000000000FC0000000003FFFFFFFFFC00FFFFFFFFFF00000007FE000FFC000000001FFFFF03FFFC000000000000000000007FFFFFFFFFFFFFFFFC000FFC0003FFFFFC000003FFFFFE0000000004000FFFFFC000000000001FF8000FE03FFFFFFFFFFE00003FFFFFFF0000380000000000000000001C000000007FFFFFFC7FFFFFC00001FFFC006000008000003DFFFFFFFFFFFFFFFFFFFFFFF000000003FFFFFFFFFFFFC0FC00007FFFFFFF01FFFFFFFFFFFFFFFFFC00FFFFFFFFFFF803FF0001
+Output = 0x61FD949D94FF3ED5A3117DD8AE0973D43B44B7E91689209A51DB2A48CF4152F3CFFEF6C74CBC69A446F65314159F5C8CAB7FCDAC61ED5E8BF92BB6EE1A5043715A85A3E6C6083113DEE9EFDB4133B695CB285BBB6FF6EBB331FE4F3F154732BC7FF96AE7650F79C120926664F87608C5390491CDCC6B46034E4D363553ACD1E45B421D136D1D2007D0908551CAC38F78A0FDE91CCB4A06C6076BDAC345671ABF0D92F9626CEEC7C9CC025F0BA1CC60DED035B48E5C3C0803FB6E3938507046CDC56AE20542A6BCE30E24A3748F77014DA74E786EBFF88E91ABF54BE93CDFFB39AEA60538131CF4135ACAD68CFAF9CFFDF6B330B48E59C07C3CE2BE11EE86A31FF9944120A78DCC0B
+
+Base = 0x7FF00021EE7FFBC80001EFC07FFFFFF7FFFFFFFFFFF0FFFFFFFFFFF8807FBFE0080EFFE0000000001FFC200041FBC000027FFFFFFEFFFFFFC180000FFFFFFE003800EFFFF803FF07FFFFFFFFFE00001C0000207FFFFBF7FF80000000020FFFFFFFFFFFFFFFFFFC0000040000007000000100000000FFFFFFFBB9003FFE0000BFFFFBFFE0027FFFFF087FFFFFFFBFFFFFFFFF0000487FFFFE01BFFFDFFF7C0000000FFFFFFF8000001EFFFFFE0013FFFFFFFFEF87FFFFFFFFFFC03FFF0001F3FF7FFFFFFFFF00000E01FF7F001E006000800000003D800000007FFFE002400000FFF000003FFFB000000FFFFFFF800078000007FFFE3FFFC07FFCC00001FC000000004000007F00000001FEFFFF87FFFF
+Exponent = 0x8001FFFFFFFFFFFFFFC00000000000000000007FFFFFFFFFFFF00FFFC00000000000003FFFFFFFFFFFFFFFFFFFC003F0001FFFFC0300000000800000000001FFFFFFFFF8007FFE0000000000000003F0000000000FFFFFFE003FFFFFF8FFFFFFFFFFFFFFFFFFFE0000000100000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000FE01FFFFFFFFFFFF80038001FFFFFFF8800001FFFFFF007F000000000007FFFFFFFFFFFFFFFFFFFF0000000000000000FFFFFF0000000FFF00000000000003FF000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE000001FE0000000001E100000000003FF000000000003FFFFFFFFFFFFFFFFFFFFFFE000000000000F00001FFFFF87FFFFFFFE00
+Modulus = 0x8007FFE00F8003FFFFFE003F8000000000000000000FFFFFFFFFFFC7FF803FFFFFF0001FFFFFFFFFFFFFFFFF80003FFFFF80000000000FFFFE3FFFFFFFFFFFFFC7FF800007FC00FFFFFFFFFFFFFFFFE3FFFFFF80000007FFFFFFFFFFFFF0000000000000000003FFFFFC00000000000000FFFFFFFF000000007F0000000000000000001FFF800000F7800000003FFFFFFFFFFFFFF78000000000001C007FFFFFFFF00000007FFFFFFF000001FFFC00000000007800000000007FC00000000C007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC07FFFFFFF80001FFFBFFFFF0000000000000FFFFFF00000007FFFFFFFFFFFFFFFC0003F80033FFFFFFFFFFFFFFFFFFFFF80FFFFFFFE0000007FFFFF
+Output = 0x7A25B3FAC7216EB38ED82393629FD84C44AB039D150C6255816D9CD4111EEE9291E2B35CC6E2A24BE4D4A7E2EE6ECCFA02F0ABA54A9542BE840AA759066FA8A29F509C838DE098FDCDD2552B09A36D2BF9C64160F5CC39ADA6E664FD03C88E26F0E3FE723ABE949A66108D508B3D0F82024D9A0851FBEAC809DD83219584AC2DD7D2EF4C78B78D789B04EEFE83B1AC743FCE6C5103B550AA8907C98333EB1D5D24927A448E560B5C03E9B6253E38AF43083B3F5D50F2F2CE33D69CCCA471E563B4C8DCE53C3A99734A0491BE4E000A19F05376240C8945F898443DAECA595DDC93936E80585710B3D4616099A5BEB9B0D105CE755F5691373A6D7F3AD8C486D0B48A8103B4D2FA883787762E80C1C705
+
+Base = 0x7FBFFFFFFFF83FFFBFFFFC004FEFF0000040000001DFFFA3FFEFFFE000167FFFBFC2000000F000000FBFFFF80231EFFC0101E000002C00000FF0400007FFEC07FFF00000200001FFF86E0001FFFFFF000000007FFFCFCF81000FF8000028010003FFDFF80003FFFFFFFFFFFFC0100000003C000FFFCC0000000FFF7FFFF1FFFFE0401FFC00000060063FFFFF00FFEFFFFFF0000000C000040000000000F0FFFFFFFDFFFFF04FFFFFFFFFF002FFFF800207FFFFC0000FFFFFFFFFFF7FFFAE003FFFBFFFF9F83FFFFF000003F8004FFFDFFFFFFFFFFFC11FFFFFFFFFFFC00C03F8000EE000005FFFFFFFFFFD80FFE0000000001FFFFFBFFF806000FF90FFFFFFFFFFFFFDFC004EFFF83FFFFFE0008FFC007E38000001FFFFC0
+Exponent = 0xFFFFFE0058003BFFFFFC780FF39E000000000001E00020000FFFDFFFF03FFFBFFFE00100EF80000FC0000021D1FFFC01007FFFFFB000000FF04000001FFB07FFF00000201F7FFFF87000021FFFFEFFE1C00000000FC0000010000007F0000003FFF3F7FFE000000000F057C010000000000007FBCC1C00000FFFFFFFF23FDFE000220000000000003FFEFF009FFFFFFFEFFFFFFFE0000BFC0007E00030E1FFFFFFF7FFF010000000007003FFE1800007FE1BC0002FFFFFFFFDFFFFFFB000017FFFFFF8001FFB0003C003F80010005FFFFFFFFFFFE10FFF801FFFFFC00C03F8000FDF80002000000007FDFFFFE00000000020000002FF87FFE0FF8FFFFFFFFFFFFFFE00002E800020000000000F7DF87E100000021FFFBC
+Modulus = 0x8000000000080000000003FFF00FFFFFFFFFFFFFFE1FFFE00000001FFFF000003FFFFFFFFF0FFFFFF03FFFFFFE0E0003FF000000000FFFFFF00FC000000003F8000FFFFFE0000000078FFFFE000000FFFFFFFFFFFFF03FFFFFF00000000FFFFFFC000007FFFFFFFFFFFFFFC03FF00000000000000033FFFFFFF00000000E00001FFFDFFFFFFFFFFFFFC00000FF800000000FFFFFFFFFFFFC00000000000F0000000000000FF0000000000FFC00007FFFF800003FFFF00000000000000070000000000007FFFFFFFFFFFFFC07FFF0001FFFFFFFFFFFFF0000000000003FF3FC07FFF01FFFFFE00000000001FFFFFFFFFFFFFFE0000000007FFFFF007000000000000001FFFFF0FFFFFFFFFFFFFFF003FF81FFFFFFFE000040
+Output = 0x4D9C194E7F96EB02CC4C638097573BC3681CD839FA06B470525C3821CFC78D31D881D08BBF66D909C40AAC21C11F3CE31FEB8B1DA27AD65473E04D2BFC26FFA523C019047A9537E7EE62CB332D9F9081510539D99A361E76482FDD3F49610B27618E2947710B5734D0470F37DA23A80AB1167F23BE2C9941CDB9E8828FA2ECB3B315321DC50A2D524555E4F3D4DE3D7E8C8FFBE529463008CC9B224E8091F01D5485486EF944A30167A5A14083DB89149C60C394A48AA3F85FB6382B53E670D5CF962D5B755EFFCC0F57EC3EC984764219F456DA62D47DE42735CDFD7DC25FB8C4A02A017EC12566E6972B7BA0B56488F95BCD5D905C6CB94D09C5397E847611AE30EBDFAAE8FA52786464AB03589733D9DA50952AC00C80
+
+Base = 0x8000000000000001FFFFFFFFFFF80000000080000000000000000FFFFFF800000000003FFFF8000001F80000000000000038000000000000FFFFFFFFFFF80000FFFFFFF80007F03FFFFFFFFFFFFFFF800000000000000000000000FFFFF8000000003FFFC000000FFF87FFF00000000003F800000003FC000000000003FFFFF0000000000007E0000000000000000000000000000007FFC003F80000000000000009FFFFFFFFFFFFFFFFFFFFFFF80FFFFFF0000000F80000000000000000F00000003FFFE1F800000007FFFFFFE7FFFFFFFF07FFFFFFF8000003FFF8FFFFFE000000000000000000000000000000000000000000000000000000007FFFFFC003FFFFFFFFFFFFFFFFFFFFFFFF0007FFFFFC0FE00001F8FFFFC001FE3C0007FFFF
+Exponent = 0xFFF000000003FFFFFFFFFFFFFFFC7FFFFFFC000000000000000000000003FFFFFFFFFFF8000007FFFFFC0000000C0003FFFF8000007FFFE03FFFFFFE0003FFFFFFFFFC01FFFFFFFF00000001FFFFFFFFFFFFFFFFFFFC0007FFFFFC0FFFFF0000003FFFFFFFFFFFFFF8000000001C000FFFFC000000033FFFFFFFFFFFFFFC07E0003FE003FFFFFFFFFF03FFFFFFFFC00FFFFFFFFF8000000003FFFFFFC0000000007FFFFFFFFFFFFFFFFFF0000003FFFFFFFFFFFF0003FFFFF000000003FBFFFFFFFFFFFFFFFF8000000000000003FFFFFFFFFFFFFFFFFF00000000000003F8C1FF8000FFFFFC000E0000000000003FFFFFFFFFFFFFE0003FFFFFFC000000600000FE003F03FC00000000007F8003FFFFFF0008001FFC000000000000003FFFFF
+Modulus = 0xFFFFFE00000000000000000000FFFFFFFFFFFFFFFFFE000FFFFFFFFFC006000001FFFFFFFFFE0061FFFFF800001FFFFFFFFFFFFFFFFE0000000000000000FFFFFFFFFFFFFFC00007F00003FFFFFFFF80000001FC000000000001FFFFFFFFFFFFFC00000003FFFFFFFF8000000001FFFFFFFE003FFFF9FFFFFFFFFFFFF8060000003FFFFFFFFE007FFFFFFFFFFFFFFFFE03FE01FFFFFE000000000007C000000000000FFFFFFE000000000000000000000F80007FFFFFE01E000FFF8000020000001FFFFFFFFE003FC01FFFFFFFFFFFFFFFFFFFFFFFFE3FFFFFC0000001FFFFFFFFE00000007E00078007FF0000000000000000000001FFC0000000000000007FFFFEFFFFFFFFFFFE00000000FFFFFFF0007FFFFFFFFE0000000003FFFFFE007F
+Output = 0x69089EFFB2D88067BAD3E996C3FE3E4B5E1356F944D2EAC3961911EB571CBF07880982DCF30BA36FBCBAFD59EC91800CD1BAEC49C9D00463680C40B1EE9C62C40039728AA8CCDF2D3C45FA708F8ADA3FC9A9B7C2678A43E7D1A45CA9B8A1440A96CE4385546BD1FE4AF5E6F0AA26C4C47D6627742B87F71AFD44AD1D4EA453EB6F117A361716B6FAFF932119D03DDA627C20EDC8EAFB644C0544E6D61F7789F566CDE6A150BA335EFCBBAEED8FAFE10EF9F70110BB521F8D704F570AED56613EE5DA240E03DDC722958508B67998583FC3EDF8523CE4D4F8D70FCC52025398C59314D9C2D9823A773440381D3798228067BFDCF2E5842C476A8A337C6EAA1BE2B858085F6E3BDFD5FC35E5B0DDFDE73CB34A94673B4414DB574ADEB83477DCEA
+
+Base = 0x5E003FFFFC0000201000FFDFFFF000000000010000000003FF7E03FF803FFF7FFFFFFFFFFFFFFFFFFFC0013FFF000000000000FFFFFDFFFFFFFFF00000000400000000FFF87FFFDFFF84FEC003F0FFFFFFC011FFF0007FFFFFBC00FFE020007FFF6086FFF010077F80008000000000017FFFF10000200000001FBF3FFFFFFFC7FFFFFFF0000000FFFF0001001FFFFFFFFFFFFEFFFFFFFFFFFFFFFFC0000000007FFF0000E008000003FFFFC7FFFE7FFFFF7FFFC0047FF8007F00013FFFFFFF00003FFFFFF403F003F17FFFFFFC3FFF00007FF0BC00000200050207BFFFE0020003FB8000007D7FFC01F7FFC000000005FFFFFF7E0000009E1FFE000007FFFFFFFFFFFC0007F003FFC00000BFFFFFC000FFFFFF400001FF80FFF808C00007F8001FFFFEC001
+Exponent = 0x8000000000007FFFFFFFFFF7FFFFFF0000000000000003FFFF007FFFFFFFFFFFFFFFFFFFFFFFFF8000000FE000007FFFFFFFFFFFF0007FFFFFFFFFFFFFFF80000003C3FFFFFFFFFFFFFF800000007FF80FFC7F8000007FFFFFFF80003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80000000000FE00001DFF0000001FFFFFFFF9F0003FFBFFFF800000F80001FFF81FFFFFFFFFFFFFC00000007FFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFE0000FFF000FFE0000001FC00000000001FFFFFF0FFFFFFFFFBFFF80007FFFE000040003FFF80007FFFFFFFFFF801FFFFF807FFFFFFFFFFFFFFF03FE00000000001FFFFFFFFFE000FFBFFFFFFFFFFFFC0F800000000000000000000000000000007FFF1FFFFFFFFFFE00000383FFFFFFFF7F8001FFFFFFFFFFFFFF
+Modulus = 0xFFFFFF9FFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFFFFFFFFFFC007FFFFF800000000000000000000000003FFFC000000000000000000000000000000FFFFFFFFC000000000000000000007F003FFFFFFFFFFFFFF0000FFF80000003FFFFFFE00000007F80000FFC00007FFF80000000000000000FFFFFE0000000003FC00000003FFFFFFFFFFFFFFFFFFFFFFFFFE000000000000000000000000000003FFFFFFFFF8000FFFFFFFFFFFFFC000038000000000000003FFF8007FF80FFFFC0000000000000000003FC0FFFFF000000000000FFFF80003FFFFFFFFFF9FE003FFFFFFFFFFC007FFFFF8380000000003FFFFFFFFC0000007FFFFFFF81E001FFFFF800000000000000000FFC000000003FFFFFFFFFFFFFFFFFFFFE007F0007F03FFFF807FFE000003FFF
+Output = 0x602AB3BCB7A1FA846AAA1078FB770033FA3EC8DD8DC088B354526BC66B255527729807AA16CECF92586643085ECBF2A1B7DB4BD00E2CB0EB6CB6AA343E73796D65518FDBCB89010105FC43D6062E4F41DFD1B1E6A567271FCD85955088DC167D432281A8CDC4722172C14CB42C9106D1FA60CBE11AB1DF156659E5C335099BDF6CE65B3A8F6C42BCD29879AA5D75BB18F36EFF2E709262E07FE48E251421EF7D94FD38830700428FB2F063261D2326758BC50241770044EEC1873282036F92689F449AB4AEBAF5B3E12E8DC0A5E2806CDDA1D4C41C733CF0C590987B6C2B367E4110E22E7BE9191603388F35175C2CF98DEC9762EC1C411BA21D82AD1E4F715FFCC1F03A10D1249E0A2BE535D10D284BF46006A96DE1A0984472A88DA10B8CF5B2C9F577B53DE818
+
+Base = 0xF7FFF80000080000001FFFF7FC06FFFFFFF800000021FFFCFFFFF80000000007FF00F00003FFFFFFFFF7FF0400FFFFFFFFFFFFFF78E7FC3FFFFFFFFFFFFFFFFF0007FC000005F018000100001FF000006FE00FFE00200F7FFFFF800007FFF800000200003FF7083FF80FFFFFFFFFFFFFC007FFFF001F7FFFC03FFFFF8027FBFFFFFFFFC1FC800001FF7FFFFFFC27FFF0000F8007FFFFFFFFFBE001000018FDF8000000001FFFFFFFFFE070000008FFFFFFFFFF7FFFE7FFFFFFFFFFFFF81807E00003FFFFC7F800007F01FFFFFFFFFBFFFFFFFFFFE020000003E000001FE0000003FFFFFFFF93FFFFEFFFFFFFFFE87FFFFFFC0000FE180100000000000000037C0100FFFFFBEBFFFFC0007EFFFF800001C1003FFFFFF7FFC00007FFFFFFF8000103000000FFE00000003FFFE7BFEF00
+Exponent = 0xFFFFF7000008000000000001FC070FFFFEF800100001FFFFFFFFFFFF000BFFFFFF00F00004F7F7FFFFF8000403FFFFFFFFFFFF7F8087FFFFFF000000000000000407FBFFFFF40058000000001FE80000700000000FF00F8000000000080FF7FBFFFE000047F8003FF80FFFF0000FFFFFC0077FFFFFFFFFFFC010001FFFF7FC000000000004000001FFF0003FFBF803F0000F8007FFF000FFFBFFE1007FF17FF7FFFFFFE0200FFFFFFFDFFFFFF80800003FF7FFFFFFC8003FF3BFFFFFFC07FFE00013FFF003E800007F0A7FFFFFFFFBFFF00007FF01FF00000420000007F000000000001FFF33FFF7F3FFFC1CFFFBFFFFFFEC0000FE48000000000000000003800000FFFFFC07FFF801FFFEFFFFF00001C0FFFFFFFFF9FFC00207FFFFFFE8000107000000C00E000FFBF03FA7DFF702
+Modulus = 0xFF000007FFFFF800000000000003F900000007FFFFFFFE0000000000000000000000FF0FFFFC0000000007FFFC00000000000000007F87FFFFFFFFFFFFFFFFFFFFFFF803FFFFFBFFE7FFFFFFFFE00FFFFF8FFFFFFFFFFFF07FFFFFFFFFF80007FFFFFFFFFFC007FFC007F00000000000003FF80000000000003FFFFFFFFFF803FFFFFFFFFFFFFFFFFE0000000003F8000FFFF07FF80000000003FFFF0000070007FFFFFFFFE0000000001FFFFFFFF8000000000000003800000000000003F8001FFFFC00000007FFFF80FE0000000000000FFFFFFFFFFFFFFFFC0000000000000000000000000C00000FFFFFFFFFF800000003FFFF01C7FFFFFFFFFFFFFFFFFC7FFFFF000003F80000000000FFFFFFFFFE3F0000000006003FFFF800000007FFFF00FFFFFF00000000000000183FF8FF
+Output = 0x4590F092E35B52DAE76DAB8558C493421AEC95969CAE4143C05A8CB9487056A09CE48BB5E2D3D571F79E735C9F8278110E26F4459C4D0554E1E384AA5662D8A87967BDD99B46B76D4EE7563DAAB177647CB97ACA13AC92893849FF48D8A08021AA7BEB179CF80ED2BE82F81DE058A672B4524F795215C599834254659DEEB4B70D2A3D8C9CD4E3AC0D3167E215618C5908E337660ED4AA414B9D3BCB28EC10DC803BA4678425241FEC5258DEAFEB0C877228F1C65FE293AA699DB4D677CB84B1D1D40185CBD7B7FAC8E8DA14D4BBBE808CD106216BD25D9F7DC85EE1FCAB4D63FC5730B51E63870BFD13945D73C97DB2754C6341334BCDBC32FC4756141E1BD2540D29154E5B086C7336F3F99FE0F4035F6ABD40B333C6686E946567060923A525DEF6748CA205CCFC7F53D93CC74206
+
+Base = 0x7800003FFFFFFB00002FFFF0000004FFFFF001FFFFFFFEFFE00000000000E100FFFFF0FF1FFFFEE000003FE400000FC00003FC80000000000FFF00000001FEFFE0001FFFFFFE01FFC00FC00FFFFFFBFFFFFFFF80000000000000F800800000FFFD00007FFFFFFFFFE0000010000700FFFDFFFA0007F800FFDFFFFFF20000FC001F00F7FFFF00BFFFFFDFFC0000007FC003FF3C000000001FFFE00000000004FFFFFE01FFFFFFA0FFC00000020000EC020007FE00000000FFE0000008000000FF0007FE00018003FFFFFFFBFFFFFFF8001FFFFE000000001007EF03FE03FF00FFFFFFFFFFFFDC04FFBFFFFFFFF810000000000000000000FFFFFFFFFBFF080000000000003FFFFBFFE07803FE7FFFFF7FFFFFFC0000FFFC07FFFFFFFFFDFFFFFFFFE0041FFBFF0CFFFFF7FF0001000001FFFF03FFC0000000
+Exponent = 0x7FFFFFFFFFFFFCFFFFF00000000000FFFFF002000000010000000000000000FFFFFFF0FFFFFEFF0008003DE0000010FFF00000BFFFFFFFFFFFFF00080001FD0400000000000001FFC007FFFFF7FFFDFFFFFFFFFFFFFFFE000000F800800000FFFDF0007FFFFFFFFFFFFE000FFFFF01000001F80007F40100000000F00000F8007FFC02FFFF087FFFEFE0080000007FC00007FFFFFFFFFE03FF3E1FFFE00002FFFFE0007FFBFFC2FFB8000601FFFFF201FFFFFCFFFFFFFEFFE0003FFFFFFFFF37FC0000003FFFFFC7FE01FB800000FE0000000180000001FFF7FF03FFFFFD0100000000001EFC05FFBFFFF8FFFFCFFE0000000000000002FFFFFFFDFFFF080000000000000000000FE077FFFFFFFFFF007FC0000001000000000000000003FEFFFFD007FFFFFF00FC0EFFFF00010001FDFFFFFFFFB07F8001
+Modulus = 0x8000000000000100000FFFFFFFFFFF00000FFE00000000FFFFFFFFFFFFFFFF0000000F00000000FFFFFFC01FFFFFEFFFFFFFFF80000000000000FFFFFFFE00FFFFFFFFFFFFFFFE003FF80000000003FFFFFFFFFFFFFFFFFFFFFF07FFFFFFFF0001FFFFFFFFFFFFFFFFFFFFF00000FF00000007FFF807FF000000000FFFFF00000000000000FF8000001FFFFFFFFF803FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000003F003FFFFFFE00000FFE000001FFFFFFFF001FFFFFFFFFFFFF000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFF810FC000000FF00000000000003FC003FFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000F8000000000000000000001F87FFFF800000FFFFFFFFFFFF0000000000000000000000003FF8000000FF00000000FFFF000002000000003FFFFFFF
+Output = 0xA6044FBB3F2891C50C8DA4517E93CC674070C6AA5A639EF40199787250FF6819C6989ED583FE3CBEC61B46BF18DE75F8332E431E4BC942C0324F5300EF40CD12072ADBCB6A33396E8C4069C31929EEC42624117B0D6D05A3C2A90472C3A7989DFFD846FA89B5C908C3E5E61838087679A5BB19E1919BDC50A7203C5AC03ABD3AC717DEF549F58FA683BF56E22E6CB06ED8E8D791DE0F660B2A0B2BF62B1B649AFFDFC2015DD2AA578C2636ACAC4D991C72F19C29C0F9E746A0EACC123A41F18E7F0EB7D8569D12CA2B8EC8E0ED1AC9C495C1377245668D5779A54AEF775D697E83C4A7A51F34ABAC2299EFEC0A96D1CB82C56A499970BCAB59AC201D3781279EED6D43F531D6FFD1C33DDAC0899ADD5C6AEA1FA47F9FF74570AF072BA1213EC740F3D414FBB3FB86C52BD8C15A70DB6036A8CCB61709D0E
+
+Base = 0x7FDFE00FC000FFFF8000001FFFFFFFDFFF030000000000FFFCF0000000002382000000000000007FFFFFFFFFFFF000000F3FFFFFFFC0002FFFFFFFFF8300006C0083FF800000005FFFFFFFFE0801FFFFFFFFFF7C3FC0001FFFFFFF80000004C0000000038000006000FFFF800007FFDE0100000000007FE01FFC007FFFFF80300000000007FEF0020003FFFFFBFFFFFFFFF80023FDFE008DFF7F9F8000100060FF09DE000003FFE07FF000000000F80000000000001F007FFFFFFFFFFFFFFFFFE007FFBFFFFFFF800000201FFFFEFC20000000000001007FFFFDFC0000000004001FD8380000007FFFFE013FFFFF011F80000000000000003FFFFFFFFFFF1F7FFFFE00200003FFDFFFFFF45E0000407F81FFFFFFFFBE7F8000FE00017FEE20002FE000000002001FFFDFF00FFFFFFFFBFFFFFF800000001FF000008FFFF0007F
+Exponent = 0x7F61FC3FFFFC803F8000001FC001FFA000030001000000FFFBFFFF000000040203FFFFFFFFE0003F00FDFFFFFFF0000013FFFFFFFFFFFC200007FFFF83FF8038008000000001FE5FFC000000080000000000001BFE00005FFFFFFF80000003FFFFFDFFFF8000FFE001FFFFFFFFFFC3A000000F8000007FE02000003FFFFFFFB03FFFFDFFFFFFF03E001FFFFFFFFC00000007805FFFF6080FBFC00000000FFFE0F781E0000000005FFFEFE0800000FFFFFFFFFFFFFFFFFFC00001FFF03FFF803FFFC01FFFFFFFFF7FFFFFFFE01E003C1FFC7FFFC001FFFFFFFBFE7FC040000000001FE037FFFFFFF4000000C00000001FFFFFFF000000003FFC003F0017FF1FFFFFFE081FDFFFFFE0000803DFFFF8400003FF8FFFFFDE003FFCFE0000FFF3F800300000000000001FFFE000000FFFFFFBFFFFFFFFFFFFFFFE0002000038000000
+Modulus = 0x801FFFFFFFFF80007FFFFFE00000001FFFFCFFFFFFFFFF0003FFFFFFFFFFFBFE000000000000000000000000000FFFFFEFFFFFFFFFFFFFE0000000007C000003FF8000000000001FFFFFFFFFF800000000000003FFFFFFE00000007FFFFFFC00000000007FFF001FFF0000000000001FFFFFFFFFFFFF801FE0000000000000100000000000000FFE00000000000000000007FFE00001FFF0007FFFFFFFF0001F007E1FFFFFFFFFE0000FFFFFFFFF000000000000000000000000000000000000000000000000007FFFFFFFE0000003E000000000000000000001FFFFFFFFFFFFFFE01FC7FFFFFFFFFFFFFF3FFFFFFFE00000000000000000000000000000E0000001FFE00000001FFFFFFC1FFFFFC000000000000001FFFFFF01FFFF000FFFFFCFFFFFFFFFFFFFE00020000000000003FFFFFFFFFFFFFFFFFFFFFFF000000000
+Output = 0x737615AA5888EB08573DF85C6CDA1E3E7709055F7BF88BEB70F2D9495060A7362845F930AD80EF39952EB32F963ADC354B3AB0AC953E538B7C1248A724427ED5E88FDE3E6FE37588D1D4597126A15D9339E6D6FB19C9D277647BE99A7A8491109FF16DCC0CEA66AE751E912B605EED6BF886D757BAADD5B14F0EAC0C789D8BA7B99602BABD73C0715E24E2CA4716249BE797B71310F17BC3048A1FF0074C02E5D10AF4E527BFA871B4064013623E7D733CFB1A165BB9F60A4FE4FBBBEAB42D52DEF05AD895ABACB2BAF6C886EEB928713208D60332CD08C2F982825FC7676BD45A59B5532DCFC838D5E0B87E2239E3B058124C68C1E62BC19B3DBD49539DD793CFD260E196008FE98D894BCA61E761D246A351E7DC6F90A5277BA0592663BBE2343E70B1C22ADAA9AB3BCDF40A78E9CD57732B9FD77C6AA47C7EE83400000001
+
+Base = 0x800000000000000FFFFFFFFC000003FFFFFFFFF80007FFFFFF800000000000080001FFFFF80000003FF8000FC00007FFFFFFFFF80000000000000003FE00000000000000000000000000000000001FFE007003FFFFFF87F0000000001FEF80000000000000001C0003FFFF800000000F000007FFFFC3FFFFFFFFFFFE000FFFFFFFFFFFFF001FFFFFFFFFFFFFFFFF0000007F807FFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000003FFFFFF800FFFFFFFF00000000001FF3FF00000000000000000000000007C00000FFFFFFFFFFF80000000000000000000000000000FFFE0FFFFFFFFFFF00007FFF00000000000001FFFFFFFFFFFFFFF800000007FFFFFFFFFFFFFFFE1FFFFFFFC03FFFFFFF0003FFFFFFFFFFFFFFFFFFFFFFFFFFFF8000000000007FFEFFC00000C0FFFFFFFFC0000000000000000003FFFFFFE0000000000000000000000FFFFF0
+Exponent = 0x80007FFFFFFFFFF800000000001C000000000007FFFFFFFF00000000000007FFFFFFFFFFFFFFFFF87FFF3FFFFF8003C00000038000000007FFFFFFFFFFFFFFF7FFFFFFFFF80000000000000003FFFFFFFFFFFFFFFFFFFFF8000000007FFFFFF800000000000000001FFFFFF80000007FF80000FFFFFF000007F00003FFFFF800000000000003FFF801FFFFFFFFFFFFF80000000FFFFFF007FF00000000600007FFFFFFFC000FC0000001FFFFFFFE001FFFFFFFFFF8000FF80000000000000000000000001FFFFFFFFFFFE0007FFFFFF800000007DFFFFFF8003800000003FF7FFFFFFF1800000003FFFFFFFFFFFFFFF80000000000000000000001FFFFFFFFF8000000007FFFFFF80000000FFFFFFFC4001C000000000007FFFFFFFF800000000000000000000007C000000000000007FFF0001FFFF80003CC00000000000003FFFFFFFFFFFFFFFF
+Modulus = 0xF800003FFFFFFFFC3C0000000007FFFFFFFFFFFFFFFFFE00FE00000001FFFFFFFFF0000000000000000000000000000003FFC0000000000007FFFFE7FFFFFFFFFFFF80000600000000FFFFFFFFFFFFF8001FFFFFFFC0000000003FFC00000003FFFC0003FFFFFFFBFFFFFFFF00001FFC0FFFFFFFFFFFFC00001FFFFFFFFFFFE1FE000003FFFFFF841FFFFFF800000003FFFFF00007FFFFFFFFFFFFFFFFFF8003FFFFF803FFFFFFFC007FFFFF00038000000000001F7FFFF000000007FFFF001FFF0000006000007FFFFFFFFFE000000000000003FFFFFFFFFFE0000000000000000000000001FFF3FFFFFFFFFFFFFFFFFFFFFC0000000003FFE00000FFFFFFFF80000000000000000001FFFFFFFFFFFC1FC7FFFFFFFFFFFFFFFFFFFFFFFFFFFC000000000000000FF07FFFFFFF0000000000000000000000001FFFFFFFFFFFFC0000000000000000
+Output = 0x30BA003F6CF71E5F4C26352F1CB76AE9853B21A8B7C4F281B1664D42B16F970165E98B230EC981A37F4B9FA4D1B42CFEECC5B188AD8B95DCBBE2AF2C7AF06B8B432CBCA4E97639BDB70393E3C933208CA4D1ECD76EED6B9ED085751FA9F096E7A4382900F5CD9C2F6893251FB4BC94EED3D0B84BD1C72A9B28092E5F6FDF0E7088DAE679A843030C728EA508DC7B111B12D887E39FD8C6CD794B5ED3AC969DB1046D369975AA8431C6EF04B5377251D24598BFB74B0AFD0BAB36E0CD18DF259CBDE98293F79B3662A04DCC4359ECEC70737A57DF3C4CCA9E08E96ABEBEB384960683F50F8BBC6D54AFC0E851EA6ECDA223F907788D93281F48F2460E3EBC262737DD1D92151044B91B5C11374137E16266C20AC64FD897F0360674A4A7CB1144956F84DCCDC202C63F22510A54760DFF11237A4AB18A05F17B61DEDD2B8769740000000000000000
+
+Base = 0x80FFFFFFFFFFFFE0007FFFFFF0000FFFFFFFFFFE0000007FFF8000000000000000000000FFFFFFFDFFFFFFF800003FFE01FFFFFF01FFFFFFFE0000000003FFFC3FFFFFFFFFC000001FFFFFFFF8007FFC000000007FFFFF81FFFFC001FFFFC0FFFFFFE000000000000000000000007F807FFFFFF0003FFFC0000007FFFFFFFFFFFFFFFFFFFC03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000000001000001FFFFF801FFF00001FFFFFFF80007C0007FFE000000000000007E007FFFFFFFFFFFFE3FFFFFFF0001FFFE07FFFFFE000601FE7FFFFE0000000FF9FFFFE0C000FC00000000000000000001FFE00000003FE001FFFFFFFFFFFFFFFFF8001FFFFFFFFFFFFFFFFFFFFFE0000003FFE7FFFBC0000007FF8000FFFF80000000000000000071FFFFFFFF000003FFFFFFFFFFFFFFFFFFFFFFFFFFF000FFFFFFFFFFFFE000FFFFFFFFFFFFFFFFFFFFFE001FC03FFFFFFE
+Exponent = 0x8FFFFFFF00000000F000007FFFFFFFFFFFFFFFFFFFFFFFF0FE07FFFFFFFFFFFF00000000001F80001FFFFFFFFFC000007FFFFFFF000000001FFFE0007FFFF7FF000007C000000001FFE000003FFFFFFF0000007FFFFFFC000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE000003FFFFFF800000FFFFFFFF000000000000007F0FFFFFFFFC000000FFFFFFFFFFE0003FFFFC3FFFFFFFFFFFFFFFFFFFFFE0F800FFFFFFFF00000000FE000000FFE0000000000000F80000000FFFFFFFFFFFFFFF0000000000FFFF800FFFFFFFFFFF00000000000000000000E0000000000003FFFE007FFF003FFFFFFFC00000000000000000000FFFFFC0000000003F8FF80000000000000000000001FFFFFFFFFFFFFFFFFFFFFFF800301FFFFFF0FFFFFFFFFF1FFFFFE0000000000FFFFFFFFE000000000000000007FFFFFFFFFFFFFFFFFE000000000007FFFFFFFFFFFFFF00000000
+Modulus = 0xFE0000000007FFFF80000001FFFFE7FF8000000001FFFF003FFFFF80FFFE00007FFFFF0000000007BFFFFFFF87FFFFFFFF000000000000000000FFF3000000007FFFC3FF0000003FFFFFFF801FFFFFE07FFFFFFFFFFE00007FFFFFFFBFFFFFFF8000000000000000000000001F0000007FFFFFF38001FFFF8001FFFFFFE00000000010000000000003FFFE0000007FFFFFFC3FF07FE000007E00000000000000000300007FFFFFFFFFFE0000000000000007FC00007F800000000007FE0000007F00000000FC0000000000000000000000000000000007FF8000000000003FFF800000007FFE00400000FFFFFFFFFFFFDFC00000000000000001C1FF800000007FFFFFFFFFFF80007FFFFFFFFC3FFFFFFFFFFFFC7FFFC040780000FFFFFFC00000000000000000000000000000007FFF800000000FFFFFFF8000000000007FFFFFE00003FF8000007FFF000000000000
+Output = 0x1A1D55C49F122A6406F9DA836AFAF4FF7D623E270F46E0F3CC869A3DE8CC1142DBC10F0CC90942CE9211928212F3B7424151CA2A00174E8C0D9878336F149B0DFDEA6D6A4EA9D38ABB6B3856102919876ED73778E9894A42C686B1A36B43B972C385CDAAEB5B3F17AA146EB04CD7E31BAE9C61902B6189FA8312D598B395753A1F5991C466F8D44EAA859C0DF7A96CBFD083034B033A4D6700F719C507F34FB7B9BC7DF0ED4113F793E610508507B03D264BE8260D53123DBF6AD0683E06FC5C8593F136299AB01EB96EAFABD7734B6E9CD27AAF18110A8031E083E02955233AF404DE18A9575B70658F3F93A452621324DBF60DB1D6744E18B78E077504485ADDDEB9374FD5426D59C2086A5A31A12E5364B55316E9DDEB8A8198120000D1A32B2E3E923F862C4F52140CBF3489133CECEB2F579E10F9088AA1B71CC785263336617CB335C9AD651C2B000000000000
+
+Base = 0x3FF00277FFFFFFFFFFFBFFFFFF04FFF00FFEF880000007F800003FFBFFFFFFFE000FF3FFFFFF1000001D000007FFFFDFFC1C7C1FFFFE0FFFFC83FFFFFFFFFFFF7FFF0405FFFFFFF00003FFFFFFFFFFEFFFFFFFFF8003FB800000020FFDFF00000003FFFFFFC300000407FFEFFFFFFFFC401CF0000C1F003FE001FFFFFC00207FFE0FF0000000FFFFEFFE08000003EFFFFF801FFF00000000000018008007FE00007FFFFFFEFC7FFFFC00001FFFFF00007F8006FF8004C0000FFF8001FF8003DFFFFFFFFE00FF47FFFC057FFFFBFFFFFE807FFFF80000FF81FB0100000003FFFF800B00000004FEFFF8080007FFFFFFF8027FFFFFF800FFFFFC00FFFFF7FF00000FFFFFF00200FFFFFBFC03FFFFFFFFE3FFFFFFF7FFFE000100F800003FFFFFFFFFFEFFFFFFFD00000003BEFFFFC40000000000007FBFFC000003FF007FF80000000040000002FF800000FFFFFFFF0000000AFFFF001
+Exponent = 0x3FFFFF7FFE780000001FFFC000004000BFF00FFF000000000800200000000001FFFD001DF00000050000001FF80600000000FBFFFFFFFFFFC010007FE00000FE7FFF7FFE0006001FFFF000037FFFFFFFFFFFFFFFFFFF80FFFF700010000FFDFF000007FFFFFFFFFFF0000008FFFFFFFE0000001CFFFFFC21FFDFFFFE000000000081FFFDF0000006FFFFFFFE10FFFFFFF00000001FFD0001FFC0200018000006000001F801FBFF007FFFFC02000FFFFF00007F80057FF800FFFFFFFF80020001FF600000000000FF4007FFF8FFFFFBFE0000207FFF78000107FFFC00FFFF00000001FFFEFFF00000FF01000800000001FDF800800001F7E2FFFF7C01000000010000000000000000FFFFFBFFF2000001FFE37FFFFFF80000100000F680FFC001FF7FFFFF000000010000000FFEFFFFC200FFFFFFFFFFFDFFFC00000000007FF8000000803F0080FF0000000000007FFEC00000070000001
+Modulus = 0x8000000000187FFFFFFFFFFFFFFFFFFFF000FF000FFFFFFFFF8000000000000000001FFF00FFFFFFCFFFFFFE000000000000003FFFFFFFFFFFFFFFF800000000000007FFFFFFA0000000FFFFC000000000000000000008000007FFFFFFFF00000FFFFFFFFFFFFFFFFFFFFFFF8000FFFFFFFFFFFE3000003E000000001FFFFFFFFFF8000000FFFFFFF00000001FF0000000FFFFFFFE000FFFFFFFFFFFFE7FFFFF800000000000000FF800003FFFFF00000FFFF807FF8FFFFFF000000007FFE0000001FFFFFFFFFFF00C0000007000003FFFFFFFF800007FFFF000003FF0000000000000000FFFFFFFF00FFFFF7FFF800000007FF80000007FF000003FF00000000FFFFFFFFFFFFFFFF000003FFFE000000001C00000007FFFFFFFFFF07FF00000000000000FFFFFFFF000000000100003C000000000000000003FFFFFFFFFF8007FFFFFFFFC0000000FFFFFFFF00000000FFFFFFF8FFFFFFF
+Output = 0x2196010A65AAB8185512F7F54C45EF17555A7E9862F67A0A1F3F15A59E9B2C015CADF65A8A3391F48C1B90E3304D52652C77EE666DDB4804A1F6BDB938640C074E45DB6F2680CC763F36371803C50A4B2EF0762F537584267C776AF92B7DFCC09E039E946CAA447B63BBF00EC205DAD8CFEEB6B31B61521836746F97369DC91C5FB71412C7A3CBE2E0E2FCB8154D01CF4CE6A8201E4F59234DE1D1B482D3C6901F94C18DD5F122152E3EA4C019965DBBDC154112644BB481047DEEEC11ED9D9785F52D109CE84E40B4989AEE319FF158A202AFFA7DD520915BAF5E64680E56B09E3E45E2B2482259E19C0C04ADEBDEB78AA6AAB323C165AA07DC729D8E519A07E4F6893456679D1811D90892BBB23EF1532986A0AA0753226351909EE1690DDD0373E7BE71389C7AB9DA7669D023A70C4856A52F524756210BB636BDFF610A79EF6CC6871661A63B811CCDF8559244D69D9DC9F7306D8B63
+
+Base = 0xF80001FFFFFF000007FE000000000007FFFFFFFFFFFFF00000E0000FF8000000000007FFFE00000000000007FFFFC00007FE003F80000000180000078700000000000000000000000FFFFFFFFFFFFFFFF8000000000000000000001FFFC000000000000007FFFFFFF80000000000000007FFFFFFF800003FFFFF80000000000007FFFFFFFFC0000007FFFFFFFFF0007FE0001FFFFF0003FFF8FFFFFFF80000018000000000000000FFFFC000780000000000000007C0000007FFFFFC00000000001FFFF07FFFFFFE1801FFFFFFFFC00007FFFFFFFFFFFFFF07F000000000000FFFFFFFFF8000003FFFFFFFFFFFFFFE00000FFFFFF807FF0007F800700FFFFFF01FFF80000003000000000FFFF800000007FF800000700000030003FFFFFFFF80000000000000000007FFFFFFF07FFFFFF80001FF800000000700000000000003F7FF0000000000C007FFFFFFFFE1E03FFFFFFFFFFFFFFFFFC7FFFFFFFFFFFFFF
+Exponent = 0xFC00000000000007FFC0000000000FFFFFFFE0003F83FF9C03FFFFFFFFFFFFFFFFFFFFFFC00000007C00000003FFFFFC00007FFFFFFFFC0003FFFFFFFFFFFF00001FE7FFFFFE0007FC000000000001FFFC0000FFFC000007FBFC0000001FFFFFFC000000000000000000001FFC00000000000000003F7FF803FFFFF81FFFFFFFFFC00000000003FFFC0000000000001FFFFFFFFFE000000003FF000000007FFFFC03FFFFFFFFFFFFFFFFFFFFFC00000003FFFFFFFE0FFFFF03FFFFFFFFC0000000000000000007FE3FFFF01FFFF000001FFFFFC001FFFC0003800001FFC0000000000FFFFFFFFFE01C1FFFFFFE000000000000000000001FFC0FFFFFFFFFFFFE03FFF8000000000000000000FFF0000003FF8000000000003C0003FFFFFFFFFFC3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC00001FFFFFFFFFFC07FFFFFFFFFFC0000000000000000003FFFFFFFFFFFC000002000000000000000007FFC0000001
+Modulus = 0xFFFFFFFFE000000001FFFFFFFFC0000000000000000000000E0000000000000001FFFFFFFFFFFFC0001FFFFFFFFFFFFFFFFFFFFFFFFDFFFFFE00000000000003FE00000001F01FFFFFFFFFFFFE000000000000000000000001FFFFFFFFFFFFFF81C000000000001FFFFFFC0040000000010FFFFFFFFFFFFFFFFFE00001FFFFFFF800FFFFFFFFFFFF07FFFFFFFFFC000001FFFF000E1FFFFFFE007FFFFFFFFF8001FFFFFFFFFFFFFFFE03FFFFFE00000001F0007FFFFF00003FFC003FFFE0000000003FFFFFFFFFFFFE00000000007FFFFE001FFFFFFFFFFC000000781FFFF0FF80000000000001FFFE00000000000000000000001FFFFFFFFFFFFFFFFFFFFFF801FFFFFFFFC0000001FFE0000007FFFFFFFF0000007FFFFC000003FFFFC000000000000001FFFFFFC1FFFFFFF8000000000000F801FFFFFFFE0001FF8003FF8000C00000FFFFFFFF81F80000000007FFFFFFFFFFFFC00000000000FFFFBFFFC0
+Output = 0x64A5A8E09269320707696F543089B99F410A884614AA30B168B3DD7D8B2A2AD4FB6CDC8E17F64D0D2DE9EAEEC9B1ECC4138ED434D6DF3B32008C964EE9BDDF079740071C3D473DB851A35D5CF737B331CB207D0925FB0BEAE7EED05BD0D3D99966D29E1CDFD716032A737A5680D9FE954310F692F869A9C48F0A4962049279C7B37978D3B48FE34451735E998DD340B42366516D298258590F5EFBDC71146FADFA8F038BE88554F0CEF543886D73EF613A1506B9A560C0254C123DCB8E230BB72EF405A32F1FFF5A58BBCC363F211B63FAA901D0FFAA2FCFCE0BE2762C13B2E23D54D4720A131F00C1E0D12FF6B65F3D39E6C499702E47DF51466753A77917279D25D8E327C89271ECD896FD59F4E5B8EAC9B22B70B29952A948E24F5E1185611F6EE99B4DD9EE68F66897DD8D29631F61960E406E061A00975CC59F7B0B744988E5FBE98F539BF8CB0983FE378B8F5D3806F03EBD0D653B6DC0D10C0B2D87BF
+
+Base = 0x800000000000FFFFFFFFFFC00000000000FFFE0007FFFFC000FFFF00FFFFFFFFFFFFFFFFFF00000000FFFE000000000003FFE00000FF01FF80FFFFFFFFFFFFFFFFC0FFF000000000001FFFF800000FFFFF00000000001FFFFFFFFC00000000FFFFE000000000000FFE00007FFFFFF03FFFFF1FF84000000FFFFFFFC00000FE00000000000001C00000FFFFFFFFFFFFFFFF000007FFFFFFFDFFFFFFFFFC0FFC0000000000008000000000E00FFF000FFFFF00000070FFC0000000003FFFFFFFF8000000000000000002001FFFFFF8000000FFFFFFFF00003FFC000000000000000000000000FFFFFFFFFFFFFF00000001C000000000001FFFFFFFFFFFFFFFFFFFE3F0000000007FFE00FFF001003F0FFFFFFFFFFFFFFFFFF000FFFFF8000000000000000000007FBFFFFFFFFFFF0000000000000000FFFFFFFFFC001F8000000000FFFFFE000000007FFFFFFFFFFFFFFFFF3FC000000000007FFC000007FFFF1FF818000000000000
+Exponent = 0x8000000000FFFFFFF000000000000000003FFFFFE0000000007FFFFFFFFFE0000000000000001FFFFFFFFFFC000000000073800003FFFFFFFFBFFFFFFFFFFF8001FFFFFFFFFFFFFFE00FFFFFFFFFFFFFFF000000007FFFFFFF8FFFFFFFFFFFFF0000001FFFFFF800007C000000000000001FFFFFFE000000007FFFFFFF8000000007F80000000000007FFC00000003007F8FFE0018000000007FFFFFFFFFC0000000003FFFFFFFE0007FFFFFFFFFFFFFFF801FFFFFFC00000000000000000000000FFFFFFFC0000000000000000003FFFFFFFF00000000000000000003FFFFFFFE0000000000000000703FFF9FFFE000007FFFFFFFC00001FFCFFFF0000000000000001FFF800000001FFFF9FF8007FFFFFFFFFFFFFFE0100F800000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC07FFFFFC00000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0000000000001C00000003FFE7FFFFFFFFFFFFFFFFFFFFC00000000FFFF
+Modulus = 0xFF8000000FFF8000003FFFFFFFC00000003FFFFFFFFFFFFFFFFFFFFFFF000000003FF0000000000FFFC0000000000000000000000000000001FFFC00003FFFFFFFFFFFFF800000001FFFFFFFC003FFFFFFFFFFFFFF0000000FFE07FFFFFFFFFFFFFFFFFF003FFFFFFFFD000000000FFCFFC0FFFFC000000000000000000000003FC0000001FFFFFFFFC003FFFFFFFFFFC000000000FF80000001FFE000000003FFFC00000001FE03FFC1F8FFFFFF000007FFFFFFFC00FFE000000000000003003C000001E003FFFF800000000000000000F000000000000001F80000000000000003F0000000007FFFC0000007FFFFE00000007FFFFFFFFFFFFFFFFFFFFFC0001FFFFFFF003FFC00003FFFF000003F801FC0003FFFFFE000003C0000001FE0000000007FFFFFFFF00000000000007FFFFFF8703FFF807FFFFFF0000001FFFE00007FF00FFFFFFFFFFFE0000000000007FFC0FFFFFFFE2000003FFFFFFFFFFFFFFFFFFFFFE001F9FF
+Output = 0xC7C289E19E6D62C485659B9992C4723D81C8F7BCC21B38FBD22E50D9FFA869518CB39368ECC82F5FCB2545536E5977114A3B2E804F43D44FEC458DA4743144AF4124A09F00453C3099DB8FC638D504AF1CA5EFC41A3ED17BD2CC211B78D47D0B76AA6FEEE1EAC41FDDA5151F9B75759A8246D5CF5988A8EAACE5B3ED183486EB5996D322B3DBC46224F32FEFE08D606300A6EB0C94DA1585B56A187CEC5DB5A2FE2D4D60DBDA63C5491D7536D8E2D1ECABC31AB5A3D5CD7B789BCB144BF2B1C7103B91146611D5CD38B55A643335D040BC8897E448CCBAC6B9323D046ED3646F792301A994BBAA28FEF02E17D09E44945EB7A1D339EE88FCB192567B1B33E6780C6FE7B47C5DBB7E3883EBB698E1A21653C299110CAEB704040C80B96EB84BAC4B606E8AD3B823BDD41D59EFB81ACD978BA277AC9A190B600D85A478F13779C2D2C35EC56D3AFA6FA4E2AAE34006B91BCABB3EBB926673070CD1FC23BD6A87868462BD751ACA1B77
+
+Base = 0x7FDFFFFFFFFFFFFC00001F9006FFFFFC001FC3FFFFFBF0000027FFFFFFFEFFFFFFF8000000002000FFE0FFFFEFC027FFFF600001FF87FFFFEC0000701CFFFFFFFF987FC003FFFFFFFFFEFFF1FFFFF4FFC8487FFC3FFBE000041FFF7FFFFFFFC0101FFFFFFC01F7E00007FFFC001FF7FFF007FFFFFFFC0000001FFFFFFFFFF7FFFFF8F0040000703FFFFFFFFFFFFFFFFFFF1FFFFFFFFFFFFFE3FFFFFFFFDF0080FFD8000001FF00100007FDFFFFF00001FFE020000F7FFC000037FFFC000011F800E3FEFF0027FFFFFFDFFFFC00080007DFE7C0080007FF80FFF7FFFFFFD78000083FF7FF803FFFFF9007FE0000000007FFF800000FFFFFFFE008000007FFBFF03FFBFFFFFFFFFFB800DF8003FFFFFEFFFFFFC000001FFF80000803FFFFD7C80000001FFFFFBFC003D8184000007FFFF000000007BE40000FF007F7C801FFFFFFFFFFFFBFFFFBFFFFFFE8000180000000000000003FE000FFFF980FFFFFF7F8807F80000000000F800003FFFFFFEFFE20
+Exponent = 0x7C001FFFFFFBF8041F8FFFF00003FFF0040001FBEFFFFFFFFE000000FFFFFFE7F00000000000FFFFFFFFEFFE1FFFFF8400000007FF000FFFFF800FFFFE00000870000003F000002EFFFFFFFFF8FFC067FFFC3FFFE40003FFFFFFF01FFFC00FEFFFFFFC02F7FFE017FE0000000001D017FFFFFFFBFFFFFFFFFFFFFFFFE0000008F003FFFFFFF80000000000078000000007FCFFFFFF000000007FFFD00000FFF80080000000000007FFFFFFEFFFFFFF00200FFF8000000008000002000DFC3FFFFF000007FFFF000FF01C0007FFFFE007400002077F810007FF000FFFFFF0003FF8000040000F60080000000FFFFFEFB8000000003FC00017FFF7FFFFC000400BFFFFFE0FFF77E0FF7FE000003FFFFFF00FFFFFF0007FFFF8000003E847EFFFFFFFFFFFFF8005E017F80000800000001FFF7FFE0000FFF207FFC001FFFFFF000FFBFFFFF800F0000800017FE00000030FFC00400FFFFFFFF80FFFFFF6107FFFF000200007FF7FFFFC000007D00001
+Modulus = 0x8000000000000003FFFFE07000000003FFFFFC0000040FFFFFF80000000000000007FFFFFFFFFFFF000000000FFFE000007FFFFFFFF800000FFFFFFFF0000000000780000000000000010000000007003F980003C0001FFFFC0000000000003FF000000003FE07FFFFF80000000000000FF8000000040000000000000000000000070FFC000000000000000000000000000000000000000000000000001FFFFF0007FFFFFFFFFFFFFFF80000000FFFFFFFFFE000007FFFFFFFE7FFFFFFFFF000000000FFFFF8000000000003FFF800001FF83FFFFFF8007F0007FFFFFFFFFFFFFFC007FFFFC000007FF7FFFFFFFFFFFFF807FFFFFFFFFFFFFFF8000000003FFFC004000000000007FF007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80000000838000000000000007FFC1FE7FFFFFF8000000000000001FFFFF00FF8003FFE000000000000000007FFFFFFF7FFFE801FFFFFFFFFFFFFC00000000007F0000007FF80000000000000007FFFFC0000000FFFFF
+Output = 0x55AE83755308541AED5330D0A04ACB420E15CE04D2DB7249159D373021A96B614C8A1F761ACF8AB84908BF5A07CEB7DC6765D2BAC899C35BABB3E73A7E8F920EA314F7BFF5C114DB10B0BAA6B4724AF2169EA608DC82CC48BF6D74D1DF5F99BFDF0C002408FFF4375DA1BC8BAF7AA415A99653E76A01BA161AF4301314A2EA7DE933313AEA303243C76234BB053BCF1ADA548BC607C28F5B87765ACF8C58F71BDE00748D251EF53DA39AC03C09BED0B25D251FEDE761E43E9CFECBDDE33912157953947D84BE354A19055F82D1664FA24350FF86B6CD0D3938A8006076CB546484ABA793DCB459F027D69D4DFB18788CA4C110F8E293C72190451A09555D32EE55732DAEDE7AF03EF251FE54477FE53DA46874EA7D1F41F88E32A608B800926EA74A2C35601ED3E1E3798E9E5F132019549FE610617F2F04D4AFC0A510E0216FEA295CF2C58F8939AEA783C3CA1D214B626044507889100D8DFCAC1B377BA0947F32400042956803AFE56260A33E6EB3
+
+Base = 0xFFE3F000000000003F800FC0000001FFF00FFFFF003FC0000003FFFFFFFFFC00000000007FFFC0000000000007FFFFFFFFFFFFFFFFFFF000007FFFFFFFFFFFFFC00000000000000003FCFFF00003FFFFF00000000000007FFFFFFFFFE0000000FFFFFC00FE03FFFFFFFFFFF8000FFFFFFFFC0000000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0000000000000000000000003FFFFFFC1FFFFFFFFE01FFFFFFFFE000000000000000000000000003FFFFFFFFFFFFF8001FFFFFFFFFFFE00000000000FFFFF80000007FFFFFFFFFFC000000FFFFFFFFFFFFFF800000000001FFFFFFFFFFFFFFFC00000003FFFFFFFC00000003FF00007F80000000000000003FFFFFFFFFFFFFFC000000000000000000000000007E0003FC7FFFFFFFFFFFFC00FFFFF8000000000000007F83FFFFFF9FC00000000000038000007FFFFF3FF3E000000000000003FFE0001FFFFFFF03FFFFFFFFFFFFFFC3FFFFFC03FFE000000000000FFFFFFFFFFFC01FFF80FF
+Exponent = 0x8001FFFFFE02003FC00607FF00000000001E000000000000000000000000FFFFFFFFFFFFFFFFFE00000FFFFFFFFDFFFFFFFFFFFFE00000000011E000000000000001E000000000000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE00001FFFFFFFFFFFFFFFF000007FFFF80000000003FFF0000000000000000000000001FFC0000000000000007FFFE0FFFFFFFFFFFE0000000FFF800000000006007FE007FFFF0001FFFFFFFE0000001FC000000000000001FFFFFFFFFFFFFFFE000001FFFFFFFFFE0007FFFFFFFFFFFE00001FFC000000000000000000000003E00000000FFFFFFFFE00000000000201FFFFFFFFF0001FFFFFFFFFFFFFF00FFFFFFFFFFEFFFFFFFFFFFFC0000000000000FFFFFE000001FE0000007FFFFFFFFE07FFFFFC00000003FFFC3E00000001FFFC00000000000001FFFFFFFFFFFF8001FFFFFFFFFF000001FFFFFFFFFFFC1FFFFC003E03FFFFFFFFFFEFF00100000FFE001FFFC000000001E1C0007FFF000000FFFFFC0000000001E00007FFFFFF
+Modulus = 0xFFFF0000000007FFFFFF001FC1FF00000000FFFFFFFFFFFFFFFFFFF8000FFFFE01FFFFFF80000001C000000000000000000FFFFF8000000000000000FFFFC0000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFC01FFFFFFF8000E00003FFFF00FFFFFFFFFFFFFFFFF000000000003FFFF0000000000000000FFFFFFFF000000000000000007E07FFFFFFFFFC000001FF8FE000000000007FF7FF00000FFC000FFFFFFFFFFFFFFFFF0C000FFFFFFFFFFFFE000C00000000000FFFFFFFF00000000001FFFFFFFFE000003FFFFFFFFFFFFFFFFFF87FFFFFFFC00FFFFFFFF000000003FFFFFFFF803FFFFFFFFFFFFFFFFFFFF00000000060000000000007F800000010000001FFFFE00FC0003FFFEF03FF80000000FFF000000000000000000000000FFFFFFF87FF0000007FFF00000000000FFFFFFFE00000000F8000000FFFFFFFFFF800000000000FFFFFFFFFFFFFFFFFF000007FFFFFFFFFFFFFFFFFFFFFE
+Output = 0xBF1A9DAB7FF993B3ACCC9A3A4F72BF10BAB92CA6EC455E3485532BA244618E577D820B55284F7B1DE11F50C35EAE76B7978B4B40FDC9199619DA62437351812DF3DB67DD46A187A8B364A2DFBC9F1E44CE6F35162B24635E24940E2854D8B04792FD5498E6ED669E50DB74ED8CDA1A8BE8E158F96F233E4AB1F3C7B5D1F69C2F0690BE46F4E5E3ACCFB1173FE555AB2D8C2C98DB7C2162443C4DD794474B9BABB2A8C9E687F9AF9352C6CC74003DB4529BC40BB57132F829ECF985CA54A308698956ACC6C8085E272279C563678BB44FA3A4661CDAF6EB675330C54A04C5E7BE9CF975319ED2D3A0B50C6232F515AB4499F216A75135E233C91D0516F8FC07E22FBE7B189A5098CB05D8F7FA53EE4F843F002E5CE0B2270415E93B0DDD63FB1981C175C8F92383C6103A5EC8A1235805F32D8292494EE3557DFF4D7DEDE9FA19D61EBF21B3E4A423C2C020935C0B13E40118BD7C2DB8CB356A8C085AA42BA479CFD3127FD25BCD9418A1A2097CA3B401BB35AC8F72BE2185
+
+Base = 0x8000000000007FFFFFFF80003FFFFFFFFFFF8C1FFFFFFFFFFFFFFFFF80000003FFF07FFE000FFFF1FFFFFFFFFFFFFF8FFFFF8000001FFFFFFC000000003F800FFC1FF80000007FFFE0000000000000000003FFF800000000000000000FFFFFFFC000000000000000003FFFC00007FFFFFFFFFFFFFFFFFFFFFFFFFE0000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000000003FFFFFFFFFFC0007FFFFFFFFFFFFFFFFFFFE000000000000000003FFFFFFF80003E003FFFFFFFFF00000000000000000003FFFFFC00007FFFFFFFFFC000F8070000000000000FFFFFFFFF800000007FFFFFFFFFC0FC007F87FFFFFFFFFFFFFFFFFFE0FFFFFFFF8000000000000003FFFFFFFF83FFFFFF80001FFFFFFFFF807F001FFFFFFFFFFFFFFFFFFFFFFFFFFF80000007FFFF8071800003E00007FFFF8007FFFFFFFFFFFF801FF007F8000003000007FFFFFFFFFF80000000000000007FCFFFE00001FF007FFFFFFFFFFFF9FF80000003FFFFFFFFFFFFFFFF800000007FE00000000001FF800000FFFFFF
+Exponent = 0x40003FFFEFFFC00001FE3FFFE40000000000A7FFE008000000003FC0007FFFFFFFFC2000000000000FC000000FFFF801FFFFE07FF7FFC020000001F00001FBE0FFFFFFFFFF7FE00002000037FD00007FFFFFA00200003FFEF8005C000F81FFFFFFF7F000000FFFFFFFC03BFFFFFFFFFFFFFFFFFFFFF09FFDB8003FFFFF10800000000800100003FFFFFFC0003FFFFFFFFFFFFFFE007FFFFFFFFC1FD002000000BFFFBFF9FC00189BFFFFF00000003FF7FFFFE00000001C0000000401FFFDFFFFFFFFFFFFFFFFFF80000020000000000000000FFFFFFFFFFFFF001FC00000001EFFFC5FFFBC003FFFF071BFC00004FDFFFFFFFFFFFFFFFFFFFC003FFFFFFF000001FFE0002F63807FFFC00017800011000005F800000000107FF7C0037FFFC01001FFBFFF01001FFFE00001FFFFE00003FF0FFFB840008037FFE00002000000F8EFFFC4071FEE00100000181FFFFE000000007FFFFFDFC100040FC3FDFFFF002000004000000000000FFE7FEFC0003FF7C01FFFFFFFF80040000040007E200000
+Modulus = 0xBFFFC0000FFFFFFFFE01FF801FFFFFFFFFFF18001FFFFFFFFFFFFFFFFFFFFFFFFFFFE00000000000003FFFFFF00007FE00001F8007FFFFFFFFFFFE00000003FF0000000000001FFFFE000007FF00000000001FFE00000000FFFFE000007E000000001FFFFFF00000000003FFFFFFFFFFFFFFFFFFFFFFE00047FFFFFFFFFF3FFFFFFFF7FFFFFFFC00000000000000000000000001FF8000000003E00FFDFFFFFF8000000603FFE78000000FFFFFFFE00000001FFFFFFFE3FFFFFFFC0000000000000000000000007FFFFFE00000000000000000000000000000FFE03FFFFFFFE00003E000040000000000003FFFFF02000000000000000000000000000000FFFFFE001FFFE01C7FFFFFC00007FFFFEF000001FFFFFFFFFFF00007FFFFFFFFFFFFFE000000FFFFE000000000000000000000000007FFFF8000001FFFFFFFFFFF000FFFFFF80001FFF0000000000000000000000000001FFFFFF80000000000FFE00000000000000000000000003FFFFFFFFFE000000007FFFFFFFFFFFF81C00000
+Output = 0x6A3605D5AD653A163E6ABA8ECC5889600D74B1F553D59197C8C0E6C248CDEDE0BE83715303432D794DFDA205DEEFD271EF865E24D1E7C8ACFA761FEE2CD6D6EC60E5FE412C28A522B33F98DB52002F4B83FA91BCB5A7C27EB3232B5E90CB813954D711776E119907C4EF27CC20E35B928C6548236E45FC17074827A94980A85B12485C9FE9FCDFA4C86090153850FECD957DF08ABF3B9182106B4901CB807B098B1C6096C9762E4A248E2823AF0C7CBBD5DBFBDD2BD6CAA63F88C71EC4B3500128E3060A53ED35B197B72ADB5A309B658A9CA92FB0BCFF2AC6DDAD2E7861D044E9DD5DB97B08DBE4FC3402BACC682C8F57952A8C0461121B40876E59D4D4FBC9F7F34EAA9F27B158CADACA73258AC0A76D4F9C0EB07102E12A8724B1EAB7E373E29CD6885576E2BF996B73C032836193963815388A54226B1CDC18D4E83FE203BCC9A95EE130B0016B6730B87C0D6838815ABA73883D9C85423281C2CB332EF259797162E7D5DA1B09392E8819B8D9685B259FE64835372183E6989002C00001
+
+Base = 0x800037FFFFFFFFFFFC00000000000000000003FFFFFFFFFFFFFFF01FFFFFFFFF03FFF8000000000C0000000000000FC000000000000003FFFFFFFFFFFFFF800003FFFFFFFFFFF00000000FFFFE07FFFF00000000000001FFE000000900000000000000000FFFFFFFFFFE000FFFFFFFFFFFFFFFFFE000001FFFFFFF0000000003FFFFF000001FFE000001E00007FF800000000FFC000001FE0000001FFFFFFFC07FFC000000000000000FFE00000007FFFFFFFFFFFE0000000000F0000003FFFFFFFFF007FFFFF0000000FFFFFFFFFE0000000FFFFFFC000FFFFFFFFFFFFFFF80000000000000007FFFF80000000001FFFFFFF000000000003001FFFFF00000000000008000003FFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000001FFFFC00001FFFFFFF00000000FFFFFFFE00000000003BFFFDFFFFFFFFFFFE0001FFFFFFFF000000000000000000000001FFFFFFFFFFFFFFFFFFFFFFF800000000001FFFFFFFFFFFFFFFE003FFFFFF7FFF000003FFFFFE0000007FFC000003FFFFFFFFC000007FFF80000
+Exponent = 0x800007FFFFFFFFFFFE00FFFFFFFFFFFC000007C0FFFFFFF0000019FFFFFFFFFFF00007FFFFFFFF8000000000FFFC000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01FFFFFFFFFFFFFFFC000000FFC00000007FF007FFF80000007FFFFFFFFFFF00007C300007FE000FFF87FFC00007FFFFFFFFFFFFFF800007FFFF000000FFFFFFFC7FFFFFC07FFFF8000000007FCFFFFFFFFFFFFF007FC00000FFFFFFFF8000000380000000003FFFFE007FFFFFF8020000000000000001FC07803FFFFFF800001FE03FFF80000010000000FFFFFF0000007FFFFFE07FFFF00000000000007FFFC03E3FFFFFFFFFFFFF800007FFFFFFFFFFFFFF00007FFFF007FFFFFFFFE00040007FC00003FFFFFFFFC0000000003FFFFFE0000000000000007FFFFFFFFE03FFFF8000000FFFFFFFFE7FFE7FC07FFF0000000000000001FFFF81F80001FFFFFF8000000000007FFFFFFFF800000000000060000000FFFFFFFF800000007FFFFFFFC00000007F800000000007FFFFFC00007FFFF8007FFF80000000001F8000000000000000000
+Modulus = 0x807FFDFC00000000000000FFC0FFFFFFFFFFFC007FFFFFFFFFF803FF000000FFFFE000000000000007FFFFF8000007FFFFFFFFFFFFFFFC00000003FFF000000001FF800001FFF8001FFFFC0FFFFFFFFFFFFFF9F000007E03E000040003FFFFFFFFFFFFFFFFFFFFE0FFFE0FFFFFE1FFFFFFFFFFFFFF003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0000007FFFF800000001FC00000000007C0000003C03FFFFFFFFFFFFFFC03FC000000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFC000007FFFFE00000000000000001FFFC000003FFF9FFFFFFFF800003FFE0000000001FFFFFFFF83C003FFFF8000000000000000001C0000004000000000000030000001FFE00FFFFFFFFFFFC0003E000003FFFFFFFFFC003FFFFFFFC0003FFFFFFFFC0000000000000001FFE07FFFFFFFF80803C0001C07FFFFFFFFC1FFE0003FF0001FFFE00000000000FC0000000000000F00000000003FFC0000000000000000FFFFFFF800000001FFFFFFFFFFFFFFFFFFFC007FFFFFFFFFFFF8003FFFF0000200FFFFF
+Output = 0x67D1D0026D86BE1ACA337BFF2CBB2A6621A59D44D8CE09D82FA834F6714F4784C1C4A06BD73D4DD7EFB64B692A38B8E6A27423E60AD8F2C0A72AD3BDA651B12073B1010F13A4212638C6FC706620C36AE36A37AEF399D3CD95CE7FBE5A2A97E17F289B70532D258834B673A6178A33A2D31A193E95A0E4AC428D2B384197131386844DCBFD0070A9CC985C22C2947EF36FE3F63BC53B930B150FACA29142E0282E3A16ABDB99148572C515E3CDE09AACCD2B818237BCDBA78B89A848A4C69DE303F9FD75D3918F2E4A1E0B20620C732F421285AB99CA51C83B0BCA342F4578B162CE939528E00CF000E4CB660E6F645BEAA5D9E0B5CC742E0D2F41254C584C396AB987CF27D41F0A6EABD060849DEE5BA5690526A2D454F59645F9DDD730CFCF6885A7C920EA18BD64DA5294833188E8659C3E51E474B430FF8938D44EF18724934ED7ACE13076231FC311802FC989FBAF5F203707350FC4D1545FDDD19D9EC8FEA4FF3462FF849570D6CC2CC0E8E739ABC94B3E625E552768E5D2C9B0E1692769ED2084CD03A279
+
+Base = 0xFF03C000000000003FFE7FFFFFFFFE007FF801FFFFFFFFFFFFFFFFF83FFFFFFFFFFFF800000000003FFFFE00000000000000003FFFFF8000000FFFFFFFFFFFC00000007FFFFFFFFFFFFFFFFFC00000FFFCF01FFFFF0000002000000000000000000001FC00000FF80FFFFE3FFF8003FFFFFFFE00001FFFFFFFFFFE000FFFFFFC00000FF0000000003FFFFFFFFFF0003FFFFFFE00000000000001FFE00007FC0000000000000000000000003FFFFFFFFFFFFFFFFE00000000007FFF00030000000003FE007FFFFFFFFFFFFFFFFFFFFFFFFFFFFC003FFFFFFFFFFFFFFF807FFFFFFE03FF80000000000001FFFFFFFF0001FFF801FFFFFFFFFFFFFFFF00000FFFFFFFFFFFFE0000000000000003E00FC000000001FC0000000000FFFE000000000001FFFFFFFF80000780000001FFE00000000000000000000000000000000007FFFFFFFFFC000000000000000FFFFFFFFFE00001C00000000000000400000000000003FFFE001FFF8000003E00000001F0000001FFFFFFFFFFFFFFF00000000000000000003FE0000000FFFFFFFFFFF800
+Exponent = 0x9FFFFFFFFFFFFFFFE00000FFF83F003FFFFFFFFFF0000000FFFFFF0000001FC0000000FFFFFFFF000000000000FFFFFFF00000FE078000FFFFFFFFFFFFFFFFFFE00000FFFFFC00FC7FFFFF000700000001FC7F00000000FFFFE000FFFE000000000007FF000000000FFFFFFFFFFFFF00007FFF00F000000007FFFF00000000FFFFFFE0FFFFFFC00000000FFFE0000000000FFFF8000FFFFF801FFFFFFE000000003FFFFE00000000000001FFFFFFFFFFFFF000FFFFF003E00000000003FFFFC0000000FFFFFFFFFFFFFFFF3FFFFFFF8000003F00000000FFFFFFFFFFFFE1FFFFFFFC0000001FFF00000000FFFFC00000000000FFFF00000000400000000000000000000000000000000000FFFF007FFF07F000007FFFFF8000000000000000FFFFFFF8FFFFE0000000000001FFFFFFFFFFFFFCFFFFFFFFFFFF0003000007FFFFFFFF0001FFFFFFFFFFF8000000000000001FFFFFFFE00007FFFFFFF000000038000000FFFF8000FFC003E00000000000000000FFFFE00000000000007FFFFFFFFF0FFFFFFFFFFFFFFFFF00000001FFFF
+Modulus = 0xFFFFFFFFFFFF80FFFFFFFFFFFE01FFFFFFFFFFC000001F80000007FFFFFFFFFFFFC01F800000007FFFFFFF801FC001FFFFE0007FFFF8007FFFFFFFFFFFFFFFFFFC00007FC000000000000000FFFF00000000000000000000000000000000007FFFFFFFFFC003FFFFFFFFFFFF0000000000000000007FFFFFE0000000000000000001E07FFFFFE3FF0000007FFFFFFFFFFFFF000FFFFFFFE0000000001FFFFFF03FFFFE7FFFFFFFFFFFFFFFFFF00000FFFFFFFFFFFFFFFFC000003FFFFFFFFFFFFFFFFF1FFFFFFFFFFFFFFFF00000000007FE000001FFFFFFFFC3FFFFFF800000FFFFFFFFFFFFFFFFFFF8007FFF00007FFFFFFFFFFFFF80000003F00000FFFFFFFE3FFF8000000000000000000000007FFFFFFFFFFFFF80000000007FFBFFFFFFE00000000FFFFFFFFFC0007FF000000000000000FFFFFFFFFFFFFFFFFFFFFF8000000000000000000000007FF800004001FFFE780000000FFFFFFC00000001FFFF800000000000000000007FFFF9FFFC00000000000000003FFFE0000000000000000000001FE07FFE00000008000001
+Output = 0xFC3FD62974E1B93FC05EE93E0322EF83E459A7867C134C571FD0429B01AE4E34DEB1EAC7598D7F48713F9FC517C039339638E7B4710FDFFB15E0629815CA4BD496B2AA40931D8CB6F0EA884BDBD93DEFF778AAD185A20F5451C1B10A0448ED238996430B7A2CC77EB26F8133A73988F5D9D6218ABB220C05D5B15302ECF9249E9768EE346DDC1B30163788269820EB375C4430E694BB3152D7E8E9474E7DE9A30B9EFA054D896373503E6A3C903C5B17B03937B69EBFDFD2C4FFEAD66B18E88A8666FE2A914F86BE1623EC9546443790236516EF99A3ECA6C2227C43B31D32AB34066CACB67456C5E3A4DAD22370C343E8372C4F2373D6C8667F9CFAA478AFF33DC072753A37868EEBC5E7151F827F190FED6C67D34C233EE7E0652A1C63A89C27EAB2228B604FAF17B24A692DB75C88220FB79E3990A36096562E3C1DB7EF33E5186FD55DF2BE47201A962E7A37471A80E7838DB40E5F6449A8AD5ADF358572FE84F4D6F6DBBBF03C790C10E1F66B9A8420D905CEF84BA18A15599C4F57B2EC4D2F40C851E3F9C72A572CC3A2B1FCB5
+
+Base = 0xFFFFFFC0000000000000004000000000000007C000000000000000000001FFFFFFF1FFFFFFFFFFFC0FFFFFDFE0003FFFFF80000000FFFFFF0FF00000000003FFFFFFFFBFFFFFFFFFFFFFFFE00001FFFFFFFFFFFFFFFFFFC0FC00000007FFF000003FFFC00000001F000007FFF8000000FFFFFFFFFFFFFFFF801FFFC00000FFFFFFC000000000000003FFFFC07FFFFFFFFFFFFFC0007FFFFFFFFFFFC0000000000007FFFFF03FFC001FFFFFFFFFFFFF800000003FE0000000007FFFFFFFFF00000000003FFFFFFFE00FFFE00007FFFFFFFFFF00000000000000000000000000000000003FFFFFFFFFE000000000000000001F803F8003FFFFFFFFFFFFFCFFFFFFFFFFFFFFE07FC000003FFFFFFFFFFFF0FFFE000001FFFFFFFFFFFFF80187FFFFFFFFFFC00000003FFFFFC7C00000000FFFF8003FFFFFFFF0000000000FFFFFFFFFFFFFFF078000000FFFFFFFF80000000000003FFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000001FFFFFFFFFFFFE000003FFFFFFFC0000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFC000000000
+Exponent = 0x800000000000000000000000000000003FFFFC00000000000000000000000000003FF80000000013FFFFFFE00000000001FFFFE7F80000000003C01FFF7FFFFFFFFFFFFFFFE0000000000000003FFF8C0000001FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000007FFF001FE000000000000FFFE00007FFFFFFF8001803FFFFFF80000000000000001FFF000000000000000000000000003E00007FE0003FFFE000001FE0000000E00000001FFFFFFFFFFE00000F00001FFFFFFFFFEFFFFF0000000000000C0FE007FFFE1FFFFFFFFFFFFFFFFFE1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0007FFFFFFFFFFE0000000000000001FFFC000003FFF001FFFF8000001FFFF00000000000000000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFE00000001FFFFFFFE000001FFFFFFFFFFFE07FFFE000FDC01FFC00001FC003FFE000000000000000000000000000FF001FF80000000000001C0001FFFF80000003E007F00000000000FC000000007FFFE0000000000007FFE03FFFFFC000007FE00007FFFBFFFFFFFFFFFFFFFF000000001FFFFFFC000FFFE00003FFFF
+Modulus = 0xFFFFFFFFFFFFE0000000007FFFFFFFFFFF800000000001FFFFFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0000000000000F0000000000000000001FFF8000000003001FFFFFF0FFFFFFFFFFFFFFFFFFFFFF00003FFFFFFFFFF000000000000FFF00000000003FFFFFFFFFFFFFF800000FFF000000000000007FFFFE000FFFFFFFE0FC000000000000000071FFE000F00000FFFFFFFFFFFF00003FC00000003FFFFF000003FFFFFFFF801FFFFFFFFFFFFE0003FFFF80000001FFFFFFFFF80000000FF800000000000000FE03FFE00000001F000000000000000000000000FFE00003FFFFE000FFC00000FFFFFFFFFE000000FFFFFFF800000000000000000FFFFFFC00000000000000000000000000001FFF00000000000000000000000000000000F9FFFFFF00001FC0FFFFFFFFFFFFF00003FFFFFF8000000F0000000000000FFF00003FFF3C03FFFEFFFFFFFFE0000001FFFFFFFFFFFF800007FFFFFFFFFFFFFF000000077E3FC0000000000000000FFFFFE000000000001F003FFFFF0007FFFF800003FFFE000000000FFFFFFC000000FFFFFFF07
+Output = 0x107230CAE6343199EB2BB3B5F632585B8CA622E2E9F2BC44DEDFC6AB7A3346A35D4BC709623D15D78F882DC6EF0C3C92012BBFF679B6468ADF4D0260132C3990FA708ACBF30E00587074DD82C516B7928F6BC529796756D79780A81616B0543AC5E8993A9256641A858416701B3968E17816002A5EAAD50D86DA0C84432224CAF3BA63F9D58B325A15C41638956E15305778DA3881763C184ABE2EE152F5F47FA095FCBF7BFD47D9D9DBB1DB22B1884F11C9A6A048C5DCC05D40B01E3085918168DDB6500BD72D026C3657B703852770D041976CA4BF782EDAC2BE6BB79A857A15741EE0C8BFD742D78EF2AD32C30D61A8F10F1DB7521750DC1B60A5EA167B2BF8A7C7A4E311DF998EB2CA8516D4CCC695B56EA9D5C2209DB0C73C246056D9066BEDD1E9DBD070CFE10FC047C13682D8B55A1FA64F885CCC1B3440264EF244AC64F841275E2D94F0471F0B5684868AE259CCD0CBD1D5043AE13B0A371A713A582832D0C880FC254EE051B13D94178A3230BE379D4DFC63B301A9D1E7CA2F8768A8ECBA449277833D1E265D411066BB22F06C81C30D640A1A
+
+Base = 0x7C000001FFE000000000007E00000001FFFFE007FFFBF88000000008000000001FFFEFF9FFFF0005FFC00001FEFFFF8800001FF600000007FFC00000000000003FFFFFFC00100007FFFFFFF80FFFFFFB81C03FE80000000001FF7C00002005FE07800200007DFFFFFFFFE005FC00007800001FEA000000FFFFFFFEFE0800000600FFE0001FFFFFFEFFFFC046000000001FDF000000000203FFFFF801FFBFFFFFE080000000000000000201FEFF7FFFFFF0080001FFEFFE000000000A000000000000000FFFFFFC01DFFF0000000000FE0F000201FFFC00300001F807FFFFFFFFFFFFFFFE0FFFFFF600000007FF81FFFFFFF000803FFFFF8FFFFFFFFE01FFFFFFFFFFFF8601FFFF000000000100001FFE0003F800FFFFFFF7FC07FFF80000000001FF9681FFFFFB05FFFF6001001FFFFD3FFFFFF87FFFFFFFFD000000000FFF7FFFFFFFF6000000003F0000007FFFFF8000FF00F802FE8000000007FFFFFB81F8000000000000080001FFE7F7F9FFFFFFFFFF81000000000000EFFF45F00010000F800007FFF81FFFE0000001FFC000000000007D00000000083FFFF817E1FFFD
+Exponent = 0x8003FFFFFFFFFFFFFFFFFF80000000001F8000000000FFFFFFFFFFFC000FFFC000000000000000000FFFFFFFFFFFFFFFFFFFFFFC000000001C0000083F8000F8000000000000000000000003FFFFFFFFC00000000000000001FFF803FFFFFF00000000000000000000700003FFFFFFFFFF000003FFFFFFFC07FCFFFFFFFFF80001FFFFFFFDFFFFFFFFFC0000FFE00FFFFE000803003FFFFF000003FFFE0000000003FFFFFFFFFFFFFFFFFFFF00003FFC00007FFC00000300000000000000000000000001FFFF000001FFE003FFFFFFFE00000000FFFFF800000000000000000000000000000000000000000000000000000FC07FFFFFFFFFFF1FFFE0000000003FF000000000000000FFFFFFFFFFFFFC000000000000FFFFFFFFFFFFF80000001FFFE0000000000000000003FFE0001FFFFFFFFC00000000FFF0000000000001FC7F8003FFFFFFFFFFFFFFFC000000000000001FFFFFFFFFFFFF0003FFFFFFFFFFE3FFFFFF800001F801FFF3FFFC003FFFFFFF83FFFFFFFF80000003FFFFFFFFFFFFFFFFFFFFFFFFFFE0000FFFFC000000000003FFFFFFFFF9FC000000000000
+Modulus = 0x83FFFFFE0000000000000001FFFFFFFE000000000003FF80000000000000000000000FFE0000FFFE003FFFFE0000007FFFFFE001FFFFFFFFFFFFFFFFFFFFFFFFFFC00003FFF0000000000000000000007E7FC00FFFFFFFFFFE007FFFFFFFF801F87FFE000000000000001FFE03FFFF800000000E0000000000000001F8000001FF0000000000000000003FC1FFFFFFFFE000FFFFFFFFFE00000007FE000000001F7FFFFFFFFFFFFFFFFE0001001FFFFFFFFFFFFE000001FFFFFFFFFDFFFFFFFFFFFFFFF0000000000000FFFFFFFFFF01FFFFFFFE000007CFFFFE00000000000000000001F0000001FFFFFFF8007E0000000FFF800000007000000001FE00000000000000000000FFFFFFFFFE7FFFE001FFFC07FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8FF000003FE00007FFF00000000FFFFFFFFFFFFFFFFFF0000000000008000000001FFFFFFFFFFFFFFFF8000007FFFFFFFFFFE01FFFFFFFFF80000007FFFFFFFFFFFFFFFF800000000000600000000007F0000000000000FFFC1FFFFF00000000000000000001FFFFFFE003FFFFFFFFFFF81FFFFFFFFFFC00000001E0003
+Output = 0x4FB1251FED28CE97078E03819045E845234F163ADB951D9287313EEAB8E4F0275245189668BB139CAE4A223BE83A7AD75EAA5EB7CB5292648695EEE8E27AAAC68D343B436468DAA01B57BCB84F663C12CB26C8FA1084A7D0E82F58E690C3B7F4F7EBC39E301567E0C6FF7852426E7A36E5E572C75EDEC802BCADB5DC1BA3CD2F67D08956A8CAADA4EEB0C6BDAFB54748E9234FFF30BC618B7D023F9C3E167239915900CAFAFFC47FF86871E0C9137757433F7FEB9B16EF7E6253EDE318B99A14F664E1D015C0F5B72A9C601AD0E7579878B5329992A3C62C7BBE268679D345A1760B0CF7E02FADB1E96783DA73258DC11A391A87B21E756D9039E2E8916425073D8CA4EA16AE7E76842F4753E1ACAFD3C6526C7C02499AFCF88CED58D98F8C29DCE5EB9ABEF1FE7A1AEE11F8A68B32FCAD7720992C0ABF574AFEB7C8B76A6C6F19F54E51529C688349CAE116B131D399A6A5171C04552FEFB5D123BCD20971D1AB410EFB99E31258768058820E5CD2501EE5232CD25903B6E713CB65F99BE864E5C2B778FF2462917AFC47024111A12BFAACB36DFBB7DF24A99E8EEE1BEE1A18
+
+Base = 0xFFFFF00000FFFFFFFFFF0CFF0FFEFFFFFFC10FFE00000FFFFFFFFFF80003FC003FFE0C00000000DF8004000000020001FFFFFEFFFFFFFE0003FFFBFF803FF887FF800FFFFFFFFFFFEFFFFBC00000000000000400010000C03FFFBFC00800000000000FFFFA001FFC7C1181FF800003FFFFFF8003FFFF3FFDFFFFF000000380000021F000FF03F700038003FFF82003FFFFFFF7BFFF8000000000FA3FFFFFFFFFFFFF8800003EFC000800007FFFC07FC0000000000000001000FFFBF80000000000000001E1FFBE0001000000000013C000600FFFBF000400008000000000000F7FFC13FFFFFDFFFFFFF0100000FFFFC000EF0020000003F60800211FFE2003F7FFFFFBFFFFFE0023FFFFFFFF9F000003FBFE12FFFFFFFE0010007FFE007FFFFFFFFFEC05FFFC3DF0000013FD1FFFFFFFFFFC00FFFFC010001FE0000000000E0000000FFFE1F800FFFFF80FFFFFFFFFFFBFF01000007FFBFC0000100000001F800000FFFFFFFDFC0400000001FFEFFFFFFFFFEDFFF0000FFFFFFE13FF000001FF8000100000000FFF000003FFFFFF0001FFDFFC07FFFFFBFFE00004001FFC0C0801FFFBFFFFC01
+Exponent = 0xBFFFFFFF800000000000007FFF8000001FFFFFFFFFFFFFFFFFE000007FFFFFFE07FFFFFF80000000001F80006000001FFFFFFFFFFC000000000007FFFFFFFFFFFFFFFF8000000000000000007FF0000001FFFFFE7FFFFFFFFFFFFFFFE0000000000000007FFFFFFFE00018000000000000000000000000000000000000000000000000007FE000000003FFFF80000000060000E0703FFFC0000001FFFFFFFF00000000000000007FFF8000000000000041FFFFFFFFFFFFFFF8000007FF8000007FFC0000000000000003FFFC7FFFFFFFFFFE00007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000FFFFC3FFFFFFF00000000000007FFFFFFFFFFFFFFF80FFF0FFFFFFFFFF9FFFFFFFFC0000001FFFFFFFFFFFFFC07C0003FFFFFFFFFFC0000001FFFFFFFFFFFFFFFFFFFFFC007FFFFF800000003F803FF80000000041FFFE000007FFFFFFFFF00000000000007FFFFFC00000000000030000000000007C000000000000007FFFFFFFFFFFFE00600007FFFFFFFF07FF3FF00007FFFFFF0FFFFF007FFFFFFF800000000FFFFFFF803FE0007FFFFFFFFFFF0000001FFFE07FFF000000001FFF80000001
+Modulus = 0xFFF000003FFFF0000000000030000000FFFFFFF0001FFFFF00000000007FFFC03FFC00000000000001FFFFBFFFFFFFE0000000000FFFFFFFFFFFC0004007FC007800000000000000000100003FFFFFFFFFFFFFFFBFFFF00003FC0003FFFF80000000000000001FFE003FFFE0000FFFFFC0000007FFC00000001FFFFFFFFFFFC7FFFFFE0000000FC00FFFC7FFC0007E0000000000040000003FFFFFFFE000000000000000000000003FFF80007FFFFFFFFFFFFFFFFFFFFFFFFFFFF0003FFFFFFFFFFFFFFFFFE20003FFFFEFFFFFFFFFFFC000000000000FFFBFFFF800000000000007FFFFC0000000000000FFC000000003FFF00FFFFFFFFFC01F8000FE001DFFC08000003FFFFFFFFDC000000007FFFFFFE0001FC00000001FFF00000001F800000000003FC000001CFFFFFFC01E00000000003FF00003FFFFFE000000000000000000000001E07FF000000000000000000000FFFFFFF8003FFFFFFFFFFFFFFE00000000000000003FC0000000000100000000003FFFFFFFFFFFFFFFC00000000007FFFE00000000000FFFFFC000000FFFE000003FC000003FFFFFFFC000003E3F8000003FFFFFFF
+Output = 0xFFBB29EE587F62695D6255BC2AF965340BD8D64E40DB9A6B1282DCEC26CD4D05C41DBB489A37CFB556F1848FAF48D98B6A0863F27C414A9AB8F23906D808EB1E8F22C35275388F88C26DA46BB666E710103DA2FEDC6287FB53C6CD22681F51689D5104355822C8866F950A18BD2C77CE6B12692BADC2C4C89A5349260AA928CAFD1885942EE851AF9E7AB6798AB727953B2987AEA14FC6111AB9859F4B9FAC8CC81CA27739D688B739CB4ABA72405B3D283E4FB17C715314152CA69057470BAE9FC836AD9480AA49874416F830B65FFE8AD8418D5D7BE931DF88FAB039BBEB3131E423421138CA0259FAFA192E9D1481A00C4897601B32CB5263603A1DEA1A370BA2801D78458C7C21B2916353BD470278D7404AA6C39C90E5B8AF46700B4002E1A7B7454ECFF846AE3B6A82A37E532012E5D0EB28B8ABECCD36A20393B00E80D0CD69711F6010522FA29572A294E3AF98B72C2F1022C7285571AB82250F34FB5FA7605DB6116E38E8902B125B919F079F2C1DB66F957D3E479AAA0B1BB297E415B70D70EB105560DD2A18699CE0AADF6E1C8A2463BC075592FD96F1BD8F6F4D3FF47C7089CE111A
+
+Base = 0x7FFFFFFF8000FFFFF60000007FFF8000081FFFFD80007F02001FF00780000001FFBE00027FFF807F7FFE1FE00000000FFFFFFFFF8000FFFE0FFFFE02000000038FFFFFFDFFFFF8000000000000000000000FFFFE0401FDFFFFFFE01183F8000000003FFF8007FFBFFFFFFFFE0407FFFFFFFFFFFF9FDFF000000000047FFFFE007FF7FDFD800083FFFFE0007FFFFFFFFFFFFFFE0207FFFFFDFFF40DFE83FFFFFF603C00007FDF0800FFFBFFFE0403FFBC7000100F00000000100000007FFFFFFFFFBF0FFFFFFFFF01FFFFFFFF8003FFE07FFFFFDFF001C7FFFFFFFF003FFE00000000FFFFFFFF7FF1C00002000007FFFDFFFE00079FFFFFCF80007FFE00000001000FFB7E7FFC01FFFFFFFC7E83EFFFFF840FFFBE00FFFFFFFFFFFFFE001FFFF800000F01FFF80105FFFFFFFF8FFFFFFE0000FFFF7E000401DFFFF00277FFFFFF80003FFD800003803FC000FFFF80000000000001E000FFF3FFFF0017B47FFFFFDFFFE0047800001FFFFFFFFE000001FFFEFC02000007FFFFFFFFFDFE0000000000040000780000003F801FFD800FC000004E00FFFFFFFFFFFFFFFBFE000037FFFFFFFF0080000000000E01FFFFBFFFD
+Exponent = 0x800000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFF003FFE00FFFFFFFF00003FC3FFFFFFFFFFFFF81FFC7FF9FF03FFFFC1FFFF0000FF000000FFFFFFFFFFFFFFFFFF800000FFC000000000000000000000000000008007FFFFFFF0000000FFF01C0000000F000000007FFFFFFFFFFFC000000000001FFFFFF803FFFFFF81FFFFFFFFFFFF00007F08000000008000000FFFFE000700000000000000000000000000FFFF0000FFFFFFFFFFFFCFFFFFFFFFFFFFFC00000000000FC000000061FFFFFFFE000003000C00800000000000000000000000000000001FFFFFF80000007FFF7FE001FF03F000003FFFFFF0FFFFC003FFFF8000000000000000007FFFFFFFFFFFC00000FFFFFFFFFFFFFFFF03FF800000000000003F800003FFFFFFFFE0000000000007001FFFFFFFFFFFFF00000000000003FFFFFFF000FFFFFE0000000000007FFFFFFFFFFFFFFFFFFFFF0000001FFF000000FFFFFFFF8000003F0033FFFFFFFFFE3FFFFFFFFC001FFF800001FFFFFFFFFFF0BC001FFFFFFE00000007803FFFFFFFFF00000000001FFFFFFFFFFFFFFFFFFFFF000000000000FC0000000FFFFFFFFFFFFFFFFFFFFFE7FFFFFFF8007
+Modulus = 0xF800000007FFF000007FFFFFFFFFFFFFFF80000007FFF80FFFFE000007FFFFFFE0001FFFF80007F807FFFE01FFFFFFFF0000000007FFFFFFFF00001FFFFFFFFFC70000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFE000000001FF07C07FFFFFFFFC0007FF8003FFFFFFFFFFC00000000000000601FFFFFFFFFFFFF800001FF800000007FFFFFFFFFFFFF8000000000000001FFF8000000000FF1FF800000007FFFFFFF801FFFFF0003FFFFFFFC003F8FFFFFF07FFFFFFFFFFFFFFF800000000000FFFE000000FE000000007FFC001F8000001FFFFFFC00000000FF80020000000000000000000FFFFFFE00000000000001FFF87FFFFFF07FFFFFFFFFFFFFFFFFF003FF8003FFFFFFFFFFFF800000007FF0003FFFFFFFFFFFFFFFFFFFE00007FFFFFFFFFFFFFEFE0000000070000000000000007FFFFC0000000FFF80000000800000007FFFFC7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00C00000000001FFF87FFFFE000000000000000000003FE0000000000000001FFFFFFFFFFFFFFFFFF87FFE000007FE0007FF03FFFFFC1FF000000000000000000000007FFFFFFFFFF8000000000000000003FFFF
+Output = 0x8664581289BB709FD02F26DA3014FF0F4EEF5C942FCE9378C5C7933AB15B9EA1BBC86BB7E617169EDCA5A67D187ECA07815AFBC4B3AD4733A6A4B73EAD4361C62C383F22F4E35F5362F769DC26C077C70B126CFFF841E299C211A0BA3EE5895089B563D2F9BE8B247AF1F1493B91AF7556E488AB0F95575A9ABDC31B6FBA2E2D93CF6D3EA6587F4B44DC7A8FDDB1257E65764620BE3E23B55CEAEDD8CE882E77ED0BF38028A6D280AE944C544BB481A37D216DFBA635A650CDAD5FC229D29524045A9BEF88CA39978F3CC08ED03E884286B08BA74823FF88E42E29E2A27FEF7303829082AC6C71E1B29E4B8F4698A32C6E3DD9D894F335FF289EFF8844D609283D10E825A9B96F6A24B2DA5080B3BDB0E089D9DA137D69C3CBFF51858B1F5AE55D580B4F46F3360F2F46BF0381C7F5C44823C0EE4EF960E5236072FF3077D844EFEE9B265E3D1FC260A22C53719A3090981D3E4F734745C0FAED7FEF3AEED53103ED2019DB7B24FFCBDF35828310DFEC62F8DCCDB7B123DAA25B7F1D7AF8B0814F19483BE9828C57EF1E4DD03862A7684990A28B90FA507514101B1FC431D5C260F9D84C93B666D4425098325AAD0E27
+
+Base = 0x5FFFE010FBFFF01000007FFFF7FFFDFFFFE00007FFFFFFFFE01000FFFB00000000FF80BFFEFFFFF3FFFFFFC01FC0000000FFFFFFFFFFFFFE0003FFE1030FFFFF87FFE003FFFF7F7C001FFFFFFFFFE08000FFFFFFFB003FFFFFF00000000087FFFFFFFFFF01FFFF000083FFF7FEFFFF801B80000000000FFFFC1FFFF0000000BFFBFFFFFFF8000400000007C102FFFFFFFFFE00003C03FFFFFFF0000003F800001FFF801E0081FFFFFFDFFFF01F0FFFFF00000000037FFFFF000F001800FFFC7E00401FEFFCFFFF8007000000000000000000020003FF07FFF800000000FFFBFFFC7FF7FFFF3C0000000081FFFFFFFFFFFF00000001FFFFF0001FFFFF00FE1FFFFFFFFFFC3DFFFC00000000000C00000001007DE00103FFF003FFFFFE84FFFFFFFEFFFFFFFCF0000000000000004007FFFFF7E00001000003FE8801FFF73C00000000080000FFFFFC0003FFFFFF00000FFFFFC00003F0000FFFFFFFC038047FFFFFFFF8FFFDFFFFFFE10000000000780003000FFFFFFFFFF7F001000002FFF00100FFFFFFFFFFE000000FFFBE0C0FFFFFFEFF008000FFFFFBFFFFFFC003FF9000000000FFFF8FF8000000003FFB0000007F00000000002000
+Exponent = 0xFFFDFFEFFFFF40000007F07F5FFFFFFFFFFFFFFFFFE0000000FFFFFFF0000000000007FFF000007FFFDFFC3FFC00000790000007FFFFFFE00000000F710000000000000006F7FFC0020000000005FFF810001FFF90000000000000000007FFFFFFFDFFFFF0000000003FFF802FFFFFFFF80000000000FFFFC1FFBF00000087FFFFFFFFFF800000003FFF8000EFFFFFF7FFFFFFFFE0000000000000000007F805DFF802DC201FFFFFFFFFFF01F0F7FFF000000000203FFBF0000F818FEFFFC0001F01FF0017FFF400700000000007FFFC20001FFFFFFFFFFF7FFFFFF80FFFC3FFC800000013C0000000001F00E0FFFFFFEFFC00003FFDFF0001FFFFF20FE1FFFFFFFFFFF7E00000000F80003FE00000000FFFE00011FEFFFFFFFFFFF8101FFFFFF00000000EFFFFFFFFFFFFFFE4000000FFFDFFF00FFFFFFFF08003FFF4BFF400000000000FFF000001FFFFFFD00800F8001FFFFFFEFFFF00107EFFFFC03FFFFFFFFF90003EFFFFFE2800000FE03FFFFFEF010003EFFFFF80200FFE000FFFF0000FFFFFFFFFFE00015FFFFC000100007FEFE013F10FFFFDC07FFC0FFFFFF0FFFFFFFFFFFFF8FF8000000003FFF0000000000000000011FFE
+Modulus = 0x80001FFF00000FFFFFFF800007FFFFFFFFFFFFFFFFFFFFFFFFF0000000FFFFFFFFFFFF8000FFFFFC0000003FFC3FFFFFFF00000000000001FFFFFFFF00F000000000000000008003FFE0000000001FFFFF00000000FFFFFFFFFFFFFFFFFF80000000000000FFFFFFFFFC0007FF000000007FFFFFFFFFF00003E0000FFFFFFF800000000007FFFFFFFC0007FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0007FE1FFFE00000000000FE0F00000FFFFFFFFFE000000FFFFFFE7FF0003FFFFFFE00FFF00007FF8FFFFFFFFFFFFFFFFFFFE000000000007FFFFFFFF0003FFFF80000000C3FFFFFFFFFE000000000000FFFFFFFE00000FFFE00000FF01E0000000000001FFFFFFFFFFFFFFFFFFFFFFFF0001FFFF000000000000007F00000000FFFFFFFF0FFFFFFFFFFFFFFFC0000000001FFFFF00000000F8000000C3FFFFFFFFFFFFFF0000000000000000FFFFF000000000000FFFF00000000003FC000000000700000000001F0000000000000000FFF00000000007FFFF000000FFFFFFFF00000000001FFFF000003FFFF0000000FFFFFFFF000003FFFFFFFFFFFFF00000000000007007FFFFFFFFC000FFFFFFFFFFFFFFFFFFE000
+Output = 0x305812C1FFA07ACEF1C5F669CEB336F0AC59737F1E1A6984AE51F2B5318D7B71042B45BCFC2F237529B3C3D6729380F36B95B575B353A349F2A84A99E07D19A060A41185A3355EF82E7D55CFDB69A3F776AB7F828074D7ED1E7526B22E8B49A1A468B63262F784E2C47865BA154FC89BD945CD7CEB0B9E59B342BCF270DCE4AC44340D6C1BA96EC2E817A4C0D74905F4D154DE514AD4E68BE46089559ECE0B8E82B2D4536221C4EFD2ECD7B2FF2000FE97B9945A362FD65BD2A31811B8F78B0A67586DC117698473E519145139B4D65C522DDC8A0E8481D5F5FBF5344B5130CF5EB34FA41746DDDC3183F009774E53D156BDB64857314689B92C991D3B719CB9777A3094763BE5F91A8B885A98B9487276ACB38C67AF8C72FD7ED11318E38CD6123CE94CD583A7B02477884432249B4B6715C3095848985D0C3A56A3A5D502C60F1E822675220D9B704BEF1AD1822190EC966F09FB12D6F13E0C44059C75BCD7A135A906E9D677A3DF2EF2880DB28F165B369963128F99D6099F312CB95A4AEE6F2DDD11CAA5CF4A44E85039B2586C2A7617CAA7BCE4C78F260A8BFAB265AD9BD64DA9AE65EFF19EE2C7978970E44493D7F928FB4F57C000
+
+Base = 0x1E0000000010000001FFFFFFFEFC00000003FFC781FFFFFFE1FFC0000000001FFFFFF02001FBFFFFFFFFFFF00000000007FFFFFFF9FFFFFC04800F01FF60000021E0000005FE82FFFC10380007C0400005FE000007F85FFFE81FFFFF08FFE00000008000760000000000000400000000FFFFFF8000001FF7E000000100700FFFFFFFFFFFFE0000000001FFFFFDFFFFFF07FFFFA001FFFF7FE007FFFFFA000007C01FEF00000000008000003FF600000000003F8002000000007FFFFFFFFFFFFFFF3FC000000003FFFFFE000007FF7FFFF800000009FC0000FFEFFF8009FC0000001FFF7FFF00000400003FFFFE00000201F0000809FFFFFFF7CFE0000000003FFE000000001FE000007F83FFFA0000000DFFFFFFF820FFFF8000007FFE1FFFF800000000F8FFFFC0267FFFFFFFBF880000F1BF3FF800040000007FFFD9F9000007FFFFFFFC3FFF800001DFFFF203FFFFFDFFC03007FFFFFFFF821FFFFFFFFFFE003FDE0021EF0001FE8000FFF67001FBFFFFFFF0027BFFFFFC1C00000407FFDE0000007C01FFE0007FFFFFFF8000000800000000060FF80007FFF80006007FFFF000060045FFCFFFFE3FFFFFFE00E00002000000000000000000FFFFF7FFFFF
+Exponent = 0x7FE000000000FFFFF0200000FFBFC00000003FFC785FFFFFFE1FFBFF80400001FFF806FFFFDFC1C0003FF00000C000E000000FFFFFDFFFFFC00BC001FFFDC001001FFFFFFFE007F00000E000003FFFFFFFDFF000004003FFEF02FFFFB05EFE000000008007DFFFFFFFC000803CFFFFFFFFFFFF003FFFFEFF880000000FFE0000000007FFFFBFFFFFFFC02000001FFFFFF80000000020000205FFFFFFF820003F7C01FFF07FC007FFFFFFFFC4001FFFE3FFFFF8000020000000FC003FFFFFFFFFFF7FFC000000803FFFFFFFFFFFFFD900FFC00000005FFFFFFFFFFFF8001FC0000001FEF83FC00000004003F7FFE00000181F50017F3FFFFFBFFCFC1FFFFFC004001FFFF000000007FFFFF7FFFFE00000001FFFC001C2007FF8000007FFA1FFFF801000000F80000FFFEFFFFFE03C0000000FECFFFF3FE000000007FFFE5F8FFE0000000FFF847FF7FFC01FFFFF5FFDFFFFE0100300C3FFFFFBF80200004007FFFFBFFFE0001F00400FE0004FFFE3000FC000001F005FFFFFFFBE0000003FFFFE00000000005FFC0017CFFFFFFFCC01007F8000000020FFFFFFFFFFFFFFA00800003FFE00006000FDFFE4000000200E00001FFF000000003FFFFFFFFFFFFF0000
+Modulus = 0x801FFFFFFFFEFFFFFFE0000000003FFFFFFFC00387E0000001E003FFFFFFFFFE000000FFFFE03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFE000003FF800000001FFFFFFE00000001FF80FFFFF000000000000001FFFFFFFFFFC0000FE00000FE001FFFFFFFFFFF81FFFFFFFFFFFFFC000000000000000000000007FFFFFFFF000000000000000001FFFFFFFFFE000001FFFFFFFFFFFFFFFE0000001FFFFFFFFE0000003FE000FFFFFFFFFFFFFFFFC001FFFFFFFFFFFFFFFE000000000000000000000000003FFFFFFFFC000000000000007FFFFFFFFFFFFE0000000000007FFE03FFFFFFE0007FFFFFFFFFFFFFC00001FFFFFE7E0FFFE7FE00000000303FFFFFFFFFC0000000000000000000007FFFFE00000001FFFFFFFFE000007FFFFF8001E00007FFFFFFFEFFFFFFFFE1800000003FFFFFFF003FFFFFFFFFFFFFFF80001E0700000000000003C0007FFFFE00000E00000001FFFFCFF0000000007FE00000000000000001FFFE0FFFFE01FFFF0001CFFE03FFFFFE0FFE00000003FFFFFFFC00001FFFFFFFFFFE001FFF81FFFFFFFFFFFFF80000000001F000000000000001FF80000000000001FFF00001C0000001FF1FFFFE00000000000000000000000000000
+Output = 0x7E8C223035E7B3B02E1524B26C3AD755E9B80670B423F1B4B431586C615DDE0866645A58785399B55D1233B398F149ED9381A164289C47E13D92F5378F88D898EA639B54CE9A6CA38C633858EF732C413172C9C1F336BD94946D2CC0F25407536D47F568AF38B3248DB9393A5B8B612AEC95957193B049BEB7F276DD6BB7ED81AE002BDDFB7899FA0C04F2A35477102551376EE5B93A67E259DA63F28112742117F2329937A890E526BBB7F3CA20E10A3B8E96A333BD482DEC8DD88A74F4CC953BBC28330A3A6E59D8DDC9A4B9E8CE2858346ED84477544C5C7B7A341618809E2408634CFCF417CF5EAB225DED2DB6378B6DB21563B669778E5D38D0C6F65087A64DB6E08A7CE82B155758B1527D9A5370B5E99C79C6631CDB75779080592968C602EE180C62626DE766BBCFC4E72575E96E3958DECFDE6D76D3E46473EB7F10A52BCB4F889E1C55CDBCC27AA6E80B31A2434282C56B51CE5F2BF370F965F66C95ADA683A1722F32A086FE0C99C23D3F00A22508E8140DF2F97C287F9D4CB6119BB774DAF02C4DCEAA301CFB505A809D51D18E89397C335AC7476ADBCB368301A19D309E96F80E74C974423DBD3030203ECEB312CA9820002FFFFF8000000001
+
+Base = 0x1FFFFF7FFFC000001FF800FFFFC000BFFFFFF001FFFFFF9000BFFFFFFFC000001FC00002003FFFC7FFFFF00000BFFFFFFFFF00FFEF00000007FFC000000000017C04000000FFFFBFFFFFFFFF800000007FFFC0000040000000FFFFFFE0FE00BDFF00003FFF0000003FFE0001FFFEFFFFFC00060040007FFFE00000000001FFFFFFFFEFFF8103FFC1FFF7FFFFC10000000000001077C1E000000000FFFEFFFFFFFFFFFC000F3FF00000000000003FFFFFC1000000000870000000E00000FFFFFFFFFFFFFFFFC3FFFFFFDFFFFC013FFFFFEFFC100000FFF07FFFFFBFF81F3FF01FFF08007FFEFFFFE1FF8000207FFE1807FF00003FFFFFFFFFFF0003FE5FFFFFFFFFFFFE00010001FFE1000000000000000000003FFF00000000FFFFFFFE7FFFFFFF7FFFFFFBFF00704001000000000001FF2007FA1100007FEFFFFFFFFFC007E01C2000000000FFF41F8001000007FBFF021FFFD002E001FF0001FFFFFFFFFFFFFDFFF00000000087FFFF00FFFF7FFC00000000000201FFE00FFBFFFC000000000003FF000800FFFFFC0000FFDFC0001000007C6000FC0020003F7FFFFFC00001FC0000007FFFFFFFE04003FFFFBFE00FFFFFFC1FE7C0001C00007FFFFFC007FF80401FBF0100000
+Exponent = 0x400007FFEFFC000003FFFFFFFFF4200FFFC7EF00203FFFF8FFF803FF80020000007000040003FFFFFFFFFFFFFFF40000000BF00FFEC00000007FFC0000000000178440000005FFFC000000000380000000000000000BFBFFFFFFFFFFFFFFE1F7FFF600000008000001FFDFFC2007EFFFFFE10060000007FFFDFFB800000123FFFFFFFFFFF8003FFA27F78000000000000006000100041DFFFFF8000800000C07FFFDFFC00003FF00000000000003FFFFFC801FFFFFF88800000000000007FFFFFFFFFFC1FFF4403FC0000007C003FEFFFF07FEFFFFFFFFFFFFFFFFFF8003FF0000000007FFDFFFFE0000000200F7E20000001FFFFFFFFFFFFFFFFFFFA807F0000007FFE00000003F020001F80000000000000FFFFF07FFFFFFFFFFFFFFE7FFFDFFF800000047F00305FFFFFE0008FE001FFFFFFFE10FFFFFFFFFFFFFFFF007FD01C1FFFFFFFFFFF7FFFFFE0FFFFFFFFFF01FFFFEFFFDFFFFF0005FC7FFFFFFFFFDE00000000004007FFFFFFFFFFFFFBFC0FFFFE60007A07E00FEC07FFFFFFFFFFFF80000E0060FFFFFC0400FFFF40008FFC001F7FFF84001FFE400000003FFFE2FB000000FFFFFFFFFF3FFFFFFFE000000000001FE740780400007FFFFFC007FF803FFFFEFF80001
+Modulus = 0x8000000000040000000000000003FFF0000000FFE0000007000000000003FFFFFFFFFFFFFFFC0000000000000004000000000FF000FFFFFFFF8003FFFFFFFFFFF03BC00000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFC00000000000000001FF8000FFFFFFFFFFFFFFE001FFFE0000FFFFFFFFF9FFFFFF80001FFFFFFFFFFE0000000000007FFC003E0007FFFFFFFFFFFFFFFFFFF0003E1FFFFFFFFF8000000000000003FFFFC00FFFFFFFFFFFFFC000003FFFFFFFFFF78000000000000000000000000000003C000000000003FFC000000FFFF0000000000000000007FFC00FFFFFFFFF800000001FFFFFFFE00001E00000000000000000000000000180000000000001FFFFFFFC001FFFE0000000000000000000000000000000000001800000007FFFFFFC00FF8FBFFFFFFFFFFFFFFE00000001FE0000000000000000FFFFFFE3E0000000000003FFFFFF0000000000FE00001000200000FFFE00000000000001FFFFFFFFFFFFF800000000000003FFFFFFFFFFFFFE001FF003FFFFFFFFFFFFFFFFFFFFFFFF000003FFFF00003FFFF00000007FFFFBFFFFFFC00000003FFFFE03FFFFFFFFFFFFFFFFC00000003FFFFFFFFFFFE0183FFFFFFFFF8000003FF8007FC00000FFFFFFF
+Output = 0x2692DF831822EDEDDA5891FA16F9104A9AD7B9CBC8FFC112755E1CB2787313580041B7ED64096C74D056A40095EED34413BBDC869EFC28E652F02705D58FAF73D72E099FF003591B867A272440551367450E4AD723D53AA3156E70830367E76A0BD6C7E892ED33AB5B39B03286B6FC4BDBAF92A2CF1CBE37BC55EDD1F6FE1D050B54C5FE1BFA08EE155DF648A1DE2D64B00927C6C9C9D31A79B38308AE9D8D43B5B342C69DFC478CC12FD1144A54ACE7EA841FF821EF4BC30943BDFB2F0569F922C9B5938620EDCB88D7829CB6EEE1DBB55EC8776CE866AD5A7FB6501724E858063A03EE6B000A94CF93D8F8BC991F4D787C4D74C74F4AA982A019263D8E2C06A571B022696C2DF3190AB58BA63FF1307B25A0E34792D12472767D6810C6303E8801ACD6DE465F6D447B2376A06ABBB34C4B702157F05371DAF29904A4A238AD9E4358224B82F5B6D96BC99E17EE4705FAAACD491EB96A03A184B43C825E6D3349319E47CB107DCFD8C6C9E3F77BBE328ABDD681AAA55E9AA5024108158FA90E463775D9BC44099D6829672AECA071E94B24E1A009CE417D5A47CC363EEFBB2BAA73996DA4965BE7F9A34633864DCFCCD4791E346D6ED5086C99974BF984C4DF674597A7D14BC017
+
+Base = 0x7F7FFFFFFE21FFFFBFFFFFFFF005FFFFFFFFFFFFFFFE60000001A0800001FFFEFFF780803FE1780200007FF003FE0003F7FFFFFFFFFFFFD003FFFFC000F000000000001FFDF2000000000000007D900000017FFE00007F0000000060200201FC03F001FFFFFFFFFFFFFFF7E008003FFFFFFFFFF840005FFFFC01FFFFFFFE0200000FF800003F7FFFFFFF80000045FFFFFC00008C000038200001E07FFFFF83FDFFFE00002000000000000007FFC077FFFFFE1FFFFFFE7FC00000FFFFFFFFFF0000081FFFFBFFFC001FFC000FFFFE010000000000003D80000000000007F240000002040010007FBFFFFFFF8807097FC001FFFFFFFC00800000001FFFFFFFDFFFFFFFFFFC008CBF7E000003FE00107FFC00000FFFEFBFFFFFFFFFFC000002FFFFFFFF807DFFF87FFFFFF800000002000007E1FFFBFE623C00000001FBFFFE0001FFEFFFFFFFFF810003FDFF000021FFFFFFFFEFFFFFFFFFFFFFFFFFF00005F0FF7FFC0600C7FB800000F000000200FFFF0000FFFFFFFFFF6000003F800002000000007EFFFFFE0000403FFB91FFFD8400000000001C3FE03FFFFF800000027701FF000000100003FFFFFFFFFDFF8040007FFDFFFFC4003FFFF7FFFFFFFFFE7FFFFFC000600000500000003F01FEFE0040
+Exponent = 0x7D80000000203FFFFFFFFFFFEFC4FFFFFFFE0000FFFFFFFFEFFFE483FFFFE00007FF80787FFFF80000007FF003FFFFFFFFFFFFFFFFFD000043FFFFFFFFFEFFFFFFFFFFFFFE00000000000000008F8FFFFFFF7FFFFFFF7F00003F00401FE07FFC04EFE200FFFFFFC0007FEFE008000000000000000000FFFFFBFF80000001018007DFF800005F7FFFFFFFFFFFF00800000BFFC06C8000781FFFFFFFFFFFFF83F60000000027FF00000000FFFFFFC077FE0008000000007FBFFFF8000000000000000800000003FC001FFBFFFFC000000000000000103F7FFFFFFFFFFF87F13000000403FFEFFF8000FFFFFF87FFF980000000000000000000000000003FFFE18000003FC0FFFF4F7FFFFD03FDFFFF80007FFFFFFFF03FFFFFFFF01BFC4000000007FF807FFFF09FFFFFF7FFFFFFF8FFFF8800FFFC0001FC00000001FFF80000000000003FFFFF800003FFFF000001FF80F800000800000000000000700C03FFFFFFFC004038037F8000F00001FE01FFFF0000FFFFFFFFEF8000803E7FFFF8000010007EFFFFFF7FFFF93FBF8FFFFF861E07FFFFFFF001003FFFFC7FFFFFFC7C01FEFFFF000000040000001FFDFFFFFFC08000003FBFFF400000000000007B80000FDFFFFFFF00400000003F01FF00FC01
+Modulus = 0x807FFFFFFFE00000000000000FFC0000000000000000000000001F800000000000007F80000007FFFFFF800FFC000000000000000001FFFFFC000000000000000000000001FFFFFFFFFFFFFFFF80700000007FFFFFFF80FFFFFFFFFFE0000003FC0FFE00000000000000001FF7FFFFFFFFFFFFFFFFFF800003FFFFFFFFFFFE00000007FFFFC07FFFFFFFFFFFFFF8000003FFFFF3FFFF87E00000000000007C01FFFFFFFFE000000000000000003F87FFFFFFFFFFFFFF803FFFFFFFFFFFFFFFFFFFF80000000003FFE003FFFFFFFFFFFFFFFFFFFFFFC07FFFFFFFFFFFF80FBFFFFFFCFC000FFF80000000007800067FFFFFFFFFFFFFFF80000000000000001FFFFFFFFFFFFFFFC07FFFFFFC01FFFF8000000000000FC00000000003FFFFFF000000007F80000780000007FFFFFFFFFFFFF8000003FFFE03FFFFFFFE00000000000000000000007FFFFC0000FFFFFE000000000000000000000000000FFFFC00000003FFFFC7FC7FFFFF0FFFFFFFFF0000FFFF00000000007FFFFFC07FFFFFFFFFFFFF80FFFFFFFFFFFFC0007000007BFFFFFFFFFFFFFFFFC000007FFFFFFF87FE00FFFFFFFFFFFC0000000001FFFFFFFF800000003FFFC0000000000000038000001FFFFFFFFFBFFFFFFFC0FE00FFFFFF
+Output = 0x6589871ED499C727B9EF319AD11365A4CEECBCD14623552DA9357E1A34A47FCBF8B1FB581B4C99D3684168401AB61B6F92788CA579F2CEACA052488C84205DA06DF2EB1E8FB05532952A4A2BC6E7EA574118B216906BF8C00392370B2122B6311298C7BC89CD3A22950BE330D7D7E966B54C84EA40139DCF66ED26945B6BDD9D0482CC407081BF3A1DE1C42EF414C430DB8D85EFAC2BF59ED6E2FF29542C582CB65DF2F5C46FBC741AA9043AA62FB5C97FAF38CB99FDD71CE2DFD0A33F43B73A49503DAC7E2F220B0E56C2E748381CF139AFBF3137A7057EB10235226195A206025790C2890F4F6583082592559BC20ECC6AFBD8EAD5EFB07CB9AD15D81DACB508C4FDB6710ACBF1F49EF3DB5082560E4C6B9973B4BEC67BF306560B971F0D3DA541EEDF999B67D31C7A5F5BA6D77D5D66E896C53D601AF678A626D939A5AFC25C6131010EE4F397E943E9015400F1B829A80FE499A587B93C0F4C29CA76206A123124AA10A2E4EDEEB322EFBB90FF153A5700649D24ADA72E7CFE66B756484AD41B6A4A7C35076812860E5BCD2B6B2313C91EC956F9DBF9B7A7F70CADD10A2E7C4FBC1FE830A96EB37DF043F7278A36EA35E7152AD23C8953FFFB6A8658B42B8D12490470F373BD06A7491D69249E4C
+
+Base = 0xFFFFFFFFF0003FFFFFFFE0000007FFFFFFFFFFFFFFFF3FFFFFFFFC0000001FFFF8000001FC3FFFFFFFFFFFFFFFFFC7FFFFFFFFFFFFFF000E0000000000000000001FFFFFFFFFFFFFFFFFFFFFFC00000000FFFFFFE00001FFFFFFFFFFFF803FFFFFFFFFFFFFF80000000000001FFFFFFFF80000000000000000FF800000003FFE07FFFFFF80003FE000001FFC00003800000000000003FE03FFFFC00FFFFFFFFFFFFE0000FFFFFFFFC07FFFFFF000000000FFDFFFFFC0001FFFFFF00000001F80000001FFFC1FFFC0000000000007FFF803FE003FFF000000000001F9000000000000000020000000001C00000003FFFFFFFFFFFFE7FFFFFF87FFFFFFFFFFFFFFEC000000000000007FFFFFFFFF003803FFFFFFFFFFFFC003FFF00FFFC003C0000FFFFFFFFFFFC000000007F0000003FFFFFFFFFFFFFFE1FFF8003F0000003FFFFFFFFFFFE000FFFFFFFFC000003FC00000003FF800003FFF0FFFFFFFFFFFF0000000000000003FFFFFFE00000000000000000000000000007FFFC00000003E00000FC00000003FFFFE00200000003FFFFF7FFFFFF00000000FFFFFFFFFFE01FFFFFFFFFFFFFFC00000003FFFFFFE00000000007FFFFFFFFFFFF8003FFFFFFFFFF8007FFFFFFFFFFFFFF0FFFFFFF000000000000000003FFF
+Exponent = 0xFFFE0000000000000040000000001FFFFFFFFFFFFFFFFFFFFFF00000FFFFFFFFFFF000000000E0000001FFFFFFFFFFFFFFFFFFFFFFFFF001FFFFFFC00001FFFFFFFFE00FFFFFFFFFFFFFFE7FFFF060FFFFFFFF8007FFE0000000007E00001FFFFFFFC00000007FFFFFFFE3FFFFFFFFFFFF801E0000001C000000000000001FFFFFFFFFFFFFFFE000003FC00000000003FFFFFFFF0000200000000000001FE00000001FFFFFFFE000000000000000000000000000FFFFEFFFFFFFE000000003FFFFFFFFFFFFFFFFFFFFFC1FFE001FFFFFFFFFFFFFFFFFFF8000000000000000007FE0003FFFFFE07FFFFE0000007FFFFFFFFFFFFFFFFFFFFF000001FFFF801FF8001C0000000001FFE000FFFFFE000000000007E000039FFFFFFFFFFFFFFC000000000000003FE00000007FFFFC001FFFFFFC000000001FFFFFFFFFFFC0001FFFFFFFFFFC0000FFFFFFFFFFF800001FFFFFFFFFFFFFF00FFFFC1E00000000000000001FFFC07FF007FFFFFFFFFFFFFFFFFFFFFFFFFFFF1F800FFFFFFFFFFFFFFFFCFFFFFFFFFFFFFFFFFFE000003FC00000000000000000007FFFFFF00000003FFFFFFFFFFFFFFFFFFFFFFFF800001FFFFFFFFFFFFFFFFFFC000000000000000000007FFFFFFFFFF07FFFFFF000000000001FFFFFF6001FFF
+Modulus = 0xFFFFFFFFFFFFF8000000000000000FFE000000F800000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000007FFFFFFFFF8000000000000180000001FFFFF007FFFFFFFFFFF800001FC7FFFF0007F00000007FFFFFFFF00000000000000000000000000000000C00000070007FFE07FFFFFF800000FFFFFFFFFFFFFFFFFFFE00000003FFFFFFFFFFFFFFFFFFFFFFF00000040800001FFFFFFFF00000000000001FFFFFFFFFF80FFFC0000000003FFFFFFFF1FFFFFFFFC000FFFFFFFFFFFFC000000FFFFF000000FFFFFFF00000000FFFFFFFFFFFFFFFFFF802000000000000000000000000000000007E19FFFFFFEF07FFFFFFFFFFFFF000000000000000000000000000007FFFFFFC000FE001E00FFFFFFFFFFFFFFFE07FFFFFFFFFFFE00087FFF00FFFFFFFC0000000000000000018000000000000000000000FFFFFFFF01FE003F000FFFFFFFFFFF0007FFFFFFFFFFFFFFFFFFFFFF007FFFFF007FE000000000FFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFFFFFE000000000000FFFF800001F80000FFFFFFFF1FFFFFFF01E0000000000000000003FE07FFF001FFFFFFFFC00001FFC0000000000003E003FFFFFFFFF03FF80000000000000000FFFFFFFFFFFFFFFF0000007F0FF80000000
+Output = 0xD6B671BD1928358441505A40FB2B3DA61C99C668CFD01BE9830CC942B718910475979910E3E5F1C28CEB4EF50BFC3554AA44F3CACD62B1AB5FD83C9C99B90673D18BB64640C845FD549EBF742687A3A96FE7689637ABCFF86E6F0E2EC1E9D258A627F03B415F15C7FC1026BA6EC5B51C8A8C4469D31E0E74432A170F85242E80C3084CF59DEA8C17C631C7EE007AB475B1D14A1A001F8CBE34E2C3E38ABCDB02959C8217477C6B0A6F56E96E6E060B25C5107978E9710FC7AAC3738BD9F08D0E866201B1A169D2A0075CDD93F4ED8E55EF242F96FC4D07184F23FCE9C367509CA7CA1EA4D2E41B5FE55A465BC1ED226642F9AB09DD08CD4616D639B54FB9E83A528FD453EC136E6F9D896AE83908768C0D6389BD5DF8C69D2D7E1BDC02E25324671613F268D54A878A9A3032069BAB541272CD44ADD5D85BBD7EDCF7E155B64F93D233CE812239C30FF60FBB8A08B640CF096F0FBF7C6E92069CB3A371E8C6731B5E49A0F0BD868D6BA2F121E12E52D81D3768CB25EDEB268DC7E4C81FB85F8D597B6B129E36A4D0D0FBDD4895315DD93BD5D120F45A894C72DC91E5EC409E6D9A31C51C98FD4C9FC051A59994201DC94FAA72332C6F25E00D3EDF48F206CE941D8C8EAEACF241B40752D2C6DC625DA820EED712F7FFBFFF
+
+Base = 0x3F03FFFFFFEF83FF8FF8000007085FFFFFFFFFFFFFFFC0000007FFFFC03FE00003F0000000FFE1FE00007FFFFFF0000000000000000003FF80000000001FFCFFFFFFFFF000009F000001FFFFFC0040107800040000000FDFFFF8800000038001FC001000000000000FFFFFFFF000000002000000000001F8000000FFFFC07FFFFFFFBFC1FFFEF800000000FFFFFF800000010C000000003BFFFFFFC27FFFEFFFFFFFEFFC00009FFFFFECFFFFFFFFE004400019FE3FF181FFFFFFE80000003FFFFBFFE00000000200000000000003DFFE0000045FF0027FFFFFFFFFFFFFFF64003FC07FFFFE001FFFFFFF1700020000000005FFFFF0001FBC001FFF0E00207FFFFFF7FFFFFFFE000000000400000010000000000000FFFFFFFC7FC0000FF781FFFFFFFFFFFFFFDFE03FFFFFF8800063EC007F0001003FA0071BC0000000078000000000000000800000000FFD00E0000001007FBFF83FFFFFF8000000FFFFE00007FFFE04600F60000FFFFFFFFFFFA0000000000000007FFFFFFFFFFFFF7F9FFFFFFFFC01FFFC00C000009FFFFFFF600FFFFFE00000000007E000000003FF8A1FFFE7FFFFFFA020001FFFFFFFC0009FFFFFFFDFF008000007FFFFFFFFC0007E000001D00001FF5C3FFFFFFFDFFCFFFFF0000080000003600000002000000FBD0
+Exponent = 0x80000001FFFF8000000000000000000000000000003FFFFFFFFFFFFFFFFFFFFF9FFFFFFFFFFFFC00E000000000000000FFFFFFFFFFFFFFFF80000000000FFFFFFFFC0000000003FFFFFFFFFFFFFFFC0003000000003FFC000000000000000000000000000000021FFFFFCFFFFFFE000000000E00000003FFF00003FFFFFFF000000000403FF03000000000000000000000000000000001FFE0000000000003FFFFFFFC01FFFFFC07FFFFFFFFFFFC0000001FE01FFFE00003E000001FFF800007E00001FF001FFFFFFFFFFFFFFFFFC00007FFFFFE00000007FFFFFFFFFE00000000003FFFFFFFC3FFFFFFFC00000FFFFFFFE0000000000000000000000000007FFE0000007FE003FFFFFFFFF800000000000000001FFFF80003FFFFFFE000020000000001FFFFFC00003FFFFFFFFFFFFFFFFFFFFFFFFFFC00000000000001F800000003FFFFFFFFFFFF0FFC000000000000000000000003FFFFFFFC00000003FFFFFFFF801FFFC001FFFFC0800000000000000000000003FF8003FFF000000000003FFFFFE000000000007FFFFFFFFC0001FFFFFFFFFFFC00000FFFFFFFE0000000000000000001FFFFFFFC00000003FFFFFFFC0000007FF00000000FFFFFFFFFFFFFFFFFC00003FFFFFFF00001FFFC000000000FC3F00007FFFF000000FFE000
+Modulus = 0x800FC0000000FFFFFFFFFFFFFFFF81FFFFFFFFFFFFFFFFFFFFFFFFFFFFFC01FFFFFFFFFFFFFE01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE003FFFFFFFFFFFFFFE0FFFFFE000000001FEF87FFFFFFFFFFF01FFFFFFFFFFFFC00000000000000000000000000000FFFFFFFFE00000000000000000000000000000000003FFE0001FFFFFFFFFFFFFFFFFFFFFFFFF3FFFFFFFFC00000003E0000100000000003FFFFE0000003000000001FFC3FFFE601C0000000000018000000000000001FFFFFFFFFFFFFFFFFFFFFFC1FFFFFFFFF9FFFFE00000000000000001FFFC000000001FFE0000000E0FFFE000000000000000FFFE07FFFE07FF1FFE000000007FFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFF000000000000000007FE000000000000001FFFC000000780001C0FFF80FFFEFFFFFFF8003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF001FF1FFFFFFF00000007FFFFFFFFFFFFFF00001FFFFFFFFFFF9FF01FFFFFFFFFFFFFFFE000000000000000000000000000007FE000000003FFFFFFFFFFFFFFE00000001FFFFFFF9FFFFFFFFFFFFFFFFFFFFFFFFE0000000000001FE000000000003FFFE0000000000FF8000000000000000000000000002FFFFE001FE00000000003FFFFFFFFFFFFFFFFFC1FFFFFFFDFFFFFFFFF0
+Output = 0x7EA3D3A77FCF66D962E270686F889D94F105A160BF1E730929FF7EB8FBA7EBBF86C1A23C15D6D15DDE987C422B95AFD88AF2DADAFCD947A5B69D30C69B938FBFF0A4C1DCA290B16CFD190DD08FAE050D6F3E4E01505A9984890B697BE90A0CA0909A2E288A351720C11F470AD35FCAADBF2B615539AEB31194E55F7D917832E34E4D16CAAD9892F53F2A72FAE8A54892CD217AD2A6280B534F092725A8836A178E1EB68ABC3AFF9606FD6CB8CCFA62D39BF8EE483A04AF2ECFAE45F63C6B955B1A8DD2D212E57FBEFD44F0229D3246211B99BED08E67DBBCEC9F64A4D40E21B4125AFA44882E8BCD55C4295B99E1B170644A9019A2E6BEF486ACDCD893FDDDB1175BB878A1F11AF6ADFD4A595BE30989E0B918107464ACFC069807A8DE5FE2ED9F4F5766031AF1B399E01B81FF1E84EF4747A5F53A475F1BD2256BDA29D17BA0055BC0FDDCCBB55D002038201F3762E5C7B7954866E8A8F8847542E24563C84AE2EAAB7B26AA73339258E2A7B2BF9CF21BB5C4596D7A7656F8E9707EFF1C219F25397C686838FBEBEB47540657A293F2689DAFE4B1AD84C8AB0CBBBB0A290B951A1583C5F944185BF348D5E4BDB304FCB8ED99253453BA91063E8937D731587118D23DA04852035A1212064F92D0A4390A2415B1D56836EFBC639D7B5E5809E0
+
+Base = 0x80000000000000FFE0000000000000C000001FFFE00000FFFFFFF0000003FFFFFFFFFFFFFFFFFF80000FFFFFFFFFFFC00000000007FFE0000000000001FC00FFFFF003FFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFF0000000FFFFFFFE0000000000003FFFFFE0001F00000FFFFFFFFFFFFE0000000000000000FFFFFFFFC11C1FFFFFFFFFFFFFFFFF1FFC0000000003FFFE0000FFFFFFFFFF0000000007FFFFFFFF0383FFFFF800000FFFC00000001FFF0000000000000FFFFFFFFF000FE0001FFFFFFFFF000FFFFF0000000000F800010FF81FFFFFFF8000FFFFFC0000000008FFF000000000000700000000007FFFFFFFFFFFFFFFFFFFFC0001FFFE000000FF00000000FFFFFFFF000FF7FF000C1FFFFFFFE0000000E000FFFFFF00C000001FFE0FFFFFFFFFFFFFFFFC00000007FFFFC0000000007FFC00FE3FFFFFFFFFFFFFFFFFFC0000001FFFFFFFF000000007FF07FFFFFFFFFFFFFFC00000000000007FFFF000000000000000000007FE3FFFC00000001FFFF80000FFC000003FFFFFFF0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000007CFFFFFFFFFFF7FFFF000001FFFFFFFFFF000000000001FFE00003FFFFFFFFFFFFFFE0003FFFFFE000FFFFE000000000001FFFFF8000000000000000000000007F000000000000000000
+Exponent = 0x7FDFFFE0BF7FFFE0000003FFFFFFFFFF00FFBFFFFFF41000FEFFFFF0000010000003FFDFFE0400000000000C0038000000FFFFC00000003FFFFFFFFFFDFC00000FFFFC0107FEFFFFFE0400007803FFFFFFFFFFFFF00400170007F80020000007FFFFFDF0000BFE003FFBFFFFF9F8FC00040000000007FFFFFF3FE000001C0400003E0007FFEE0000001FFFEFF413FFEFC3FF007FFFFFFFFFFFFFFC01FC040077C0401BFFFFFA0000000FFFFFFF00000FFFFFFFFFFFF80000401FFFFFC0000000007FFF000003FFFFFEE8000000000038000313EF800007FFFFFC4000007C07FFFFFFFC000038001FFC03F7FFFFFFFFFF81F80000FE8000000000013DF80BFFFFE01C0003FFF80001BFFC00000800003FFFFFFC00EFFDFFFFFD00FFE00000000000000010FFFFE0000000100010000007DFFFFFFC00001000000000003FF4000000002000000003FFFFFEFFFFFFFC40FFFFC0FFFFFFFC000400000000000400000000FFF8000C0007FFFBFFFFFC0BE0000003BF0000001FFC0000000FEC0400000382000FFFFF04FDF80003FFFFFF800000002000000400000000001FFFFFFE000F7DC0000103FFFFFFFFFFFFFFFFFF00203BFFFFFFFCFFDFFFFFFFFFE007FFFFFFF8000001FFFFFE40000000FFE00000000F6000003C000000080000000000000003FFFFDF840
+Modulus = 0x800001FFFFF8000001FFFFFFC0000000000FF800000000FF00000FFFFFFFFFFFFFFFFFC001FE1FC000000000003FFC000000000003FFFFFFFC0000000000003FFFFF00003FF0000FFFFFFFC000007FC0000000000000003FFE0FFFFFFFFFFFFFFF80000000FFFFC00000003FFFFFFFFFFFFFC0000000000000000001FFFFFE3FC00000100000013FFFFFFE000000FEC00003FFFFF800007FFFFFFFFFFFE03FC00003FC003FFFFFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0000000000000000000FFFFFC000000F8000000000007FFFC70007FFFF8000003FFFFFF83F800000000000000000003FC0000000000007FFFFFFFFF7FFFFFFFFFFFC1FFFC00001FE3FFFC000000000003FFFFFFFFFFC0000000000FFC000001FF001FFFFFFFFFFFFFFFFF00000000000007FFFFFFFFF800000003FFFFFFFFFFFFFFFFC003FFFFFFFFFFFFFFFFFC00000000000003F800003E00000003FFFC000000000003FFFFFFFF00000003FFF80003FFFFFFFC1FFFFFFC00FFFFFFE004000000000FFC001FFC7CFFFFFFFFFF0007FFFFFFFFFFFFFFFFFFE0000003FFFFFFFFFFE0000001FFF0023FFFFF03FFFFFFFFFFFFFFFFFFFFFFC3FFFFFFFC0000000000001FFFFFFFFFFFFFFFFE03FFFFFFFFFFFF0000000000007FFFFFC3FFFFFFFFFFFFFFFFFFFFFFFC000007FC0
+Output = 0x1129F9B783C64B9A3B0ADDADAC4C68D503F8A3379CEFD1BA086FB8DB291049E7F57525F02EF3A681D64656132199A024686A7C7481511A2BA376B508E4427F271D2AC32CFE9C1DAA6DDD96EEC7906624E33FA90D8018636AD17429F3AAB335E2CA4744D9A2C2DF0473F79D6BF3B7D31AB19588D96408BD8F5C2C35E5BCE67047D3D511CF5D53C81648EAD1875DCEC725756C99FB8868C9871C0E726B487BA3386CF8DD7994148D431794082847801AE637DDA33E33A3EDB626659FE20C07FAFF55BF0096F758F6B71D214C5AFDC7A80FF12D8B7B3D6A2F14D162853DB1D83CDEFA0842E1F63D5902A333F4D79F001CCC5F51F290609B13A816EA03064BF2799787717E711A55AD1D9FFF278F610B00810C12EDA6645D583EE2AB94A1BC3CE9B883054B95A86AFD44302E5E2ECDE9E907145D25D5C3A96C92031CBFC4262CAF3B5599AC888CCF23B717FBCD867D48FBA4D22A836B35973A90FB9251CFE25A459BA7180E0F66D98D588043009FA30F380F5056223CEF016B248A808392E63E7872346BDFDCD598813F2A4F4DF2F5A4172676232774788A5B6F061FE23B57B95FE2227B3E7DB0E412317E878784ACE5426B3168B8B2C6F03C1EF460B6304FBA5177AD996868156034B97FCBB14254AAAE7ED28D2B0508634B7602CBA370E754FCAEC2F033FA9B2F4000
+
+Base = 0x380000000000001FFFFDF0000000000FFFFFC20000000017F8000000007FFFE00000009801FE101FC000001FFDFFFE10FFC00007FFFFFF98018000083EFF800800000000000000180000000000000237FFE003F8000000200FFDFFF0200000003DFE0003EFFFFFF8000000238000000003FFFFFE0007DFE0004001FFFFFFFFE0FFFFFF00007FFFE0FFC03780000203FFFF00000001BC00080000FFFFEC40001C000000001FFFF847FFDE200601FFFDD00001FFFFFFFFFFFC0001F7EBFC3FE003FFFFFFE0007FDFE8001FFEFFFFC00000000000FF9FBFFFFFFFFFE000000003E80000001800FFFFF7FFBFE100000001E7FE0000077FFFFC240003FFFFFFE3FFE80000005F800FFFFFFF808001FFFFFFDFF83FFFE0FFF000077FFFFFE020000007BF7FFFFFFFFFC027007FFFFFFFFFFF67FFFFFFFC0000000000000087FFFFFFFFFFF80000E7FFFFE0000001E000001F0000000000000EF01E000000000000009F80007FF700200007F7FC007F900FFFFFFFFFFFF7FFFFFFFFFFFF0007C001FFE000100FF7FFFF001FFFFF080000000000003FFEFFFC0FFFFFE7FFFFFFFFC083DFCFFFFFFFFC07FFF80007FFFFF620002600007FDFFF000014107FFFFFDFF8010000DF000380100796007FC00000000FFFFFE0000000000025FFFFF05FFE7FC000003BFFFFF807FFC70000100000003FE0
+Exponent = 0x80000000007FFFF8003C00001FFFF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0003FFFFFFFFFFFFF00000FFFC1FFFFF07FFFFFFFFFFF000FFFFFFFFFFFFFFFF0000000000001FFF000000000000001E000000000000000000003FFFFFFFFFFFFFFFF0FFFFFFE001FFFFFFFFFFFFFFFFFFC7FFFFFFE00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF001E000007FFFFFF00000000FFFFFFFFFFFE00000000003F060000000000000000000000000000FE0FFFFC00001FFFF0F0000000FFE07FFFFFFFFFFFFE03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE00000FFFFFFFFFFFFFFF0FFFFFFFFFFFFFFFFFFFFFC000000000F01FFFFFF00001FFF00000000FFFFFFFFFF0000000001E0000023FFFFFFFFFE00FFFFFFFFFFFFE0000007FF00FFFFFFFF00003FFFFFFFFFE0FFFF803F00000000FFFFC0000001FFE0000000000000000000000007FFFFFFE3FFFFF00000000000FFFFFFFFFFE00000FFFFFFFFFFFFFF80FFFF3000000000010000000000018000FF000000000007F800000001C000001F0000000000000000C000001FFFFFFE000000000000000000000000000001FFFFFFFFFFFFFFFFFFFE0000000000000000E7FFF000FE00000000000000000000000000007FFFE00000E000FC0007FF800080000000FFFFFF00FFFFFFC0000FFFFFFFFFFFFFFC00001800000000000007FF0
+Modulus = 0x87FFFFFFFFFFFFE000000FFFFFFFFFF000003E0000000007FFFFFFFFFFFFFFFFFFFFFF87FC01F00000000000000001EFFFFFFFF80000007FFE7FFFF800FFFFF80000000000000007FFFFFFFFFFFFFDC7FFFFFC07FFFFFFFFF001FFFFFFFFFFFFC003FFFC00000007FFFFFFFC000000000000000000001FFFFFFFFE000000001F00000000000000000000007FFFFE000000FFFFFFFE3FFFF80000000003FFFFFFFFFFFFFFFFFFFFD80001FFF9FE00000FFFFE000000000004000007F803C000000000000000001FF8000000FFFFFFFFFFFFFFFFFFE07FFFFFFFFFFFFFFFFFFFF800000007FF000008003FFFFFFFFFFE0001FFFFF8000003F7FFFFFFFFFFFFFFF80000001FFFFFFFFFFFFFFFFE0000000007FFFFFF000FFFF87FFFFFFFFFFFFFF800FFFFFFFFFFFFF8FF8000000000007FFFFFFFFFFFFFFFFFFFFFFFF800000000000000000000000000000000000000FFFFFFFFFFFFF00FFFFFFFFFFFFFFFFF8000000007FFFFFFF807FFFFFFFFF0000000000007F00000000000FFF83FFFFFFFFFFFF007FFFFFFFFFFFFFFFFFFFFFFFFFFC0000003F0000018000000003F80003000000003F80007FFFFFFFFFFDFFFF80000000000000003FF8000000007FFFFFF00FFFFFFFFF807FF803FFFFFFFFFFFFFFFFFFFFFFFFFF9FFFFFFC000003FF80003FFFFFFFFFFF8FFFFF00000000000
+Output = 0x2C3A1AB4531EF69E44DA2ACF04801F8ED7C0DD6FDD3E8ED831303AC3D247D28D4639E10D41FDE2F110A141345C610523A8191745DE125EE3ED97017AA33A9F37376EFA6D1D3C28C93923B94AD98F45B40FA3127F27B5F757D12ADE77E16AB22DA6DEB8970652C2918B3E65C31685EA2B2BEE0953E855B9D016550FF691BE6C0DE93CA609BD40CFF83B2FB61BF36573BD25E73FA27A7972CEA3530A1678C4D28E6AC1B899EFFC3F62796DA005B3BADECDDC8D431261125E7E654C71D3D6EA98D91B12949FF9FC0AC8CFD4FA5C2D88FDF7632C0D5FEDB94A333C6F2EA22A007BE01F82FBBF397CE5BFA0DA40E5222FABE51EA68B042C9E4F569F7BF4F7916631F04D7EDF65142094FCEF897FB4BED1C76734E487793FDD3C6239A0717C09D46385FF4523A38A92E344D1E57A743373BE9C46F45829FECA4F35E4A083DFF249F40A19CFC5DDF3E6986FE1CED01C7DBDAF43B5038ACF3C660845BAEBC544D4AF5D3F200F8488855E9783AAD183CA3BBBE4D2EBA02FBEB265AE26BD8728390411E183683AFE7C1C01D614DD7FBB0AA85DF480AB9B165921410C27181E790A9D9050CCEA5DF09F6BBAA1DAC23C750D490210530602FF5DF24488BDA0F0480E957FE83D78C2A23A28CB82D9F864EEABE7FBCCD95DD10842B06C049F3A359A3D737DA082A5465CBF713E0BDEE168D00000000000
+
+Base = 0x3FFFFFFFFC7FFFFF3EF00041FFFDFFE7FFFFFFFFFFFFFFFFDFC0800FFFFFFFFFCFE00003FFFFFFFFFFFF80FFFFFA0000000000003FC001FFF00FFFC00F00000FFFFFFFFFFFFFC0004FFFBFFFC03FFFFFF000000000078000478FF8001FFFFC0000801FFFFFFFFFFFBFFFFFF0FFF000043000007FB03FFFC00FFFE00010003FFFDFFF01FFFFF01FFF8FBC00004000007F400203FFDFFF03FFF00001F00000003C4FFC000FE000F800007BFFFFF00008002FFFBE0F00001FFFEFE78000001000003FFFFFFFFF8178004FFFFFEF800087FFEFFFFFFFFFFFFFFFE0000000000FF800B1FFFFFF800FFFFFFFFFFFFFFFE00FFFF80001FE1FEFFFFE3FFFFFFFFFE001FFF9FF80004FFFFFFFC7FFFE003FFBFFFE100FFBFFFC0000000FFA00003F8000003FFFFFFFF7FFF80040000080000080782FFE0000807FFFC000003FFFFFFFFFE3BFFFFFF81FF00000080000FFFFFFFFFFF7E005FFFFE00000000FFFFFDFFFC0003FFFE07800001F83F000000008010EFFFF0001C12FD03FFFFFDFE1FDFF00207FB000FFFFC00FFFFFEF8000002003EFFFFF000043FFFFFFE001FFFF408FEFFFFFFFFFC00000080003FFFF000200FFFFFFFFFFFFFEFFFFFFFFFFFC000100000FFFF03EFE007FFFFFFFD3DFFFFFFFFFFFFFFFFF8000000002001FE03FFFFE00000010FFFEFFFFFFFC0047FFFE10FFFFFFFFC
+Exponent = 0x7FFFFFFFFFFFFFFDFFFFF7FFC800FFFFF00003FFFBE0004000000000000000007BF8013FFFFBFFFF00000000000FFFFE0010001FFFFFFFFFFFFFFFFFFC002005000000000000000000000003FFFFFFFEFFFC000013FFFFFD1FFFFFF00FFFFF017FFFFFFC000000000002000000001FFFFFFFFF000000003DFE2007FD03FFFC01FFFE03FF07FC0001FFF01FFDFF000002FC000000000007F600004001FFF03F80FFF01F0000000002FFBFC0FE00100001FFBFE00100005FFF7803E000000000010068080000FFFC00000000007817FFFF000000F7FF8087BF0000000000000001FFFFFFFFFFFF8010FBFFFFF8010FFFFFFFFFFFF7FFFFFFFFFFFFFFE1FF000001CFFE000080001FFD80000002FC000000001FFFF800001FC0FFFFC08000000000FF9FFFFFFFFFFFFE0003FFFF7C003FFE400000000007F7FF0000000008007FFFFFFFF8000001C1FE00FFFF7FFFDFFFFE0000100FFFFFFC01FDFF800000000001F8007EFE0000000000000FF80000000000000080600FF3FFFFFFFFFF01000001EE7FFFDFFFFFF7FF010FFFF60107FFFF00000000003FFFFDF000203E000000FFE0000382FFFF0001FDFC0000008000003FF0001E100000000007FFEFFF00000000000011FFFFFFFD05FFA00000000002FFFFFFFFFFFFFFFFFF78080000001FFC00000007FFFFFFFEFFFFFFFFFFFFC0008000010003FFFFFB
+Modulus = 0x800000000000000000000000380000000FFFFC00001FFFFFFFFFFFFFFFFFFFFE03FFFF0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0003FFFFFC000000FFFFFFFFFFFFFFFF80000001FFFFFFFFFFFE000000000000000000FFFFFFFFC0FFFFF800FC0003FF0001FFFF00000000000FE00000FFFFFF03FFFFFFFFFFF807FFFFC000000FC000FFFFE0FFFFFFFFFF003FFF01FFF00000003FFFFFFFFF8000FFFC200000000000FF87FFFFFF0000000000000007E7FFFF00000007FFFF8000FFFFFFFFFFFFFFFE0000000000007FF100000007FF00000000000000000000000000001E00FFFFFFFFFFFFFFFFFFE0007FFFFFFF00000000000000000000001F00003FFFFFFFFFFF0060000000000000000000007FFFFFFFFFFFFFFFFFF80000FFFFFFFFF800000000000000000000000000007FFFFFFFFFFFFFF0000000000001FFE0000000000000000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FF00FFFFFFFFFF0FF0000000200001FFFFFF800FFF00007FF000000FFFFFFFFFFC000000FFFFFC0000000001FFFFBFF000000000003FFFFFF800000000FFFDFF00000000000000FFFFFFFFFFFFFFFF000000000FC001FFFFFFFFFFF00000000000000000007FFFFFFFFE001FFFFFFFFFFFFFFFF0000000000003FFF7FFFFF0000000003
+Output = 0x2F318E95938ED99888247B764559BB36B2976A1075312A3028F23CB21EC9C43DA7987D1720092B74B65A8E9AA3C8580CCF3FC56F3F4F9107330D3F201295F86587D77D6ACF93833C243868BD7F41E52A0D9E8ED6D0491D6D9612B5B04E908C0A90E33058CCD9BA5921DC17B3FDA479DB458C1A7887C2F7747F151887732F83CD5F6E493C21F75C5C0D31551E3F7B4F2BFDE162F90A9C1EB1FBBF166B9B4D2C61604E1F181BFCB4772087C38F3A42903DBB95D3C91066BFCC6461B6761FA6CC2D078B1CE68A3D33A1C89DFFA78A71BCEE0E67352D06FDDF94322E580F1264440173826D298089D0A74EBABCE18B0B91716EE94C705BAEE9AE9D883A85F559C6A3CC0B24D6786D3525DE1A90069295E15835FF1E1257457A5F021C2B9C367D6A075E1B9AF7CFF587E751947F2F2CA3F10539B8571ABFD7D79B1724512C70E452226881A734D726B4C3AE66C359AF68D02EEC705459815CE2136C20F57C797463DA13B47738352E9CFDA2E13DE67B414BBBDCAC1F2F40B9854522E0B5987FA47F9A385D7B4B1F946495C6F915133ADEE33525A61AE30C7F6C0220D4B6D72318769611EEEEBDEA267CD9546EFC6B9D4D72693A647456727331FC952DEE8D2C539115EED685D238723B5A40164088B07934E603DC9FF8F4E0632281E7552A7A55CA5B15F2E2C7AE9E16A24C8493CA053B400A9BCA54740FECE1F4
+
+Base = 0x80000007FFFFFFFE70001FFF80000000FFFFFE00000000000000000001FFFFFE0000007FFFFFF00080000000000000007FFFFFFFFFFF3FFF8E000000000000007FFFFFF800000000000000FC0000000000000001FFF8000007FFFFF0000000007E00000000000000000000001FFFFFFFFFFFFFFFFFFFFFFF80000000000000000000000007FFFC007FFE0001FFFFFFFFFFFFFFFFFFFFFFF00000001FFFFFFFFC7FFFFFFFFFF0001F8002000000007FFFFFFFFFFFFFFFFFFF803FE0000000000000000000000000037FFF9FFFFBFFFFFFC000000007FFFF07BFFF0000000007FFFFFFFFFE0001FFFFFFFFFFFFF87FFFFFFFFFFFFFFFFFFFFF87FFE0000001FFFFFF80001FFFFFFFFF80000000000000007FFFFFFFFFFFFFFFFFFFFFFF800000007FFFFFFC00000000000007FFFFFFFFFC000FFFC01FFFFFFF80000000000000007FFFF81F800F0000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFC000000FFFF80000000007FFFE0000001FFFF80007FFF000000007FFE00007FFFFFFFFFFFFFF0000000000000000001FFFC3F800000007FFFC00000030040000FFFFF8000003FFFFF80007FFFFFFFFFFFFFFFFFFFFFFFFC3FFFFFFFFFFFFFFFFFFFFFFFFFFE018000001FF8FFFFFFC00000000000000000000001FFFF80000000000380FFFFFC000000007FFFE000000000007FFFFFFFFFFFFFFF80000000000000F7
+Exponent = 0xF81FFFFFF801FFFFFFFFFF80001FFFFFC0000000000000003FFFC0003FFFFC00003FFFFFC01FF800FFFFFFFFFFFFFFFFFFC007C0400000003FFFFFBFC000000000000FFFC00000FFFFFFFC000000000C3FFFFFFFFFFFFFFFFFFFFFF00000000000000003FFFFFFFFFFF0FFFFFFFFFFFFC000000007FFFF0001FFFFFFF00000000000000000003FFFC1FFFFFFFFFFFFF84000001FC000000000000000001FF80000000000000000000000000000000002000FFFFFFFFFFE0000007FFFFFFC0000000FFFF000C00000000003F803FFFFF83000000000001FFFC0FFFFFFF80000000FFFFFFFE0000000000000007FFFE000300000000001FC0000007FFFFFFFFF803FFFFFFFFFFC00000000000000030000000000FFFFFFFF0FC0000000000003FFC001FFFFC000000000000000001FFFFFC00000003C0000003FFFFFFFFFFF9FFF000000001FFFFFFFFFFFFFC1007FFFFFFFFFFFFFF80000003FFE0000FFFFFFFFC000000007FFFFFFC000001FFFFFF803F800000001FFFFFFFFF800000000001FFFFFFC00000000003FC0000000000000383FFF1FC0000000007FFF80000000000000000FC00FFFFFFFFFFFFFFFFFFFFFFFFFFFF8000000FFC0007FFFFFFFFFFFC0000000003FFFFFFFFFFFFFFFFFFFFFBFFFFFC07FFFFFFC00003FFFF0000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000003FFFFFE0000007FF
+Modulus = 0xFFFFFFFFE000000001FFFFFFE01FFFFFFFFFFFFFFFFFFFFE1F9FFFFC00000000007FE01FFFFFFFFFFFFFFFFFFFFFF000003FFFFFC0001FC01001FFFF000000001FE0000000000000000000001FFFFFFFFFFE0FFC000003FFE00000000000000FFFFFFFFFFE00000000000000003FF8001FFFFFFF9FFFFFFFFFFFFFFE00007FFFE00000000000000000000000000000000007FFFFFF07F83FE000FF80000000FFFFFF800007C000000000001FFFFFFFFFFDFFFFF80FFFFFFFFFFFFFFFFFFFFFFFF8000001FFF8000000FFFFFFFFFFFFFE003C00000000007FE007FFFFFFFFFFFFFFFFFFFFFFFFFFFFE0000000000000003FFFFFFFFFFFF0001FFFFFFE000000001C00001FFF8000003FFFFF80000000000038000000000000000000001FFFFF0FE0000000000001FF1FFFFFFFFFFFFFFFFFFFFFFF00003FF8000FFFF000001C0000007FFFFFFFFFFFFFFFFFFFFF8FFFFFFFFFFFF0000007801FFFFFFFFFFFFFC01F8FFFFFFFFFFFFFE0000000000000000000000000000007E0003FFFFFFFFFFFE000000000003FFFFFFFFF80000000001BFFFFFFFFFFFFFFFFFFFFFFFC0000FFE0000000000000000000000000000007E000000000000007FFFFFFFFFFFFFFE0000000001FFFFF1FFFFFFFFFFF00000007FFFFFFFFFFFFFFFFFCFFFFFFFFFFFFE1FFFFFFFFF000001FFFFE78000000003FFFFFFFFFF7FFFFFFFFFFF800000002
+Output = 0xE5209F268DF2151C5452C1F7B03BA4BC03390990809DB6401C51F6CA1A39994032B9CF2117AD3EC2249F103F37EEC58407F089A067BD44320EC51107C2B0E0C129718668E14BE162193906F78B83B248A75B9827B4457BB24EDFA036BBAF1479477102FF5879D2ED64CC8B96A9DD138A6923A81D9BA7D6AC96955E8A91136782B58C071C16A298958FB2129C589DDEC9B3F7BDED77637037910C5F75D0DBFF7DCC9C67BB0D60685B197B6B83ABFCEF60EC5A13C2BC340B8D27F83260851ADF94B65984176EE5B6916AC765D5B5D199753481F67CB6E6954E582A24446B5F209EC93FA109E85460A2FD30297FBD02528779F328E7AE97201632FA30B3F6E452A902FB0F9F3B04A3FFAB291FD6A69A647C93535B871E0179F0007B12E79C1027C015B11C00ABB26F8770EA307151E0E72AA9B6059F1A5DDD3472A466027197AB541849B2BE41D964565C22E98FAE5AF836090A2770B009BD55DD303143A3E1104B006C72614D1A9DBE1146087FB06D02768F7E57141AB405675F1F8589EF38FD5CD3510347EEF488996C3AE5E11AEDE51DAE56E16E11354F9065CA491250B1CF598B0E4A972170374DE38FB8ED11AAD9C53494CFB9F1CB110CF7418ED0F88D3FEF7D149A7AD855D4FC0D7C0641296C7464FE2CAC04D4A44086FCBB6949956EAD97390F23DA10274C2F03B9D94C882E9ABB8027F5DBDA2E5C9A0DFF86F30261B729
+
+[PrimeTest]
+Value = 0x0
+IsPrime = 0
+
+Value = 0x1
+IsPrime = 0
+
+Value = 0x2
+IsPrime = 1
+
+Value = 0x3
+IsPrime = 1
+
+Value = 0x4
+IsPrime = 0
+
+Value = 0xFF
+IsPrime = 0
+
+Value = 0x101
+IsPrime = 1
+
+Value = 0xFFED
+IsPrime = 0
+
+Value = 0xFFF1
+IsPrime = 1
+
+Value = 0x10001
+IsPrime = 1
+
+Value = 0x100000001
+IsPrime = 0
+
+Value = 0x908EF92E5453DD53
+IsPrime = 1
+
+Value = 0xC892038CD8BD587BA244C45B
+IsPrime = 1
+
+Value = 0x8055A641BA9041BA0D10166579D42F6B
+IsPrime = 1
+
+Value = 0xFCEEE64D4D40D734058A51944F2B53152FFE7F15
+IsPrime = 1
+
+Value = 0xEE23CE225FDEE2080403C2358C17A72D57C5B7CBE171D6D2BA59FE82DAABA9D3
+IsPrime = 1
+
+Value = 0x1043F9AC97177F7BD0B6876E1747CD0A6CF3B5DBD5306E6D2BA59FE82DAABA9D3
+IsPrime = 0
+
+Value = 0x24F08CFE94F236901
+IsPrime = 0
+
+Value = 0x1C443F2F861D29C3B
+IsPrime = 0
+
+Value = 0x2BF2F5F313B1784CAC2B5CF9532AA6CFA27DFC0F3
+IsPrime = 0
+
+Value = 0x95D9E7C08BF3FA230171B6188BBC154FC879D340687A52C6B35424B471E28449091A7D784F9F
+IsPrime = 0
+
+Value = 0x886353EE3F610EA9DC507EBC572E2F659D76E1459F175556D93795683BA72A6679491C328076CF
+IsPrime = 0
+
+Value = 0x168E8FA52C7B0274DDC9A7B6BB14FB2437B91638CB25161BD004EF43565B5231FAF88E13AB885AE0E7C20FC96BA3BE15436F03D1603
+IsPrime = 0
+
+Value = 0x1DA20BCB5DE084D2DDA31B118D671342B828052EF5D39AEB65904E9F6027000D3A00F88658EA1EC52A10CF32D8892ED16F2BB9E110F6C9555ABB069BA7A069C6F1FE46873E957
+IsPrime = 0
+
+Value = 0x7215D1519157B349829486479DCA81AF352EFE7B516C0079D4213F1554FEA6FE81A5E099B528536361EB5B5ECEC96CC3183CB21B3E4A045F50A5D18BAF5CA154E856D88A2D6082E93BA5AF650E20C3C2873A98AFD9D54843C02547157
+IsPrime = 0
+
+Value = 0x36133736D1
+IsPrime = 0
+
+Value = 0x8DD3F98C901
+IsPrime = 0
+
+Value = 0x53251
+IsPrime = 0
+
diff --git a/src/tests/data/block/lion.vec b/src/tests/data/block/lion.vec
index 30f231abd..9010565bc 100644
--- a/src/tests/data/block/lion.vec
+++ b/src/tests/data/block/lion.vec
@@ -1,4 +1,4 @@
-[Lion(SHA-1,ARC4,64)]
+[Lion(SHA-160,RC4,64)]
Key = 00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF
In = 1112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F3031323334353637382015B3DB2DC49529C2D26B1F1E86C65EC7B946AB2D2E2F30
Out = BCE3BE866EF63AF5AD4CBA8C3CAA2AA9CF9BB3CC2A3D77FF7C05D0EC7E684AD6134ABFD7DF6842B7292071064C9F4DFE4B9D34EAE89201136B7CE70ED4A190DB
diff --git a/src/tests/data/dates.vec b/src/tests/data/dates.vec
new file mode 100644
index 000000000..46db7f71a
--- /dev/null
+++ b/src/tests/data/dates.vec
@@ -0,0 +1,18 @@
+
+[valid]
+Date = 1970,01,01,0,0,0
+Date = 1998,04,23,14,37,28
+Date = 2037,12,31,23,59,59
+
+[valid.not_std]
+# these dates are valid but not representable as a std::system_clock::time_point
+Date = 1800,01,01,0,0,0
+Date = 1969,12,31,23,59,58
+Date = 1969,12,31,23,59,59
+Date = 2038,01,01,0,0,0
+Date = 2083,05,20,8,30,9
+
+[invalid]
+#Date = 2037,12,32,24,59,59
+#Date = 1998,10,31,22,61,0
+#Date = 1998,10,31,22,60,60
diff --git a/src/tests/data/hash/comp4p.vec b/src/tests/data/hash/comp4p.vec
index baa7a5781..2944ebb9a 100644
--- a/src/tests/data/hash/comp4p.vec
+++ b/src/tests/data/hash/comp4p.vec
@@ -2,7 +2,7 @@
In = 636F6D62345F696E707574
Out = FD1A64F7BC61608FD054303AFA2E31608AA3F3788E3034821D63A0288A70B573
-[Comb4P(SHA-1,RIPEMD-160)]
+[Comb4P(SHA-160,RIPEMD-160)]
In = 636F6D62345F696E707574
Out = 2B5F61CB57F94E7C7E6D7439FFF260028665853988224E0AD8C08C2FAA61963C8F761654AC529325
diff --git a/src/tests/data/hash/gost.vec b/src/tests/data/hash/gost.vec
index 971efd303..b2e30ad6d 100644
--- a/src/tests/data/hash/gost.vec
+++ b/src/tests/data/hash/gost.vec
@@ -1,4 +1,4 @@
-[GOST-34.11]
+[GOST-R-34.11-94]
In =
Out = 981E5F3CA30C841487830F84FB433E13AC1101569B9C13584AC483234CD656C0
diff --git a/src/tests/data/hash/md5.vec b/src/tests/data/hash/md5.vec
index 4385840ff..00c759951 100644
--- a/src/tests/data/hash/md5.vec
+++ b/src/tests/data/hash/md5.vec
@@ -1,5 +1,5 @@
[MD5]
-In =
+In =
Out = D41D8CD98F00B204E9800998ECF8427E
In = 7F
diff --git a/src/tests/data/hash/parallel.vec b/src/tests/data/hash/parallel.vec
index 1cbfcb8bb..8fd62a76b 100644
--- a/src/tests/data/hash/parallel.vec
+++ b/src/tests/data/hash/parallel.vec
@@ -1,11 +1,11 @@
-[Parallel(MD5,SHA-1)]
+[Parallel(MD5,SHA-160)]
In =
Out = D41D8CD98F00B204E9800998ECF8427EDA39A3EE5E6B4B0D3255BFEF95601890AFD80709
In = 61
Out = 0CC175B9C0F1B6A831C399E26977266186F7E437FAA5A7FCE15D1DDCB9EAEAEA377667B8
-[Parallel(SHA-1,RIPEMD-128,Tiger(24,3))]
+[Parallel(SHA-160,RIPEMD-128,Tiger(24,3))]
In =
Out = DA39A3EE5E6B4B0D3255BFEF95601890AFD80709CDF26213A150DC3ECB610F18F6B38B463293AC630C13F0245F92BBB1766E16167A4E58492DDE73F3
diff --git a/src/tests/data/hash/sha1.vec b/src/tests/data/hash/sha1.vec
index 5cbe155e3..f5fd82340 100644
--- a/src/tests/data/hash/sha1.vec
+++ b/src/tests/data/hash/sha1.vec
@@ -1,4 +1,4 @@
-[SHA-1]
+[SHA-160]
In =
Out = DA39A3EE5E6B4B0D3255BFEF95601890AFD80709
diff --git a/src/tests/data/hash/tiger.vec b/src/tests/data/hash/tiger.vec
index 276e71472..7e6c9091e 100644
--- a/src/tests/data/hash/tiger.vec
+++ b/src/tests/data/hash/tiger.vec
@@ -1,4 +1,4 @@
-[Tiger(16)]
+[Tiger(16,3)]
In =
Out = 3293AC630C13F0245F92BBB1766E1616
@@ -12,7 +12,7 @@ Out = 3293AC630C13F0245F92BBB1766E16167A4E5849
In = 4142434445464748494A4B4C4D4E4F505152535455565758595A3D6162636465666768696A6B6C6D6E6F707172737475767778797A2B30313233343536373839
Out = 48CEEB6308B87D46E95D656112CDF18D97915F97
-[Tiger]
+[Tiger(24,3)]
In =
Out = 3293AC630C13F0245F92BBB1766E16167A4E58492DDE73F3
diff --git a/src/tests/data/mac/hmac.vec b/src/tests/data/mac/hmac.vec
index c519ed8cd..2db21bc3a 100644
--- a/src/tests/data/mac/hmac.vec
+++ b/src/tests/data/mac/hmac.vec
@@ -40,7 +40,7 @@ Key = 8FB6AB01840023EC453ECDEC73DC1B66
In = 54657374205573696E67204C6172676572205468616E20426C6F636B2D53697A65204B657920616E64204C6172676572205468616E204F6E6520426C6F636B2D53697A652044617461
Out = 6F630FAD67CDA0EE1FB1F562DB3AA53E
-[HMAC(SHA-1)]
+[HMAC(SHA-160)]
Key = 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B
In = 4869205468657265
Out = B617318655057264E28BC0B6FB378C8EF146BE00
diff --git a/src/tests/data/mp_valid.dat b/src/tests/data/mp_valid.dat
deleted file mode 100644
index 47a5df1f1..000000000
--- a/src/tests/data/mp_valid.dat
+++ /dev/null
@@ -1,5477 +0,0 @@
-# BigInt validation file
-
-# These are all in decimal, mostly to help make sure the I/O and decimal
-# conversion stuff is working. We test the hex conversion in the PK tests
-# anyway...
-
-# Some of the numbers have very simple binary representations (such as
-# 2^256-2^192-1) while others are chosen 'randomly', mostly by me hitting
-# random keys into 'bc'. Some where also machine generated with a strong PRNG.
-
-[Addition]
-0:0:0
-0:1:1
-1:0:1
-1:1:2
-1:-1:0
-
-5:-0:5
--5:-0:-5
--0:5:5
-
-255:1:256
-
-65535:1:65536
-
-4294967295:1:4294967296
-
-18446744073709551615:1:18446744073709551616
-
-124536363637272472:124536363637272472:249072727274544944
-
-9223372036854775807:281474976710655:9223653511831486462
-
-9223372036854775807:137438953471:9223372174293729278
-
-# Carry tests
-340282366920938463463374607431768211455:\
-340282366920938463463374607431768211455:\
-680564733841876926926749214863536422910
-
-340282366920938463463374607431768211455:\
-340282366920938463463374607431768211450:\
-680564733841876926926749214863536422905
-
-11579208923731619542357098500868790785326998466564056403945758400791\
-3129639935:\
-11579208923731619542357098500868790785326998466564056403945758400791\
-3129639935:\
-23158417847463239084714197001737581570653996933128112807891516801582\
-6259279870
-
-11579208923731619542357098500868790785326998466564056403945758400791\
-3129639935:\
-11579208923731619542357098500868790785326998466564056403945758400791\
-3129639919:\
-23158417847463239084714197001737581570653996933128112807891516801582\
-6259279854
-
-13407807929942597099574024998205846127479365820592393377723561443721\
-76403007354697680187429816690342769003185818648605085375388281194656\
-9946433649006084095:\
-18446744073709551616:\
-13407807929942597099574024998205846127479365820592393377723561443721\
-76403007354697680187429816690342769003185818648605085375388281194658\
-8393177722715635711
-
-13407807929942597099574024998205846127479365820592393377723561443721\
-76403007354697680187429816690342769003185818648605085375388281194656\
-9946433649006084095:1:\
-13407807929942597099574024998205846127479365820592393377723561443721\
-76403007354697680187429816690342769003185818648605085375388281194656\
-9946433649006084096
-
--397942700139194066108348269604271467697661897648384734165029652\
-9192053560111268857919862747528477749805933030612876334500852832\
-5994574657552726381901:\
--342238655038:\
--397942700139194066108348269604271467697661897648384734165029652\
-9192053560111268857919862747528477749805933030612876334500852832\
-5994574657894965036939
-
-2511029185349894083125189792298767815734633609329237357694542628\
-9097725034326735312448621015537884914:\
--365510811543986457345339657399796975273732516080550566276869562\
-81114038842935173436543461:\
-2511029185346238975009749927725314419160635639576500032533737123\
-2470038078045621273605685842101341453
-
-27802650352:\
-660736146705288303126411072388564329913778942:\
-660736146705288303126411072388564357716429294
-
--134824589995504186480095446370988146623149603821668360871542456\
-6397833766910915722793041224478985289:\
-1151714952286618235856515264359526625702022859705853911311473221\
-8008332987904361457299261161227276764386173666571334749062651694\
-592291882972:\
-1151714952286618235856515264359526625701888035115858407124993126\
-3544623106438129961261044477618561339819775832804423833339858653\
-367812897683
-
--175405304416816169628682516351336019150390262549968865836182439\
-14226325157426408929602625346567256761818:\
-8652004279835272452069018101603566414024194616420826231795446815\
-19016990:\
--175405304416816169628682516351327367146110427277516796818080835\
-57584922737964766846979445801885737744828
-
-1288447760742982615563987140969486034581770182750513292185554983\
-74:\
-4438163138291508763620522351346106032205489281076979612299536118\
-73695276391917150913346479060246759720475193648:\
-4438163138291508763620522351346106032205489282365427373042518734\
-30093990488865754371523497335298088939030692022
-
-1709484189262457846620911889502097055085989595277300243221975568\
-275935717696463:\
--1646592344139809206374540620411514484579951199941360:\
-1709484189262457846620911887855504710946180388902759622810461083\
-695984517755103
-
-3201758654296371761657093415761871025401806278064180152049287711\
-7023353895132395250905592913967322327352806288308303059519915387\
-7335714942842:\
--282824169696073608987996588238668793593857085654548122761949764\
-0844399275054327390050478930503975773972:\
-3201758654296371761657093415761871025373523861094572791150488052\
-8784685101538538165251044791205372563268366360802870320514867494\
-6831739168870
-
--403539836054218172590829531210749614210541501474425943996337720\
-4111754181625695349185753326709217:\
-85450213703789913646546187382091037800:\
--403539836054218172590829531210749614210541501474425943996329175\
-3898050391712048802998371235671417
-
--129216644607347987680152236338235788743165763918415128477552538\
-7363973852756087726243671676713861533673009088319851:\
-8045388958745181755374994252823750582362455317985903504033438417\
-6695557207064326714194569562489510933024274993575473943439469171\
-4971:\
-8045388958745181742453329792088951814347231684162324629716862025\
-8280428729511787977797184286880738308657107322189320576138560339\
-5120
-
--451986588700926309459451756852005697379481014956007968529234251\
-884946522682901215022086432597024324062240835564200177389:\
-15762983479:\
--451986588700926309459451756852005697379481014956007968529234251\
-884946522682901215022086432597024324062240835548437193910
-
--390747541211572881697456702205527837411679402562428747433403883\
-1885743634200801846649105209920908153587891040882946582394429615\
-396962188674594744360388466:\
-1938936112365378546948796774781062371570792073982831173929981754\
-54362643521031390:\
--390747541211572881697456702205527837411679402562428747433403883\
-1885743634006908235412567355226028476109784803725867374996146498\
-003964013220232100839357076
-
--72603710637966201224690926289:\
--136184426422985332615812550349236126405125071507280171067688615\
-06299813289801666559564532:\
--136184426422985332615812550349236126405125071507280171067689341\
-10010451256002891250490821
-
-5607796083571305683140294840679074710788944676935750975947220760\
-3483968107693997028111823994257399379783658853302692762256851623\
-103019589392739:\
--427057313888431079237360487703561848638868677065083968842:\
-5607796083571305683140294840679074710788944676935750975947220760\
-3483968107693997028111396936943510948704421492814989200408212754\
-425954505423897
-
--220980083850850444349478376253480033771210140515678470878219758\
-0824527899758308:\
-4284407650303949586450021392583759850781770841835415277411207859\
-6443089606598570396235816327987463393971710495985285591895096794\
-994387176281079:\
-4284407650303949586450021392583759850781770841835415277411207859\
-4233288768090065952741032565452663056259609090828500883112899214\
-169859276522771
-
-3388776730880982684241784117615223232127223178833840452685901937\
-0507113927387984766381329515371768224976188337692:\
-349484339542971517481628970179002500341:\
-3388776730880982684241784117615223232127223178833840452685901937\
-0507113927737469105924301032853397195155190838033
-
-8574808963985866072258732162153629808269070752641242695163010155\
-1228144063151688592419555048867068162:\
--383634567691961960211191292397062452265352651123492760493087381\
-707279:\
-8574808963985866072258732162153591444812301556445221576033770448\
-8775878710500565099659061961485360883
-
-23889807888563742283608049816129153552608399262924421832404872043475:\
-995:\
-23889807888563742283608049816129153552608399262924421832404872044470
-
--654786925833474864669230962582694222611472680701859262466465606\
-239654996048306783957549697781271829257774329538985:\
--276137507159648540503039013089014674747:\
--654786925833474864669230962582694222611472680701859262466465606\
-239654996048582921464709346321774868270863344213732
-
-50463316268089933:\
--140591583463431806921000349498135287589005423318927850947894242\
-9953101385694731575213124136524392343244191305277028999171613076\
-57443381774866237429:\
--140591583463431806921000349498135287589005423318927850947894242\
-9953101385694731575213124136524392343244191305277028999171613076\
-57392918458598147496
-
-1339015021665554488163337105187026760232395594198925052890859936\
-418304234254229440059229155546157793544192:\
-6294037420283433712414743361937677483761554699961644450461297486\
-2247932788230044871756877711635975905661325925915992499702811257\
-81761944353272:\
-6294037420283433712414743361937677485100569721627198938624634591\
-4118200390554000813746128240544575269844368268458286900295102813\
-27919737897464
-
--241446683:\
--282671163032866994488211995758272717472259277760825940523445628\
-442206062910449311538519756165635175664610569214430918184214:\
--282671163032866994488211995758272717472259277760825940523445628\
-442206062910449311538519756165635175664610569214431159630897
-
-2358605503303452637996081421902056515951744611718383128442445119\
-505739707550326378912342448355046239066896995563581:\
--383043722914532516527336452555126144064884579194968166126094695\
-6860463720730123941973615:\
-2358605503303452637996081418071619286806419446445018602891183678\
-856893915600644717651395491494582518336773053589966
-
-1860794367587960058388097846258490:\
--237344494507203983863096991896035366478949095337787603280:\
--237344494507203983863095131101667778518890707239941344790
-
--286399096802321907543674770412181810379003627366516307780436082\
-546:\
-6433131620680089024037442172197761714707480582555136398379812339\
-597187475099646442833150194:\
-6433131620680089024037441885798664912385573038880365986198001960\
-593560108583338662397067648
-
-1811803390771023695595378175836278947833228041818597295747524425\
-7214680056902377349016498752054120312533829578576324428322456925\
-9250011493:\
--119912766577350317025030707802803587547945939765717835695952624\
-5067549497129923023348187933280753018204983010837846725666878521\
-137637491:\
-1799812114113288663892875105055998589078433447842025512177929163\
-2707925107189385046681679958726045010713331277492539755755769073\
-8112374002
-
--641402013955555338114086428916201846520512758110759261762820321\
-4491558550345077676836677565241902214951203461131114985869530775\
-0874152:\
-174441039:\
--641402013955555338114086428916201846520512758110759261762820321\
-4491558550345077676836677565241902214951203461131114985869530757\
-6433113
-
-1272757944308835857208037878018507337530557445422230495561634616\
-5037244198775127175123602392596401935136013522028214622088960493\
-31599624285621:\
-7326562354017884140300121264633612334070903165496641915889499701\
-38457507491850467631029977010:\
-1272757944308835857208037878018507337530557445422963151797036404\
-9177544320039760787457673295761898577051903021729599197163878997\
-99230654262631
-
--296171972628230:\
--829576609912184321900082369936222286517382010256973151771639172\
-7126741710202086962877467940292139:\
--829576609912184321900082369936222286517382010256973151771639172\
-7126741710202086963173639912920369
-
-7469859140681995100248436821088394448284142227691915206159676323\
-62127522466922882591:\
--20487191102299831461877807785745372724903547246374023:\
-7469859140681995100248436821088189576373119229377296428081818869\
-89402618919676508568
-
--4:\
--234439009075326480604323496098115161312227136676259000693031887\
-6906455201397017135:\
--234439009075326480604323496098115161312227136676259000693031887\
-6906455201397017139
-
--448761802739957373377693318750581411296787367117499463888322757\
-67882143882764:\
-20982187786:\
--448761802739957373377693318750581411296787367117499463888322757\
-67861161694978
-
--601944008264824351134005823298148744369561537910415436895793990\
-7896782179207195666302228625496897271988494:\
-5325663024991554160033166078015937845836527207540797603647364222\
-91735917382015688217276924340984564880:\
--601890751634574435592405491637368584991103172638340028919757517\
-1474490443289813650614011348572556287423614
-
--737554715636160268477263493571675308338509596629210590529282292\
-3781472871944886871927821129478599825311797681268315326408823018\
-2865250970217610487:\
--30100016097092378349958946184353117306134810372681:\
--737554715636160268477263493571675308338509596629210590529282292\
-3781472871944886871927821129478602835313407390506150322303441453\
-5982557105027983168
-
--221117706668970434568685275663894630667495895204444708028536428\
-3965878599873864667094550865713828159912:\
--536556043937245689200756579876160678199726920153847573681478030\
-0517383963455858081652308237033460360040921820049494698892905680\
-307378540208:\
--536556043937245689200756579876160678420844626822818008250163305\
-7156330270130817033696755317318824644006800419923359365987456546\
-021206700120
-
-6074122512337108841968521649035076841633691574254417104144285970\
-8190687151580370231498672521465704184848502349798380642493738161\
-63440:\
-301843614094506325875637699:\
-6074122512337108841968521649035076841633691574254417104144285970\
-8190687151580370231498672521465704184848505368234521587556996918\
-01139
-
--518214776931158149908771340564348982010543985108065053479219152\
-7346598920424997741288096547136515478330872068932567407374262007\
-15673766732196603988:\
--298351725577476937261155258873861370046745453114225573456588840\
-38760353928226157702249175218280718951979:\
--518214776931158149908771340564348982010544014943237611226912878\
-8501857794286367788033549661362088934919712456536106689635839029\
-64848985012915555967
-
-15937412249227240968245047444122:\
-1862146803761694261088224507009788278865690534402542585855766455\
-30381613666540347032550716844628275956253:\
-1862146803761694261088224507009788278865690534402542585855766455\
-30381613682477759281777957812873323400375
-
--125280101162586858550475042529281076239231054587017617079119695\
-27003855713485846140551107967495813584097081777160:\
--539986280927242338236008809854961759996986302156061552378097160\
-849129372827386927545686899193598721998757419572890:\
--552514291043501024091056314107889867620909407614763314086009130\
-376133228540872773686238007161094535582854501350050
-
--2454746908:\
--382295712788939478005524215636037018707559207865555237605060467\
-9934415014573879513870030211860839641756441626913419699098985245\
-833920954444218:\
--382295712788939478005524215636037018707559207865555237605060467\
-9934415014573879513870030211860839641756441626913419699098985245\
-833923409191126
-
--54288706131860071583318409080596095357980447323635:\
--425339410556015631098973742993327323051438456819027069606294261\
-157940297643297240559452124432779202181589763874:\
--425339410556015631098973742993327323051438456819027069606294315\
-446646429503368823877861205028874560162037087509
-
-1418766894051319870818496026367686195459604395660119754151922014\
-257535705077512233275240217434104:\
--111987390206074845527:\
-1418766894051319870818496026367686195459604395660119754151922014\
-257535705077400245885034142588577
-
--690410131860410477456103857594543515409677479242833618634809302\
-4529626004763532868225501682312348541164651530788457447229874477\
-19420052500874721214723:\
--258469037743394674731135699243278836145549479106673938483740960\
-9897387109736539600623155880918146331681272708396146283818299:\
--690410131860410477456103860179233892843624226554190611067597663\
-9084573915430926716599597781286219638530047537020016256411337794\
-00692760897021005033022
-
--2326153002179462643778624079324592172489363679671158:\
--109819757548464054181938329012610459679:\
--2326153002179572463536172543378774110818376290130837
-
--442875225056652548835385770919494174299378557880791141401695920\
-6453045495320705299466107784149485981354180907411034982168391:\
--392477782593742153255217680053880075265812358324465405897205608\
-55741992694947322437679214611686905696:\
--442875225056652548835389695697320111720911110057591680202448578\
-7688877941861295020026963526142180928676618586625646669074087
-
-3047:\
--735645878503131535237769321637196107334337768903902046180401737\
-9719600010085607082927794304834315616579528230750813527764131521\
-4:\
--735645878503131535237769321637196107334337768903902046180401737\
-9719600010085607082927794304834315616579528230750813527764131216\
-7
-
--89094716573076464980713547115099137014719483620102078148320806773871\
-083148864:\
-89094716573076464980713547115099137014719483620102078148320806773871\
-083148864:0
-
--89094716573076464980713547115099137014719483620102078148320806773871\
-083148864:\
--89094716573076464980713547115099137014719483620102078148320806773871\
-083148864:\
--17818943314615292996142709423019827402943896724020415629664161354774\
-2166297728
-
-7139718976538104911036273126224339498939049952371944598728684359\
-8407339615555456955143712741779487184644001767776382991377987516\
-772847242986:\
--5821969555717973232123574849275726788359152255219972775831:\
-7139718976538104911036273126224339498939049952371944598728684359\
-8407339615555456949321743186061513952520426918500656203018835261\
-552874467155
-
--181409752656613138777964092635909379021826360390960647186726991\
-165227400176766831466541160049935205507919070233410228328274:\
--523301382154855044703947051892202646490840761177533623732372519\
-6899184207698424247726764075013505280967149049152973476842478027\
-73107355881667545916901:\
--523301382154855044703947052073612399147453899955497716368281898\
-7117447811608030719594033986665779282734817363818385077341830082\
-81026426115077774245175
-
-6858961373707073067:\
--334051508933893061433844279764271107181974906283364991309903077\
-649971606436918071327072869826471946094594594115614990907:\
--334051508933893061433844279764271107181974906283364991309903077\
-649971606436918071327072869826471946087735632741907917840
-
--236350989303745694071719069604296168709084242815199446584909401\
-09956689534874971218650241680916564611:\
--189589178757795228335995891331428279524485393011427187469792714\
-4384667023598274379343968662673642819854164720298367788750543006\
-0922528525205:\
--189589178757795228335995891331428279524721744000730933163864433\
-5080709985285365221772120657139491913865160389251855285872408030\
-2603445089816
-
-[Subtraction]
-0:0:0
-
-0:1:-1
-
-1:-1:2
-
-100:-100:200
-
-0:-1:1
-
-0:4294967296:-4294967296
-
-4294967296:-4294967296:8589934592
-4294967295:-4294967295:8589934590
-
-13407807929942597099574024998205846127479365820592393377723561443721\
-76403007354697680187429816690342769003185818648605085375388281194656\
-9946433649006084095:\
-13407807929942597099574024998205846127479365820592393377723561443721\
-76403007354697680187429816690342769003185818648605085375388281194656\
-9946433649006084095:0
-
-13407807929942597099574024998205846127479365820592393377723561443721\
-76403007354697680187429816690342769003185818648605085375388281194656\
-9946433649006084095:\
--13407807929942597099574024998205846127479365820592393377723561443721\
-76403007354697680187429816690342769003185818648605085375388281194656\
-9946433649006084095:\
-26815615859885194199148049996411692254958731641184786755447122887443\
-52806014709395360374859633380685538006371637297210170750776562389313\
-9892867298012168190
-
-17976931348623159077293051907890247336179769789423065727343008115773\
-26758055009631327084773224075360211201138798713933576587897688144166\
-22492847430639474124377767893424865485276302219601246094119453082952\
-08500576883815068234246288147391311054082723716335051068458629823994\
-7245938479716304835356329624224137215:\
--17976931348623159077293051907890247336179769789423065727343008115773\
-26758055009631327084773224075360211201138798713933576587897688144166\
-22492847430639474124377767893424865485276302219601246094119453082952\
-08500576883815068234246288147391311054082723716335051068458629823994\
-7245938479716304835356329624224137215:\
-35953862697246318154586103815780494672359539578846131454686016231546\
-53516110019262654169546448150720422402277597427867153175795376288332\
-44985694861278948248755535786849730970552604439202492188238906165904\
-17001153767630136468492576294782622108165447432670102136917259647989\
-4491876959432609670712659248448274430
-
-# 2^512 - 1
-13407807929942597099574024998205846127479365820592393377723561443721\
-76403007354697680187429816690342769003185818648605085375388281194656\
-9946433649006084095:1:\
-13407807929942597099574024998205846127479365820592393377723561443721\
-76403007354697680187429816690342769003185818648605085375388281194656\
-9946433649006084094
-
-89094716573076464980713547115099137014719483620102078148320806773871\
-083148864:\
-49505213825110728957828173754776257356620450607893971553289366249708\
-672306581:\
-39589502747965736022885373360322879658099033012208106595031440524162\
-410842283
-
-65894747009896006767807716946835412110318548717263922395390971078905\
-789585431:\
-38842697419255082259907154168620472841946037999026507486310396086843\
-67281358:\
-62010477267970498541817001529973364826123944917361271646759931470221\
-422304073
-
-5950196396451977566902121301707054218364717196893101360011491777\
-7619522537369647091659626133477106071641786829877837558948110242\
-88429224592316636383:\
-8750653273562160761286422180115618621879821429145276197424652349\
-306577311499807887070429373153777028581165316131683348567:\
-5950196396451977566902121292956400944802556435606679179895873155\
-8821308245916885117413102640411332956643707959173543827410339957\
-07263908460633287816
-
-9815262808265519920770782360080149146267723690:\
-1406700576889160928136491935811529134135218991825578039756006074\
-8765650205261663193732434161580120817:\
--140670057688916092813649193581152913413521899182557803877447979\
-40500130284490880833652285015312397127
-
--390149102941948621568479722346940666704376013734485343840154221\
-6058534125031549938788864908670209347775308945934163371753998650\
-65870417717658815158195790:\
-1456031684988128870809574635750149625240648487837308:\
--390149102941948621568479722346940666704376013734485343840154221\
-6058534125031549938788864908670209347789869262784044660462094397\
-01620567342899463646033098
-
-7473774301764883450943:\
--262563698593678907551573728200523874834027237901855629084919338\
-12453:\
-2625636985936789075515737282005238748340272379765933721025681726\
-3396
-
-3624634325121492202413918675700914884929548559339795200323734966\
-0142296147421019916619944353877490544706223768684758263065399016\
-597969:\
-2574427901445527995149185461475228850098549655325125750771680756\
-4031046245695227927925972232181431549249881995623555170649626659\
-54307425375180:\
--257442786519918474393426343733604209308940080602964015737372875\
-3165754964427226645371577306598198801047497654856131748380204402\
-888908408777211
-
-30129746266682790628283889040897642317014108334116727:\
--158048052389539876256372171547438090363007387136214391586439872\
-4834897608423:\
-1580480523895398762563751845220647586420702155251184813506715738\
-943231725150
-
--4614735863800137951667138933166372061:\
-87175694379075561307234146162193190462135078700346746992273:\
--87175694379075561307238760898056990600086745839279913364334
-
--3753904:\
--11269137783745339515071988205310702154422777729974:\
-11269137783745339515071988205310702154422773976070
-
-5925239484953794400820212797381700884029188584554700501406527871\
-71830058864932939900794505955437856926902975870288:\
--205854658295495452479104108497931263758143158076949293929661651\
-111:\
-5925239484953794400820212797381700884029188584556759047989482826\
-24309162973430871164552649113514806220832637521399
-
--33993701617495591491176844355:\
-3438065097398894672826284379125235190693300918673662774192379185\
-002391232383325160416036963599856704698280:\
--343806509739889467282628437912523519069330091867366277419237918\
-5002391232383359154117654459191347881542635
-
-26876428790838270949718735111909136008255051776703:\
--178112811296681037328619200883114927554699563526876724185996760\
-9117529616872536681035700534316457543887601645022:\
-1781128112966810373286192008831149275546995635268767241859967635\
-993958407710807630754435646225593552142653421725
-
-2059771092932179758019770618974659367350250375647433386639519387\
-69317693429941871882153770641334267205446421916220398066553188:\
-3342500267594994347156312297990633112620923791590960237694328174\
-171473763026:\
-2059771092932179758019770618974659367350250375647399961636843437\
-74970537117643881249041149717542676245208727588046226592790162
-
-5545520403000578843599072515870982842927227412121917598877293331\
-575380404618111609:\
-5991287327241003718821424770352575362437680738923552868139860461\
-945460339860477495902:\
--598574180683800313997782569783670437959475351151143095054098316\
-8613884959455859384293
-
-248039029608125071340:\
-3664608673:\
-248039029604460462667
-
-15425705711415937103627:\
--143550406551774570344004527686898291075408140547412300376755421\
-1132837427846963435621523810229738262235546179779885824:\
-1435504065517745703440045276868982910754081405474123003767554211\
-132837427846963435621523810229753687941257595716989451
-
-5088284720510864560728156892268365268867173823603073291434760082\
-1086:\
-12176160963158:\
-5088284720510864560728156892268365268867173823603073290217143985\
-7928
-
--354265185659858189476700478770330228855421724619735662285097710\
-5341631254320181588119095376220762923216041205830017303882425678\
-3171761132:\
--486486260736646884318469435312383053458853801109381241820880813\
-5799:\
--354265185659858189476700478770330228855421724619735662285097710\
-5341630767833920851472211057751327610832987746976216194501183857\
-4363625333
-
--142859621471226831038214482817138481252017914160812187001355640\
-2879770424002218157546599921571184:\
--4054101:\
--142859621471226831038214482817138481252017914160812187001355640\
-2879770424002218157546599917517083
-
--200931:\
--445588024601304957594828329131607177911517867255705194754496076\
-5970517168228311149083493083504573514296684748300915751495017756\
-5952218520297258834187372:\
-4455880246013049575948283291316071779115178672557051947544960765\
-9705171682283111490834930835045735142966847483009157514950177565\
-952218520297258833986441
-
-105704314890799915321259:\
-8279235459450764155749124384991698144145630668774941008316577611\
-9049069747385436947778487411878749535140554980332961534712093812\
-3226038208:\
--827923545945076415574912438499169814414563066877494100831657761\
-1904906974738543694777848741187874953514055498033295096428060473\
-23310716949
-
-1448979433940064018828919290452280235308901982649341:\
-303926827425887072291878308433008512899006711759770318009:\
--303925378446453132227859479513718060618771402857787668668
-
--243237595290235750457450892290434789864:\
-1981770207633427640298127306741732109846753330094746386538370200\
-5126562800253466403934608765512316565811954342319565128573969:\
--198177020763342764029812730674173210984675333009474638653837020\
-05126562800253466403934852003107606801562411793211855563363833
-
-294037338365659932242802023634:\
-4401245995535867764294876849802142926077599828776505639975554254\
-356763769548465:\
--440124599553586776429487684980214292607759982877621160263718859\
-4424520967524831
-
-7303853946195223307036710881687367004566538357189824031021831088\
-365362:\
-119286025999378935715794641163321741:\
-7303853946195223307036710881687366885280512357810888315227189925\
-043621
-
-5711673553432872356876026107141104160674262893635054129088049406\
-96550592413192300554016875:\
-15872188842802631759540597:\
-5711673553432872356876026107141104160674262893635054129088049406\
-80678403570389668794476278
-
-1002240129784524388754179399598974973256811336031329881209395070\
-412702275169416754240:\
-5942948247886059134314539354042003351647830595287234900671578947\
-7946474753657206800070515207967709079933420746952:\
--594294824788605913431453935394177933866937815641181696071168145\
-04689663417625876918861120137555006804764003992712
-
-1370431648825444838359719050380239722263203134555431526491525074\
-601463042144798545817957389:\
-3473869878:\
-1370431648825444838359719050380239722263203134555431526491525074\
-601463042144798542344087511
-
-8548280229254726209:\
-3306612503526990498184932043401689273494314593558214198996828084\
-6973981913056248918:\
--330661250352699049818493204340168927349431459355821419899682808\
-38425701683801522709
-
--190235588326875064895081507959663321759901299630299289585841701\
-1175963029327693964733408210016910253836443785984639809506517193\
-6899503:\
-2489927112752354534228346876280965340763863196622012469575197689\
-4193103779443050843040771191227522843088079031762445684377195650\
-493065096847292797:\
--248992711275425689011161562692991615584345982983961148257150068\
-2315168794955481047333404813087485692518824813430081012223704204\
-8588130268784192300
-
--180035357552270638928830562379719669053087020435672292804206122\
-8497437075035917720399302198953687023:\
--118756682615304660537085387309407764121711064830726245327571774\
-71384128016458332544642788404765469924496127460164:\
-1187566826152866570013301602455148810654730928638209366255282074\
-8456085955229835107567752487045070622297173773141
-
--29861551039945217879:\
-1113473025916855642353456146647542930581669082348409639697282960\
-8778892265003199963808382325823762328728689476247937892128298859\
-34:\
--111347302591685564235345614664754293058166908234840963969728296\
-0877889226500319996380838232582376232872868947654655340252775103\
-813
-
-5655329636567611538382182775649579176587072976497579206763033016\
-55328103665512287797108510139837643506491641987188791892506290:\
--2188105671531473889939411772533707:\
-5655329636567611538382182775649579176587072976497579206763033016\
-55328103665512287797108510142025749178023115877128203665039997
-
--349535960680522202843083381184496349093812380954435872337802226:\
--1829600726218222026679938:\
--349535960680522202843083381184496349091982780228217650311122288\
-
--1:-6726974989587128275:6726974989587128274
-
--107142709838121196902389095205618516687047338619382145236348309\
-762148611647954748824:42484103615491:\
--107142709838121196902389095205618516687047338619382145236348309\
-762148654132058364315
-
--905466304300857697648396075281161213818488784945743608120275996\
-40018921358040178215575723:\
--118922408531468986902800063237122125617455464103913195171141030\
-774109638861272017660698580914239435114280434761425243:\
-1189224085314689869028000631465754951873696943390735876430249093\
-92260760366697656848670981274220513756240256545849520
-
--554504466708242712880172641672765736000158843011357818285065757\
-3063241939882570324573086267287272360432363387213743735507218270\
-373633222520429:\
--151423255459028627628896755237194376177115:\
--554504466708242712880172641672765736000158843011357818285065757\
-3063241939882570324573086267287272360280940131754715107878321515\
-136438846343314
-
--5247636471953421659649611318164848102069:\
--4024324110573096565232590473170599175885004:\
-4019076474101143143572940861852434327782935
-
-3941289260601504332248485425387937172318645783859022479504017847\
-2832:\
--503832132195745214503468781543289068482546657912347492184846539\
-3400312:\
-5077734214563467188357172669686770056548653036962065146643505571\
-873144
-
--559794145880092270356836245052087667531874697277996402772042742\
-07843317583292736333912783829528270272642583004969175230274821:\
--109633110576212669339535976775635762395927171313557427036242111\
-4760163985793453669084013340255712657141281083080320737794421813\
-69365924213118258269679:\
-1096331105762126693395359207962211743867001356299329218274753582\
-8854667077970508970412712618225368242139177439524824425117190872\
-6782919243943027994858
-
--387523538981733893474792162857729999063252864213028668543507370\
-50533204094183249691110:\
-2428819407377764342156426895396654728835493564788997075896393065\
-230009911546390816091652653701035085361:\
--242881940737776438090878079357004407631470985056199698222167948\
-6532876765897127866624856747884284776471
-
--2784579005241382005249492720344:\
--164204542616919252351131740123094674:\
-164201758037914010969126490630374330
-
-2009488574208715447478080609723750390524012808225058048517328681\
-00:\
--795957177479360455258269298038670876462147576765875895105714:\
-2009496533780490241082633192416730777232777429700825707276279738\
-14
-
-217570540819:\
-1219550835977204209833842821666933073941855304313684768349807483\
-02158718406063500763434561937200696970170700:\
--121955083597720420983384282166693307394185530431368476834980748\
-302158718406063500763434561937200479399629881
-
-2335319252198456765380587281374076367944:\
--4500271:\
-2335319252198456765380587281374080868215
-
--393694614027544181700073367147249369966344727230221941008713805\
-434207925307052598:\
--153972676737062409261153899615588515236137907791841623991260363\
-8406802955653131579724891681323455217806580074596028231257978067\
-70:\
-1539726767370624092611538996155885152361379077914479293772328196\
-5898022219816590860252282340511529983964929365416861520049075417\
-2
-
-114832549702862263167:\
-1292186490722995955874527641883028787538667360089228102228659716\
-5773569473039953984775959232814911435097412913078625:\
--129218649072299595587452764188302878753866736008922810222865971\
-65773569473039953984775959232814796602547710050815458
-
-6489502346837936889305337487724547956628371915228387374094443896\
-2663621059310651530729834259117675802940765940789328350084947778\
-66083:\
-1099205476533612407829257935144627350486541654788267826664706620\
-630745291371323154513322608446957760026881954001581:\
-6489502346837936888206132011190935548799113980083760023607902241\
-4780942792663585324422381345404444257807539856319750749816128238\
-64502
-
-1699911441239587542538013131736629773378508702733583789516405216\
-01077152994474340806917796870911557233689087716056557:\
--15409167:\
-1699911441239587542538013131736629773378508702733583789516405216\
-01077152994474340806917796870911557233689087731465724
-
-[Multiplication]
-0:0:0
-0:1:0
-1:0:0
-1:-1:-1
--1:1:-1
--1:-1:1
-
--0:5:0
-5:-0:0
--5:-0:0
--0:-5:0
-
-4294967296:4294967295:18446744069414584320
-
-# Tests on sign handling and linear mul
-15928512:20395958369873946873946873498674938762987:\
-324877267646037601269025261886125746185503585344
-
--15928512:20395958369873946873946873498674938762987:\
--324877267646037601269025261886125746185503585344
-
-15928512:-20395958369873946873946873498674938762987:\
--324877267646037601269025261886125746185503585344
-
--15928512:-20395958369873946873946873498674938762987:\
-324877267646037601269025261886125746185503585344
-
-20395958369873946873946873498674938762987:15928512:\
-324877267646037601269025261886125746185503585344
-
--20395958369873946873946873498674938762987:15928512:\
--324877267646037601269025261886125746185503585344
-
-20395958369873946873946873498674938762987:-15928512:\
--324877267646037601269025261886125746185503585344
-
--20395958369873946873946873498674938762987:-15928512:\
-324877267646037601269025261886125746185503585344
-
-# Some tests for comba4
-340282366920938463444927863358058067579:\
-340282366920938463463374325956791500548:\
-11579208923731619541729378749232972134965448161202875719419539386122\
-8599533292
-
-340282366920938463463374607431768211455:\
-170141183460469231731687303715884105728:\
-57896044618658097711785492504343953926464851149359812787997104700240\
-680714240
-
-170141183460469231731687303715884697989:\
-255211775190703847597530955573823923340:\
-43422033463993573283839119378257736288536818090295526758568867574118\
-988163260
-
-297747071055821155530452781502797180927:\
-170141183460468022805867689086709264301:\
-50659039041325475543690391927479197318639397862390185708883012434796\
-959187027
-
-14601326942920387013816701832353570086:\
-24264364577528921915881695974297771845:\
-35429192025871610141024926748879851702222338457773664017578783702084\
-5028670
-
-146013269429203870138167018323535700860:\
-242643645775289219158816959742977718450:\
-35429192025871610141024926748879851702222338457773664017578783702084\
-502867000
-
-14601326942920387013816701832353570086:\
-242643645775289219158816959742977718450:\
-35429192025871610141024926748879851702222338457773664017578783702084\
-50286700
-
-146013269429203870138167018323535700860:\
-24264364577528921915881695974297771845:\
-35429192025871610141024926748879851702222338457773664017578783702084\
-50286700
-
-# This one triggered an internal error in the Karatsuba routines pre-1.5.1
-84464209123861960605955522581978104887597821936897255830387847065955\
-8899906113628751877643450961:\
-98736951733086678034646082696089517704609210537259909243889983275639\
-1381482452634765035178337262:\
-83397385394360978145497699467080869269009479990938738462835142243431\
-68965095514489024855209740810586369398339972616667107927536797156602\
-16305715905081674268833475056324309733116240691616008782
-
-# Bunch of random tests
-65391683115015322641882045438465620784076516421367563767344998373464\
-211053082289513139:\
-14690551177765498638640685224012137037306962019402563878738998365076\
-1050984890:\
-96063986740135661881270234408778414507112892608292678410994214305223\
-58175678639192181958429173932035325313118014847793404794351246657465\
-400198770681540554545469710
-
-1459164589787755339073553407089181299573246969:\
-4955710571301004201072727045590614350659542263:\
-72311973828792724517911747511119452992590495960205135450079047249531\
-44018123225390192150847
-
-3793974577745786452436021977649815501504431203:\
-2923303082707524288431115654231878223978230055:\
-11090937578838235312365399492067271746660860774658228109409108903923\
-640884753924587454406165
-
-101303541515453867913135264584014138619190734343846977507421629791:\
-36729564208551355196057918758932548366821793131129547653209379728:\
-37208349326455106997710672468998674976019345812041319483326955314975\
-51053692760634209776285429196890853333966465984989349956276848
-
-44895767034162990997987303986882660674722497505237491649296190658571\
-47197906588923414435381184370662953551284823547380833018151742197013\
-59303201872276975123159197578062043415450227149917179130060317248184\
-61724742069401359454784533576615919680949125073761586043027941204059\
-690093447093117249681641020785611986:\
-16696330082433130739210985196630214321753266552182432027772967004925\
-52487573743509832387533060375698218277114850491112782115377202073776\
-62825100480410971654051009789510884031202872930809935194297665183801\
-70736075740497155051843194560584923206479837331572253151736065154330\
-02181215131563438851752144164132708:\
-74959454570640520505374182178324326203870806497691482733643463532317\
-75442982425470080130736910895976501997512084030656668411349679742847\
-21690931312000529989464756559726986788294230843854125058213935382088\
-33087270201941766663613578038620398830216648062658181759195126557523\
-37555785758593956590738976578724612143644830770362020115624628734003\
-14793973405636949715493148568894826023486325367366577289710265462268\
-93078189596361078496041841642207401666400444087608269521582499768080\
-07159362627730642339199533209051979652974085966347840098279340160090\
-19527545420793815544675402025957881285966830564213200530247666994380\
-88
-
-31239732497959818638292779200667312725332984706050265703512759466859\
-84736003183931208107094690791134882086398364414246612787541657212152\
-296954515345861259:\
-44486010269203082806521604993132013139417339215738521529001729101974\
-65470989031351517957857643691181436996411785695418178273749379126148\
-152297344989418668:\
-13897310607113977660431400418487955410781290158603183057898927941454\
-42790371799023389229350908578189623154651948470463734628718228022175\
-37160459735416212605027206307627525795256098590275806474422724678539\
-64782315844000916960349331847619603498272594899577643345409426860228\
-282896290162148120168283702192583012
-
-91271582:\
-1044096341139516502862794205655492738851558322471722173871372437\
-43310942332:\
-952963248162153539313947560906101692644945912572602330737192268\
-7571591624552409224
-
--91271582:\
-1044096341139516502862794205655492738851558322471722173871372437\
-43310942332:\
--952963248162153539313947560906101692644945912572602330737192268\
-7571591624552409224
-
-91271582:\
--1044096341139516502862794205655492738851558322471722173871372437\
-43310942332:\
--952963248162153539313947560906101692644945912572602330737192268\
-7571591624552409224
-
--91271582:\
--1044096341139516502862794205655492738851558322471722173871372437\
-43310942332:\
-952963248162153539313947560906101692644945912572602330737192268\
-7571591624552409224
-
--9007685545468534598743641658049346286545924671394080257:\
-2708960019652616340610787776914583117699836940876415749938089814\
-6081690884713840035653793589401490015282276:\
--244014600122770296285710957465763428914667734328300934010213909\
-4856883353826536741655516010662407431799548978798414309377210905\
-45677125226465989158836569253624932
-
-428475864:\
-1642909320501970182957064144199510240834448195404018829560344234\
-44879791407290995292738391711524351126135935031044584272585059146:\
-7039469905757345878447661340893057388183882714889777970681372359\
-9286724999378785107476015314565835105810467743874695068716694731\
-073452144
-
-3804585298456788532803090036944486:\
-9742592765295469751314273699067197683737589672961737725951028020\
-8013084557451228262241241203602290304633025697300826898557186337\
-686135242:\
-3706652520369461349681131925078860959899355051485269139180490532\
-0467536020217182138330427311026318308608257076867490449833762996\
-8681057630927906028048393947534475842175612
-
--35149344750729324695898480464299390828429941822615:\
-1752615203067497391770113249494248437526672507748487522889401580\
-803582387921659886646983402010731854517398777968222841997058767:\
--616032759879889488930577794740723910260183908336496340745761376\
-2386195653397211971686493794958963315038864032857733526167220510\
-1088470032335610958791871921057479688753244615705
-
-2224887148112689653000916580023252657898661078193469990759133236\
-362617772742210818665763748892926451655031017362736825860:\
--2254472752938568904593125981795197834529:\
--501594745378325694157035263090451802038729306146676277613732491\
-0318865702652093235942446178330845500337957245272966813848791221\
-008304843258214793080794968119940
-
--326328701700361893997973482656600190641887240518503116265346556\
-55295515493003511016396059566561:\
--21680483:\
-7074963869626767136670866125187215271008195405978317997637869508\
-45488283622299239531287490699813128963
-
-4389513377810870521262475775128351860157070070803223156864617016\
-76781196153736168934878334587194620411888:\
-1591402338122279449286758479905480147444383058415555680119818315\
-:\
-6985481852667243947827954917503754523391596798272663056116832798\
-8639257425760121941859610354487659319836581325691828420744517855\
-7475650610301655551351877918657026128720
-
--5742879080477972131875:-117203:\
-673082656869259767772145625
-
--41663152776865616597841653055290004804009193:\
-5835026797641751552624640633869101411165325469966866477145:\
--243105612927253227498125135247022492715711849036333775420426222\
-096834839368617968764219011608104393985
-
-4173221:-226716880742:-946139647767009982
-
--2:-419149616949225277707956479498985786267693664978807:\
-838299233898450555415912958997971572535387329957614
-
--7465837654969091645574504830799010297689933581098938996:\
--202766795624052324242807175739440132217946363911505883055059139\
-6802793334274781900133686867487904621446567316359570842284699541\
-23774859572282855983153:\
-1513823977947471878037349023375096499530047411943626417913495002\
-9266163268789802231784935230530990513196596039364219349962480236\
-2882318096853516252518151818670572226535777283574688903592768015\
-9878750734388
-
-3279753735679960497081857312:\
--120409079507914667933587089469886612743428895521786295640815348\
-9755449324053336110735728979481112654778080841040146337772577107\
-9932:\
--394912128325868511771837525267263805962903118191080245346895278\
-2101319174909498798792301813784053942666817514010081546325334905\
-4670131212205861739934570662784
-
-4087017444924453990694625061188553846924665921421375573052029701\
-043709060984050262732827338392612774866740696110490073121:\
-3201354694306000008850909268274836475189060544721638298393454399\
-7010152870984867537367271090975150700374414635283625090662581086\
-8464508777654674:\
-1308399248301941463281797376424136020032561422146839113205163993\
-0095140051921364225220153999482159067766281848161373837807682105\
-9323529563247238502827327776282135135915279474234713191582888777\
-1511404594446973439104298431438185694530043948690757478249515261\
-147417554
-
--179313367402631288677862721876578030440889951889929042528322527\
-8085266134713795430545312954193172520148465554221323897345577960\
-264434757547077538451:\
--33744480794260115381826015778:\
-6050836482472199350882052360070598557985968830769735487227048700\
-2553193437634540742425617610465933528817398184780529934951394335\
-131691780368690568505046871430214639380927679878
-
-3180313045123330718974011402998828102633:\
--395949120505103380356259679899143757026704962287504981215815665\
-380:\
--125924215314748995932963128833366357734780900635789980947564937\
-2075592673896477843481666129302983824945540
-
-78394433139310872652394899769973779113149326061838893498:\
--506317937717:\
--396925077155891232039161994526220415197346559686986697686085602\
-64066
-
-6992304690095528264306828961300165566845561346363146805401105701\
-874655545973774463962200355744318214727682521358902:\
--133619017321721689986267587295828262450483752049648766344634742\
-91685037600448415:\
--934304881504630204568833073073911400366279420013023235031438382\
-2934806501904607000964107025275607243164225972618594885288739045\
-8800341193419320569112624739820560918330202201239246722530352040\
-330
-
--279747165826180670739009508896477442612565831634509:\
-1001070223323787961662547493417138134890156942660669560843733241\
-4633638061364752177870909932683912027813180522891316:\
--280046557767811427898723527174997897592562433513837063010261215\
-7561198396498373067781895023542952270308263849208412127831845586\
-715174925803969788307318868622842023844
-
--152342817045381492055715979459468344477216937481934776490228525\
-31778605803188114866165739904589756975:\
--2212835903613879894390831209261230372573882516571420663066:\
-3371096552157007383916181066595556807779212082757370662982557178\
-6303181325061530061815766217946054712863588378057790411549645679\
-971413325974723607366298385350
-
--6494091656668836641394369738257289569440116499061905611026:\
-1112275782840317521987084233672591688806254182453409490318139855\
-2744964172429976273740793816660934415725201105937791700128767940\
-628761787374194934304:\
--722322088125810479882613158179027486065378866899909715094586413\
-7631103621500568007359634288605863429230875357724233639767911115\
-2068815511020712301669909478881408853498125187530355741482610911\
-208923048035904
-
-1259075970239705718009909682383850925181613342972607875664276820\
-78026:\
--318663749166949940724436640747496455489904112200179629829091439\
-2694468149048117282961429675979014117768927070124265356881836359\
-049426402836926666527884852:\
--401221869162599711356856060105595763645472859526212982202400149\
-5177647664741074762667141421159412849263518723551697751858002053\
-7542672075930439535906386249755965714824568354356750289932068520\
-3787316784029369163777807462152
-
-2209196064019679034549708549203671427517764511470713969280084552\
-75125503453318134640933653347485145888239438775112197321859:\
-124322370280092642752:\
-2746524910923777881431201305680978264281158564024544236980377993\
-0636867162970792373254349391903852439413048040893096230035640839\
-019184047515968
-
-3082058203728546610432890576347992072668373530737159518097003484\
-3125203068791784796435721368414598060677372556794113220896530315\
-739449185455779351233:\
--552090427013053554588518469958636851397777719282856055637956259\
-9226137:\
--170157482977557810525065897604283065952067566293743982849411731\
-4057452157313429551986153220866320527892664570619020242072409661\
-0134368039649413644973455415575096896642638467426667020714240674\
-6077334196123944909716776921
-
--750276999830609236437180125267494301299136351451377419221886149\
-8911986254315057380891206497595590249266192106292303419043717156\
-81219472681905129612:\
-4205355271908551:\
--315518133662938357806548055254433388492269241826339016138263604\
-4618312099336135707474248962067915083570475597285597855437079628\
-850888491804577876260379972266112212
-
--891480538085009501272618223055661423871310460861205688650041631\
-6753749755092306432442174291514301244257968406437077389253407330\
-1027650622821713282798669:\
-1823891225274156993815141670030683418070006803521364429343774264\
-50339496570500278332821206013754250417471107492:\
--162596353091593275777884582766611115972439819895849702568800957\
-2367685595981932088283461337162038543383704114341129033405716497\
-0880798827330185683075499346562579922155299739327439570345879557\
-1617840239191503928488539315719099552021212289189718073280973406\
-93528148
-
-2124681182585249920847800665256356364758375848619965937406893722\
-55899052138313727858090571132568351249080019:\
-166675024913973810158544:\
-3541312890416478684229072496000778308444354108581194567659019593\
-9857314201986899403459218685673527418723464730927296640736532532\
-336
-
-1821270812209449323858422000208483696090755511739052940949819411\
-630382944845340233359392421633:\
-2128599324432790723202832411330404647604668944765842006449683716\
-50019:\
-3876755820478193889141631692181181045914395285524928078325690250\
-7363257606428059488182369494828732792776883797717522047063810333\
-3437096328016399478420072360461027
-
--335011184237031303208123967960797661123087083840830392886248022\
-143119440501379:\
--230989343999262588479185165706529031246884375719671837094628940\
-050182325:\
-7738401367932796012865144293474273194190542200590231371857014534\
-2578579884777706655220887725142189714172038628849075667359933189\
-054779585318363926175
-
-9198355732743233736216530024186914753135748283508055875656089812\
-193:\
-5265840759145098384429490542373787636725124845354712989635142593\
-95934459401303991397630:\
-4843707653459529764586164414557294257741706853681297466140467212\
-4298268715305496704100180574245676306441226124334746402488026433\
-56143901511622354285302590
-
-8714296327732867082392471731937188058841333771145620157971112718\
-8495045603213379592320067530490555856585188563018570084376435672\
-250185088374873:\
-4210349889307237465841484620878589644044295847340349009991385858\
-7615774626884639631625125100679586906920885988199787927848195684\
-62193938751049439136295957:\
-3669023657886054286232729883213956427553614823342184148988934625\
-8269564694550999939890817870432701814483867503196358666291080568\
-3307419798404926447543906006174853340917944983123029252530968474\
-2688682844881192340842766518335434033712938061191158275417587681\
-07991512024470998588265108393429890288461
-
-2981019:\
-4433245119720584557487584549690245587480169135936518003445698498\
-9177614053957189552768994493672410015:\
-1321558793354433725697708180673306621094454631744034296211369269\
-35453261869513407243405875196532834030505285
-
-3371841482115264548260749392909612923666167033836512042138667346\
-1110922005108438730679287361069225:\
--1224839645782921647445211493292528894:\
--412996512659022216647456819920862349778936230990047619735626685\
-9000246454258876625428723876322584511859911068016361053904468404\
-6687150
-
--339290341643379646242121130133274175571738607527:\
-3271401581452035936363564486098243173858343994842704626634540604\
-0333753792872314861533886742557607640566446319092917014148799834\
-8498182361629081026057:\
--110995496022355374018357458920157866276843573465657648989031507\
-1492983893793639677118229990155541637204519376994267321550212870\
-3024690173524970745190362239190804266551097416929422331908148558\
-3331039
-
--302193108025958893465396831014238400181355654244499365872812914\
-0671578942520441667218976086488594667623103779245243552871642908\
-5538517727995241:\
-2017851085218627867440914776334445037676170997318580940821659303\
-5046997219650546605682041506090881913886238203842281306969809595\
-246163485422064601589012:\
--609780690975771196107607785560739006824539433569270870499177868\
-0127071341610096112489032765719159734331084718676312427284431166\
-3160752183891441001416955478885614399224358737795082762053960238\
-3642229098982445564368202356432336746046757695325766162758445391\
-517573101567916271503836326565773891892
-
--35188123484838216734793425643059054080:\
-9000600267361446370368675857998:\
--316714233645582443508665110125938608546684298371094101256326282\
-531840
-
--287546392987328273673797823271747266125547785306672698267720774\
-608232552065:-724:\
-2081835885228256701398296240487450206748965965620310335458298408\
-16360367695060
-
-7239719440345013275638025455463886572537307213436218405718641390\
-921197615256801869733473418374:\
-1273855558831670011845427584052189147328498974982056877978612327\
-370857472534105245496452412950690926717874:\
-9222356853465202151464594272999727525831895475287638674380433334\
-6933374970835844231896759667044442575039030759210684473734626375\
-4867082551600245844507805177238750672856996150996602083141097106\
-5816876
-
--467193764317015751447832154618223252689085556761857235622959651\
-6527745:\
-4062614168720459964554950353412675872692580185950353528672485067\
-66348747462819:\
--189802800645215543819126042173342480893460145936335827236015901\
-5836446083789360925533289958276050415814781716398053517857780132\
-893397801668369413155
-
--256291521346916076469577753590332243088939322304016068224382551\
-5025546499325406138:\
--605053480861014149406513375530972230393655979785947325614347032\
-55672033601321733124376224905086861012031956149097:\
-1550700771061164855884803447589885127420417575088485989466750817\
-5220547092689946197222125349076097067231864772732377382975294424\
-7005994565440548405623573916996459703805738162154040744466006957\
-386
-
-37657585687987148872355696565539718:\
--1434800894234388160687:\
--54031137619832058507887448613713814837731429449464666266
-
-4393856668836163872660314169038850961070596126492582636740923958\
-869429568049592915508:\
--725654263195468754856026662040358630736857297829750596111795962\
-7542041685201743870533093436197634453:\
--318842082361080325483580016771866191199973311649234286812044253\
-9591641099237099919800666371105550379907533870255064162462208188\
-3994207992073068621770789270796474452792924978217098797124
-
--22262682191673391309862211106958012450603677337242458360760:\
-220733215635032249425562508910063071532478728405839033930940264210:\
--491411342882883504420371271016231681619217410641501118113820080\
-3099803240779721785281408106422401055283687004275837896399600
-
--1943809061953917342683052893090:\
-7700827546161027851150293971073751401383411867756623153657156490\
-3719544057834222201379883202137441380031452353172493763083243:\
--149689383687721546514336832201365455374120959277626078690972108\
-3971845846592875060793450410610935237925773161603531529842259112\
-43685728191984096169649490870
-
-3786170367178724834730573252874138148565139634940161475730134462\
-072806346795721773969696184:\
-5642009735645474144794852846572624514752624565190901861011302937\
-5113755663421195546:\
-2136161007243476508223846179651669079978058344237194176489154392\
-7622668375501304536598877419397709190638503067245194075783305398\
-2326877049744197485569753314370744763673996464
-
-13489797398057489738508057443:\
--39829491566872094526554950598431919339453350924955014031891083289:\
--537291771704743910798219370322043426391226290103531988511540464\
-278547553363892492512309370027
-
--323325112374943657482631147177688351925959386858544487312506089\
-86289604167358883842577746321363893167908786:\
--246925431746938028131175064627088867042153744157154625487424933\
-24630571161151476958595194:\
-7983719296781021810724607567340308787943618592037051108694438338\
-2489270621359904712938918152105643713875728369108646194020367483\
-4484438934808794593359943127130153265367987222230213154933289974\
-484
-
--435100258456539648627052287294649432161393329378094060187883773\
-2690708495675481854054541928447945875268:\
--10155417715410577307402999881053155099930501238885853034128275227:\
-4418624872709263597834477604499556163338660202529113122166495103\
-6300436212506625541915615934966052700868562630468721925914800339\
-297995368984918582710621377945716385836
-
-# comba8 tests (256x256->512)
-11579208923731619541729388327330122708943419524243289762333678181937\
-5385575424:\
-74179307167655687693225162271190690968501083926425986337482366849894\
-604086426:\
-85893769551194762664489787067237470111583081643887491027483108939248\
-54152414995879834924747381994424629165311199542893443807287227310529\
-677629685837594624
-
-11574114654373435432769681547953871289980961721498085841658839565237\
-8326940031:\
-10711660777805634592035489333768778748163480146501669697332609614056\
-735426801:\
-12397798998107734697368913960056304565756856899698066529320990905885\
-80174831683647898327881664370985256756518936891247178025618131778049\
-267698975117170831
-
-27006267526871349343129256945225699676622244016828866963870625652221\
-609619338:\
-10706691322561929820710026337093404691680917641214496572907959829962\
-995350055:\
-28914777018473950489193423936996699498718323255670979720398132582868\
-12326099575727022500582226148289338093647474428048875439902371078972\
-17011952607363590
-
-# Karatsuba tests (512x512->1024)
-67039039649712985497870124991029230637396829102961966888617807218608\
-82015036773488400937149083451713845015929093243025426876941405973284\
-973216824503042048:\
-67039039649712985497870124991029230637396829102961966888617807218608\
-82015036773488400937149083451713845015929093243025426876941405973284\
-973216824503042048:\
-44942328371557897693232629769725618340449424473557664318357520289433\
-16895137524078317711933060188400528002846996784833941469744220360415\
-56232118576598685310944419733562163713190755549003115235298632707380\
-21251442209537670585615720368478277635206809290837627671146574559986\
-811484619929076208839082406056034304
-
-67039039649712985497870124991029230637396829102961966888617807218608\
-82015036773488400937149083451713845015929093243025426876941405973284\
-973216824503042048:\
-67039039649712985497870124991029230637396829102961966888617807218608\
-82015036773488400937149083451713845015929093243025426876941405973284\
-973216824503042049:\
-44942328371557897693232629769725618340449424473557664318357520289433\
-16895137524078317711933060188400528002846996784833941469744220360415\
-56232118576598685377983459383275149211060880540032345872695461810342\
-17940303990259531467630757141966678572355892742551472687075667803012\
-238361561335049493812299230559076352
-
-67039039649712985497870124991029230637396829102961966888617807218608\
-82015036773488400937149085058651889274919368784987519218104008495487\
-966999617338343424:\
-67039039649712985497870124991029230637396829102961966888617807218608\
-82015036773488400937149085058651889274919368784987519218104008495487\
-966999617338343423:\
-44942328371557897693232629769725618340449424473557664318357520289433\
-16895137524078317711933062342952193277060785350743397497444921769834\
-74555755777883734829695075352889186645794406339299840443362841695908\
-49124479353346416074683250011190629511478487550142982175186156043821\
-992372090244262099992413871225700352
-
-13407807929942597099574024998205846127479365820592393377723561443721\
-76403007354697680187429816690342769003185818648605085375388281194656\
-9946433649006084095:\
-13407807929942597099574024998205846127479365820592393377723561443721\
-76403007354697680187429816690342769003185818648605085375388281194656\
-9946433649006084095:\
-17976931348623159077293051907890247336179769789423065727343008115773\
-26758055009631327084773224075360211201138798713933576587897688144166\
-22492847430639474097562152033539671286128252223189553839160721441767\
-29825032171526323881440273437995950679223090335649513062086992526784\
-5538430714092411695463462326211969025
-
-67039039649712985497870124991029230637396829102961966888617807218608\
-82015036773488400937149083451713845015929093243365709243862344436748\
-347824256271253504:\
-67039039649712985497870124991029230637396829102961966888617807218608\
-82015036773488400937149083451713845015929093243365709243862344436748\
-347824256271253504:\
-44942328371557897693232629769725618340449424473557664318357520289433\
-16895137524078317711933060188400528002846996785290185531506439882279\
-67948175579511934243229492219161469505115934541754787322072497766508\
-32568813609316312895189314891581055577244380152406865341154204627445\
-048144934853380616505964511432278016
-
-67039039649712985497870124991029230637396829102961966888617807218608\
-82015036773488400937149083451713845015929093243365709243862344436748\
-347824256271253504:\
-67039039649712985497870124991029230637396829102961966888617807218608\
-82015036773488400937149083451713845015929093243025426876941405973303\
-419960898212593664:\
-44942328371557897693232629769725618340449424473557664318357520289433\
-16895137524078317711933060188400528002846996785062063500625330121359\
-98742154443577980079599561074597766784810090551438150849000845701430\
-39463393843012149940933139094628420823280505085783531419710269806521\
-710678242326571370194267352288198656
-
-13407807929942597099574024998205846127479365820592393377723561443372\
-67729797885965581514188847955651931542202341709841678538338597448558\
-6698740166243034228:\
-13407807929942597099574024998205846127479365820592393377723557015178\
-15690541073572989474743035547506906776301480077261237516040494971968\
-7212579269664735026:\
-17976931348623159077293051907890247336179769789423065727343002177599\
-00942480367760499251857295455939596154105772404450931317906536826768\
-15455762278256937871060873932808316066099592555454681197347421682785\
-09568862593066461743520871555375522976812396705343420538862100685795\
-3308142564518141627105027011868469928
-
-13407807929942597099574024998205846127479365820592393377723557015178\
-15690541073572989474743035547506906776301480077261237516040494971968\
-7212579269664735026:\
-13407807929942597099574024998205846127479365820592393377723561443372\
-67729797885965581514188847955651931542202341709841678538338597448558\
-6698740166243034228:\
-17976931348623159077293051907890247336179769789423065727343002177599\
-00942480367760499251857295455939596154105772404450931317906536826768\
-15455762278256937871060873932808316066099592555454681197347421682785\
-09568862593066461743520871555375522976812396705343420538862100685795\
-3308142564518141627105027011868469928
-
-# 1024x1024->2048
-17976931348623159077293051907890247336179769789423065727343008115773\
-26758055009631327084773224075360211201138798713933576587897688144166\
-22492847430639474137785575823367462584850327217807092221598818903544\
-47838349239959440410649295502088991241512540406677820071644448472599\
-8099692362528251405302763273230221311:\
-17976931348623159077293051907890247336179769789423065727343008115773\
-26758055009631327084773224075360211201138798713933576587897688144166\
-22492847430639474124377767893424865485276302219601246094119453082952\
-08500576883815068234246288158970519977814343258692149569327420609321\
-7230604120280344292940337537353777151:\
-32317006071311007300714876688669951960444102669715484032130345427524\
-65513886789089319720141152291346368871796092189801949411955915049092\
-10950881523864482855309433042883335846718668037787037650188893055840\
-73018927951831283900011347985854627812829075980481789955530757008122\
-88824849145421420410206954413439564292684600051414432901225421532791\
-01381942730678481306279979329106412319570512109276383150572147028830\
-25199880085119057947572011024091985929007350883874353448844224836795\
-78442377318748543006187648103374862164234771293283689764786919194438\
-37888284136626985706746129572759980426766233612587290367814732695050\
-64961
-
-17976931348623159077293051907890247336179769789423065727343008115773\
-26758055009631327084773224075360211201138798713933576587897688144166\
-22492847430639474124377767893424865485276302219601246094119453082952\
-08500576883815068234246288147391311054082723716335051068458629823994\
-7245938479716304835356329624224137247:\
-10112023883600526980977341698188264126601120506550474471630442065122\
-46301405942917621485184938542390118800640574276587636830692449581093\
-50152226679734704194962494440051486835467919998525700927942192359160\
-54781574497145975881763537082907612467921532090438466226007979275997\
-0325840394840421469887935413626077183:\
-18178315915112441606652118137376847977749807751714959768073319302982\
-61851561318862742342579398163882332490385301856763596544225202215114\
-31159870857173771592553548685191068103016094862345941793100727824215\
-91038007155695622986473612841033928065392845889702175791770421586624\
-26143899184951734174822450721084185903177062211837438496534372480202\
-97467411486790074725866007726424039330919514310082034160544731735015\
-05505148992020823080165429348056649053453259548580079987024817945821\
-06278219961860441688154154020423122651667491374047530445279534822367\
-96606089062121158502205590789299321244993290459201196063373244192071\
-35201
-
-17976931348623159077293051907890247336179769789423065727343008115773\
-26758055009616165775278099964665396948321782087417396060386782903823\
-07012341545824090641587839835926419363551226096078071585202389405050\
-15136893796472153753067084907045685619026471680211462175364329863209\
-0971267582066228875273648785630167039:\
-16853373139334211634962236163647106877668534177584124119384070108537\
-43835676571529369141974897570650198001067623794312728051154082635155\
-83587044466224506991604157400085811392446533330876168213236987265267\
-57969290828576626469605895138179354113202553484064110376679965459995\
-054306732473403578314655902271012864:\
-30297193191854069344420196895628079962916346252858266280122198838304\
-36419268864745685317012104530668242911371513575805609806190451951607\
-10557715881476395538121318622342054920551385626039497775648111929192\
-11010149235353314669473560070738635821344900819492979642122564308821\
-93832836355009007808239907501987022158846860226885245037291654118972\
-21789040347542992939815493420694907963244430325400081905612531817013\
-53434121697017777687388707760265950247661467236793723639977817395453\
-05333658727917987431471148302830409557728284992844256725143219605511\
-19105089461515317003555642348174884134868178964134073119096779203778\
-9696
-
-# a1 = random 512 bit integer
-# b1 = (17*a1) mod 2^512
-# a = (a1 * 2^512) + a1
-# b = (b1 * 2^512) + b1
-17930121528120518743193890185292405362795914617726312913105692310966\
-79834089760159821608571760102261884739604751290203318392915809389705\
-18533152042879507565469760620770664602498091326659618430896499562864\
-33097556186753511259807783990999180942484334496111552855551238437298\
-5931442517394084353378720570213259961:\
-17181164400078273397607302623726933788654231870578267885308639434063\
-29050645768615733989348336532688661355059992510519187273205749318328\
-55178025838720042408416717379221896884862317068300037779659390111981\
-97244867335458644846343599813562216158033039927051277398059877872479\
-1239444995247411522594037321941878345:\
-30806036568802130707161344222425760549041581576622091565254201628592\
-14385467809668014385184785152271193843047948236592285206889142604429\
-75839733409984928244101830825691058271214860952936075111998155431716\
-66320122704699248615782786577874030694743967942269571299270175479177\
-49821546067026790701696727687868585663474591471567191830596615534450\
-88805296433793120856742255208087463783715754626092601017174650889346\
-66486074650833697034162201049220647206717383818466106882937622653918\
-76822429098414628373727606690842310063586870064304131814649299854186\
-12692628024925259230119912648154125622594020560204924767989260701214\
-44545
-
-# 4096x4096->8192
-46230924351836247700632620916046176424079105466354534064042561034208\
-87179012808190823424753309565308557946849439937602914646826017759588\
-34308955397574010098112170264341488598373518621050984822173335661543\
-05503155484221582314725443772226962279179435429752927046418702379683\
-85046488722729558633796252405133615796333361764094300077585699651413\
-87522520295445886581348613967739679507144536630498779984858498466466\
-53949495585121328172175753765616536867610443894070462179968529055982\
-76558996753670646519698363689763792814553110716478538561711411517385\
-25392668340231371551312445292385216029091676115617060930552232679124\
-82696223439453451825724430911002048100764625928528148630937654751536\
-06304398468385126736497735857773379804983839043683211519322520305495\
-88047388177062785807692948814175519084337222913843071456581602029935\
-54683753460812611659451099340378672619627415242236591287093912255783\
-13140160231289453522976275483766396153309206695863277854402154450459\
-37546852895213179224578947936523539421852140479791200605839865108481\
-29541228564089187837510575385124529321309276742969232912010920107981\
-03957776659416089212281297890809164014975660550116306748020139153256\
-22848023511467181919573893647538869361729907908714966872881945389100\
-86101428:\
-54530990288249437719619266581633527950202167725686915722413802215908\
-13898808427693785305297340466057132347876044193194335670208491816947\
-45347065813804383143878587001488929429088856726119741100265880818083\
-08072469093027021085621909472228082331188302646328041787611120322548\
-39496025029182050271578730610401719162676648561607998168984589242763\
-61184308631479552158835170369552925804999967396481740557274002486324\
-19060734996166150772822594482483029608131347141723539465860333111879\
-99028176225288916692803103016047215834727819406429598388635703974625\
-46062134344556400079860063468483319482068487707023772004276424916600\
-70752394601181923057555584615258415106502514105268940487020754841912\
-85424335310397208518018385485167186844809177247714124187041081497708\
-96511319230068019588583992177882717832582994338933822583078086805742\
-83390233167682320436242724359199417834794808081825191377785708613777\
-86102596609226847851937748841875768625507263876321447582064560528748\
-35920609680394258473797857062463125872573573911021820161622994930998\
-20654635987081600595958107506315942531393518613570935900767436989518\
-52479980745679719049556332080920670567304319030704337342023640878866\
-09889825375285512294624431826722345023789066121979651546281497741903\
-392437648:\
-25210180868467768546757726362059843626852926905412382608676629170550\
-13500472614635251047265443464861022066815047034258382305517605789179\
-87828662358961696066164456254433404354134132444755460484661087112315\
-33092792254341786823634449794876609511305489030701548587221933119990\
-83152382137766693945997257582640307701836825909703642483047169261811\
-29415178374784201058252543144281486261236848516767550523665279551861\
-74465512384172617149107052187550658300617578084736260341723260747161\
-99876271562142167533309479325645255667176279131317552047451026692967\
-20839234037422676688042090117497405271103578405099807691583810119265\
-54336379063605406653618342419878681737223923065560012276952760198274\
-01935961653423534734281217002142980219703525915889622098752381243251\
-51337680928833690966007811584949672395686773570000393884061584225434\
-46095563213259068817841045213587660574716357554630835216272902060443\
-34556862089899310391156917797805143517814316196396914215338901147216\
-79277404380234128913536426196746405226500140030500544578565101666905\
-45355602687691883828602277709718492121846971571916556642975486330113\
-36222756064112088369190359637323581593192113210931211230367909305308\
-34626706120315368242528268242337577529275810260388371559227416421225\
-18288153930546296286935770867979820870699234878779491860155905073232\
-51502558862837164130223049756749662881084284616449485647823253076640\
-97817765026456231979422968578849627137552880186111486959114938973490\
-88961199014636207851962534069247724700485273408823799958467863418841\
-50462661461823344684758580652604422779162692518313890388399982545703\
-35206898267568862459046844795531325319249988156277069565297520226091\
-64600766297485223302985129710063725127737025349700933151412377658954\
-23709434501778907216692625235665266668930171909330255035266777372724\
-58877961350127654808072552639834541127026665379146043251830475968219\
-15018615283403488179263459581211497821758602281724174575392739616669\
-25703910463568680165861589391919447127830393426572990195899393637221\
-86477741974371802750413668808535147675421719142045765725335254381364\
-41785131009861024178374832421597792578801840696203626157231517656464\
-14052894526701810933176118179541201020906393719709492349877490392992\
-00696634018140352649412293680281970033556175696751860800582932013588\
-35349743517428143168973670929259662004881928288066741418602389631277\
-36600832956552929991925721216698487543280154312867126099744478225237\
-72707253967514116707979742986501040393426058104944823682176865543029\
-42410605893761344
-
-# Tests for the asymetric Karatsuba. Historically this code has had
-# more bugs in it. Getting good test cases can be hard for this stuff
-
-14092703816360934475287812379721584643540920654551533543420378905278\
-43263869087702953436962300677113653357118503684241080095903812797217\
-981771103880205148628392675409404139:\
-85196387648463903836201075338727419426772257423386800834159433024105\
-22722534550698330414221220484658429569965031071685565584585568273727\
-521831711430243837:\
-12006474573536728376030033121297441343323401321882664768043719554452\
-72355962084445501636044192472676171283378029237295859040510289867684\
-42082336586473179649397097120830906529744851914004493486594202273964\
-92849411579105282151504500626551480203959164076691081552725026900241\
-832342905034386191256909160400547992155689411647041343
-
-57586096570152913699974892898380567793532123114264532903689671329431\
-52103259504474008372078212980297151898765610906745757706580551032703\
-6019308994315074097345724415:\
-14396524142538228424993723224595141948383030778566133225922417832357\
-88025814876118502093019553245074287974691402726686439426645137758175\
-9004827248578768524336431105:\
-82903962954674429277182094016068528967498403743392611678986796248035\
-46708705089408694697316410864619322862709322416615890526565883322100\
-81247286886157264936638535413026388243763541729092783487919143933560\
-11669949922966041936103836718052579102251260556254458882685015932709\
-9748064577321171189330220691056136254107213091963928575
-
-# Got this one wrong in early versions of the asymetric Karatsuba code
-69328033643988284668153554428298153814569184083886776453465872993395\
-29710746972404168269687728407520676676052832464833364865313305188652\
-27796258747613771385136143521786728820782913230366107236761071531140\
-69858079626875179117509513890923817643832927518504150773412897517798\
-24069151513573630274310883822191771430575394116104021217164852793487\
-74039487132887730707079890109620203394040795732717864706534187311456\
-47616397480632810489298476433897092835849191354914181079718876936239\
-96759799034047278741267946259806379049845381337965241128934112089387\
-26387200493807084368512264417392541693498708056601725438254379619500\
-04878549999476514473638562844231061393907117784824855718620742441873\
-33707730767137725282689693949863277338600908221830652962675544003225\
-784824252054526036890965:\
-69328033643988284668153554428298153814569184083886776453465872993395\
-29710746972404168269687728407520676676052832464833364865313305188652\
-27796258747613771385136143521786728820782913230366107236761071531140\
-69858079626875179117509513890923817643832927518504150773412897517798\
-24069151513573630274310883822191771430575394116104021217164852793487\
-74039487132887730707079890109620203394040795732717864706534187311456\
-47616397480632810489298476433897092835849191354914181079718876936239\
-96759799034047278741267946259806379049845381337965241128934112089387\
-26387200493807084368512264417392541693498708056601725438254379619500\
-04878549999476514473638562844231061393907117784824855718620742441873\
-33707730767137725282689693949863277338600908221830652962675544003225\
-784824252054526036890965:\
-48063762489419715168951981307754794589808870758952639965091476616647\
-54056167932393419567481296681069246248216008267853889839320423981745\
-60479443107279226057663425943342008520701374986979347783572983701184\
-85422697584729139817700527441440371002219958422883649678565900879400\
-20025210106297773515746894906726443036026187076658079744151459354129\
-76880294234848336533442648147663722096199825871118396947178334215521\
-76943880892409643115274415151713386236948639022804530054018234460138\
-65934020545172727964007195157289495135921213561302426988267171336165\
-92297396800884174510773976233843978906677436838567701962214997325767\
-17494685809458185719292759364630203908885946118898336175097083972837\
-89342035200573700398720235821406614593531258231227043379738167751614\
-68684582976839207443768269161778663395778873870774323940683360928515\
-48027194465603770338336645857674917792255648723659298382428421752797\
-57375177034382470966583814365325881784225896969066012430257742547184\
-72418596829523189950619686978201887223055028706607853375875849336866\
-58034693741263352377027728101357005623322435070019152178347117503006\
-68898867912930645058149633650634442077017541758124699937775536013889\
-00090985949751232201541388041823183135436540422469067343022614303960\
-55855903221443598575395492738166423176780792097697804248465562838489\
-55947563036566122615600202990367217608222400507033340848053927107788\
-50110168698504066173013701126736282373942179302874896060705586003228\
-79037941627812442489494360833298836822298442280730034168111230609093\
-310545565906004082962175112065394876123298631225
-
-[Square]
-0:0
-
--1:1
-
-1:1
-
-549755813888:302231454903657293676544
-
-18140671814051116644:329083973865108631122076757343293822736
-
-18446744073709551615:340282366920938463426481119284349108225
-
-85070591670813493966310340604280700927:\
-72370055672222822149686532165239924548184855554193955235705358728264\
-18659329
-
-85070591670813493966310340603475394559:\
-72370055672222822149686532163869766764144178225565969340654319581407\
-26804481
-
-85070591670813493970922026622708088831:\
-72370055672222822157532909328992644361925323993014681825303471075565\
-86946561
-
-85070591670813493980145398659562864639:\
-72370055672222822173225663656498083990682319746609654242487350548038\
-36600321
-
-340282366920938463463374607431768211455:\
-11579208923731619542357098500868790785258941993179868711253083479304\
-9593217025
-
-3138550867693340381917894711603833208069318394046068373092:\
-98505015490986198030697600250359034513838056601414221774853647899383\
-99716620339203600092485547982803495343709640464
-
-3291009114642412084309938365114701009965471749407831540748334692:\
-10830740992659433045228180406808920716548582445089016068317535718032\
-308295472658277178853031537853949474393196307576171250734864
-
-# These set off the bug in word3_muladd_2 with sizeof(word) == 1
-251232322172118783022840239225457019863:\
-63117679703995287066909540140557654581113950055128878944628202319505\
-176538769
-
-273689842353342519508740475928754711696:\
-74906129807397480797309133044676004424334564639782656684007505697520\
-079196416
-
-271302823667110475639266093952890097614:\
-73605222129747240032647628582852465568122948805929122728180342334818\
-448492996
-
-319387279021025860024422185475130973014:\
-10200823400045462544411223752203740218511249559589398235010527269723\
-0396244196
-
-293643199753680203052743123832843662352:\
-86226328761579733262787961688682814116999624225084316052032576511892\
-182171904
-
-# word3_muladd_2 bug with sizeof(word) == 2
-202324725318880963191371356135299852624:\
-40935294475360631472543732691759944656086403346062162368816126408076\
-119685376
-
-309321842385349400717946354447033364075:\
-95680002176666937035836738263162897574421497416350873907840493696211\
-500605625
-
-233489517300128090786970749707229607527:\
-54517354689046815002040771363970021549478312409815296261172173208794\
-455055729
-
-[LeftShift]
-2121258017766159160754962465958381577677890208124499494536189186\
-869637798499791383037162061664492554205374097:204:\
-5453968336700566799508983726051663849667997549076624612345231282\
-8439638899716201006845993775936915589934028192020733447985075402\
-867441526514914927633382250278301101719552
-
-9127815530925814339720645654057304030995143310324020188491605652\
-0167383202307739291645752386748299386607033417580789665740910548\
-485496057884342754125:116:\
-7583092465041842489806678334004575989684288504372713429243106807\
-3821340263788338036051275796540123856480834349684104861172576642\
-18512263948855799232636502228939840695954790558990336000
-
-2720447254558553014578566972012963115777446398846598038146885883\
-1866886314261120634838361392523025566783357944737665:164:\
-6361500986895495805616781332881685455158868774711923425935172754\
-6665493357037199343516238602124200135772591677608344475613159685\
-2488399997844504678061831690534256640
-
-2346814922039931311567833556790864002896525919808081028569793383\
-4008825609596357974972673276604:112:\
-1218535974727059175894407931694205043690238717758619344357411498\
-0976423842428997921600747804778709388243970226872640908420343398\
-4
-
-136766652934857914:106:\
-11095829099781028284216214312551702886842940522496
-
--401051144733532769909045041716441134958154294462987253741112236\
-561026903932355958855274471955131:63:\
--369904391368386363775763871932535866765470702774151965641848084\
-2144652587998489299622223077809753503943936440270848
-
-2620878467008554581948549874850974711547561914123735587938770041\
-8388598339275821514904454964587607270922729716663659446422771149\
-9620476383257:195:\
-1316121661879758521098806625253965626323323320500789427869263340\
-6367324456851018233189899650111735222276905756611447392283605658\
-6424209018483795579529997393099798973115070359293039187878410704\
-39858176
-
-4986386024639314608574963909430738820138995826850354329027683283\
-7084148930520285795218001501791951858649714264370213994065039723\
-183:24:\
-8365767539475510328001762170072394222505708301016699425463251243\
-0365357678350782716810417828388796339416772455162018414465188948\
-4421398528
-
--455552309543147716127587827277903635248610246950391821050011180\
-4998378889619941436810075030388024035287640271262080871447338739:\
-87:\
--704933054965487499017626788420861259932661059464379088499410099\
-2559199084336675766400427127749751321008643932765664940335284556\
-99667386383995835821064192
-
-1037757592587696398725288196824188929011363632075879222442626801\
-16359163984447531185310046467135652319371987503:95:\
-4110981359797486520990313529905064933484217701344426282406713957\
-3073026585644903347542613235747258250235327631427113860134353360\
-95122325504
-
-1078541466278039800083311:111:\
-2800053733577506391526406073538574747169164913752227708928
-
--458929098580755:143:\
--5117230445820379540747782782105603341274706553475212247040
-
--122928855329072870073433015110819526943336867562196620340919010\
-07272608951275193:11:\
--251758295713941237910390814946958391179953904767378678458202132\
-62894303132211595264
-
-2253797880121520663606973674330182144804901367932449178312384948\
-1031054670305841291542789729087450336886747413803342773383544037\
-2581272420142035100:211:\
-7417269366041670925252065169199359207792625796677651698479867559\
-0580700643261572311187905593603949279149066613049589728766147448\
-5040626948461011388280995781694782614846527093302465736147768556\
-526048195169484800
-
-6442142951860149863781434107200105215105005142361888584824558528\
-2484597164156116892847036815:107:\
-1045297456599241794709977613787275378715930460342137602357284620\
-3705135174457613106078796927549665575893358403516669173432320
-
-5097783526093860243839154243285093453167843731134916160503060680\
-6809190520533632436146045688586:126:\
-4336714610774466073591769540544761879648163769201204653675081413\
-2084346529112353622016096796405522770364375296300671020674092934\
-10304
-
--331899363008322441533569955164860025843805741291332922663910367\
-2943065616917605415617171113991360901486760154578289560762927508\
-7724:91:\
--821743020962630744101604179924332933222787625033777030204941339\
-2423604240087684356284281911697948345840642580768340681886419299\
-0501324963749459198616746852352
-
--184253938912501307159324447512804721862709269931381112790263931\
-81321750494139191589459903767473167677816275893773523:152:\
--105190403673940947755727602264308003613546006738759564870362217\
-0667469418523232027185126832293519850235443686300723583174147136\
-58107043639016550258714106195345408
-
-4027173611709683208685144938635076643642081573452904517803697826\
-5275420130:216:\
-4241108819962870257795832303288513204199186270237663098986852370\
-8839925819263809342179370062199525789246961806149451534207820475\
-33392199680
-
-1654910280148247058930466878701929681980555724947453908536393353\
-732583647848670616170583254506:78:\
-5001659417042237892080348861898586734617398707583112481824590338\
-23652150179951382510963323144882735068533089594507264
-
--353256518864739539912727355980967022578755727546889874982122719\
-759:107:\
--573191472861980058226433447553366186933814120008015485620963412\
-26306829015345625594865954588721152
-
-3358622889967376849369646308014887582255587127977426994425421674\
-4686208321633331897065809513496651:69:\
-1982581020522590603474492135975397792733918369926415317084561070\
-3822831264254057644126980676514200036423975856884416512
-
--8326918561933317515897484042242279813635:222:\
--561233200828572354853379214799650393202723352144809535912742619\
-21980589457786088539861748815344432096215040
-
-1738239605092625935802720509793:210:\
-2860281191896129448328585042777498571666530315075635885634512550\
-142285038644212151822720172032
-
-1541590531164046827151493969434074217996086405826244177284191842\
-623229626655598394491064824017724575585890968239654882203827:130:\
-2098304299069634414151232805637412871131277307615398366601971342\
-9665834217942888720462643703124214574302721592303513592056859315\
-13427518479162077139334989713768448
-
-1822414219485473007729455052579570934353421556802754634400780753\
-581487672806631709:25:\
-6115007400355837902569347395883763750593834759507216779268585854\
-2958784576028372828684288
-
-5336246625295048457347325312327723275413189882766845079019668950\
-23491709759645168524198853958247909:145:\
-2380045526144475863333782125314997581392105067362688736487270903\
-5095219526391819075074039117499741190364575496806391148745118026\
-089345253900288
-
--276651306081170196285504936260680311592104354245874357656134941\
-6718897362629511494172851413903784541053958724076679151843367695\
-9748070409785949098743856:225:\
--149170089146918319214991272148007797149650392266859882932532072\
-0896314266755406819672840795334582356690986796948912969229786129\
-8759392443252182124719967927140260518022196506128222178285661500\
-32303899305525355025417633792
-
--103357876921000174182112715460846616262383449332882137139998255\
-68582685162004410585410474998733490779307256347656936844453628:\
-128:\
--351708629986009787155639181729583046307639877673123732501848524\
-3559886115426724541117518475093181639785217728536729396711614403\
-275792414126622561825487435090362368
-
-1094708276267187017583512230031436979221999105657255772315062187\
-0590945418853726695999585645264076550:76:\
-8271381875782668577777728720058787519656348054693237381352477271\
-29815039067706300744940289871871309203285264026829638860800
-
--815525457724752321603940535029563571154068567797107498491974746\
-2624523816971433695155984655769263875263814891:185:\
--399932520776254684164524385851380762766645298639846935216904114\
-2896647055743804753583601279854374681737834012702515619494942793\
-50304095670986950350223830081561690112
-
-4052679849880044255138459864411550773099421944874654179650065311\
-7857061613513287290910396020606030441122363087181232793161493035:1:\
-8105359699760088510276919728823101546198843889749308359300130623\
-5714123227026574581820792041212060882244726174362465586322986070\
-
--248399491197694456686506789360892375748400795979825040399299010\
-53517808438265883:176:\
--237919445383638978127975473390525029152877274034190677596480116\
-8519869938343860007136898454280955008871656020990685920874468986\
-585088
-
--341602794141123390057384653491582990307091266762526194256752907\
-742814:102:\
--173213194813054140534683117609830955377834183581805190021073324\
-3591496880056169249935512491320672256
-
--958393530005648757477093349096350288904499954214052393312348399\
-2770943667934610603880158622319612235433869275282625539708353046\
-09:167:\
--179288795303756735253272048111864507295054051907270903858033299\
-1984105913251800521090082264035457471680922762784248326006303327\
-80357892372568802535086338017562314555143800752177152
-
--244934270799654899396979330417224591920216069659327770883960842\
-308099872348715409398096:24:\
--410931516700830297264139197394514709915731976734558842691872198\
-6944930107966825746000286580736
-
--2106457461641547906609473458:69:\
--1243433014305839647767580171740431469025056260096
-
-135142685675091:202:\
-8686636920585527698499063657324055240285043487766458873488405392\
-44004900864
-
--116790541221558472322206451254911347381714818839018118383610841\
-510309754344586351337420036400717803838650415501291198800754587:74:\
--220611094952357360270322465694065886169870282492555195903063877\
-7058528470895456709658637256734101042181231965942902938524566534\
-006236702950668894208
-
--113662437497188191611046105180147670725123405622356749057822533\
-9374200354866981925638532649150827622554422704805900523233811186\
-7804339566343416115467056:164:\
--265788541608259131511323286352380846617232004964000794820926894\
-1982659118064626109656559724002147778215968030048122363389101341\
-4916257633270717425007538758533769604203658211543099937688495500\
-8515178496
-
-3139835124875473212694109318074161136799592793072048253708819570\
-6031251397956934770541559259048189239569502903816890554914148616\
-8710074892985168204104697:95:\
-1243816837708147260845084661039007547826018395188591656306366764\
-7513402868999491043335036172230767347465042406686594960568733454\
-486595586019513727045751542829562936306306793756164096
-
-5599994070119518146348:199:\
-4499421759449900671784284327121118030698801585196299978528243915\
-527017858726887424
-
-10270683209834825258725306919273690176679518030925177258309490:43:\
-9034188491533697033850866046124648731048958323889347163636163337\
-5107153920
-
-4578000383070746273307:184:\
-1122522427702119950972128384343669227408405080033193267723578847\
-06832894656512
-
-4806080526717717017641435948049790217951184540837962383194474375\
-4177372178226:213:\
-6326741927653364567544399799665952033829979000600292660407440869\
-8862171634248299057579558184663298119372699195026451647955448240\
-7792959291392
-
--213240753886670778938493896779297584390212374893239014196784169\
-31016786722016582:85:\
--824935210136591658197356601203169660873055716952680926144487605\
-063939313393392322678258809253441593933824
-
--187286407031666462047035483383441327248520717346072223723620843\
-4454125887374738735368124928725176429609366:134:\
--407873676011864041904214443478531790285593140265704678916369737\
-8659007443902659865299628228125085923760625746613398039989747449\
-2137333668230201344
-
-8621689714197434562630867265841464865623072938828506100870809463\
-96744539349725331277869713700313427547966:97:\
-1366161267647991190642664883853673418069284183801958399635868396\
-0937205383180691314472971265906730508050012658612328503341173152\
-3633152
-
-16955933412697913917032678757506722466737685:229:\
-1462819393593898553961710324275156357656459346902684987437691843\
-5481519688706703310919911715271056730027164958720
-
-2180018258288311836232601230248111131649953969135839015779353659\
-8104321725586576274057148974991731503239472085567581116:165:\
-1019552081247881910408108587819850135603932052219933414781931958\
-7658929796456697439849089055853009742845594506749609005029155283\
-87206223717397886377023326519137153318912
-
-[RightShift]
-3163645694280286863843274284995813000413750703767888062060371447\
-2548769377833432476732199026703457620511:71:\
-1339856068247304299517035929669762064048406302964464795193542030\
-8616778680708128951
-
--14453551017278988424486997167045:183:0
-
--14453551017278988424486997167045:184:0
-
--14453551017278988424486997167045:250:0
-
--243110742861195501591733619507439366721710893401851315001032874\
-934976816617401149916967847829528780962:77:\
--160877194558516235935268045675608004834374082748681492335699377\
-1554731869523279
-
-1578511491667772739870432690812184603408439934845400990951391424\
-2042606791815444346835351458430330984370157647950174636188696067\
-901582998887813:172:\
-2636868630877883693962671763727310843333678410156464570287439347\
-867714845687034115945072876
-
--369990587551414900909444219626623817296602594145580698921004093\
-03886523992221862362854753622740275252526720452:175:\
--772576394901327014846975657022405166419128733678436351046
-
-664523869708591456637358847652496607157050130461836524747531314:\
-191:211729
-
--424946102426960838249158490450106473832054726611725352096551869\
-301633439915:132:-78050272313569003846694186065678698
-
--2477488754280410161548750939069:92:-500
-
-3885576822798328723491155206700259517121985332303318810671479550\
-5721679465077987975131032494226814645578292798864088316633495241\
-72281732561:116:\
-4677092971402698635823599561404354384957452158155534044221842927\
-8654700322373721814974862542990905781201
-
--7784136527805956:72:0
-
-173:199:0
-
-4615578569620677656625:149:0
-
-4905579994733063495470152932606524195238444602458194107223829134\
-6548096468622028014016518915362921381743841987304665341504653820\
-77:36:\
-7138558422932784735851095949483750439304923351240277562790767311\
-0236786987839191008266816665655527877597839669476765763
-
-6860659646513892651503913841872495917865372347379124495074404003\
-48669:86:\
-8867194763939375066201545129950170866662337
-
-4932993580763155556722299514:18:18817877123882887102975
-
--278747767898647506540238310041925406724691634519605101611983422\
-6204966588409142854005261436295569885823506142825506136904961441\
-137712103262466261:104:\
--137433260320539729826934608254525294966481185197904919592889909\
-661839883445042061361887992911622135941137977531125
-
-1882169262671501641122532021045100553271183358274828402533612516\
-4:215:0
-
--113308045504297792964762442633165425691924733661899127245385800\
-0508491250659909229734510933018929528943605300925959716095482095\
-0781551497986883190460:29:\
--211052681327420832523633619087125036291637893136402829075950756\
-7637583707757125105214325586369129883020381072398200102328289477\
-3001878518586
-
-57567025533800:64:0
-
--132072785244069918116388563501248470774742728409639846537789812\
-5119402223003876981196535555849118422274367340745545:47:\
--938433581467776307621794014588434654731534070106419040781914109\
-4019259860231421876594989980795833320
-
-332:218:0
-
--559822315679298304410139625796782279674102061246050482023351416\
-534297836795811816038579409314284017985789979551604:185:\
--11415659555585642743745444064957984965053472879394546525917
-
--165370654266946240954843198912509990578949570887804349975976624\
-7848:193:-131725325
-
--194216125550322203453264566553636693381698:190:0
-
--574918037852237888178117788291362893480850545560575590351360319\
-3555180688115045992424767676514653030256481410814556185745502407\
-367635738697301:25:\
--171338927105736103110944565621424583637967868316345092758941745\
-5659860577617599365837802790556744644122267189864682014508695127\
-77556053
-
-22512966965683176238772169284:210:0
-
--571304627859240495908938310435848221105034147099897333911621990\
-2429210200375110530363596454364595974303366523715867605148466947\
-82:64:\
--309704859338005592964733519326108195603366962254800737268694205\
-05469907491401631445860907279418326766038568169
-
--309596777436591740355404153813541201302898762127036944631572788\
-15893302883997570045883151320905855931366:104:\
--152642996313836176964502120620181580006920013080253805054740742\
-4297460034
-
-29089712758204609787443669188235835:57:201850430524318292
-
-3772893855139299527739062333307773429569483215869291954483303258\
-8826307095346005890226120725877767624562307811438348806708086825\
-272884:33:\
-4392226523649063342878434729422178852336345258948034553885580109\
-062873187398771509787314655943513804180816259635420144385202
-
--107286131603440054982169113843212878238243177589333571934531:\
-220:0
-
--171860798431436300064006491940938069877937918743982288348494291\
-9605122825021394820452085254301230580701:35:\
--500180753970740770641733228522754710510890927235544334248681238\
-27185564005671616773239955489
-
--736899297617589968040433744284158522983339306401749767611116884\
-1084063920382957413309258573768392475688901297388389668250828837:10:\
--719628220329677703164486078402498557600917291407958757432731332\
-1371156172248981848934822825945695777039942673230849285401200
-
-6494520002849829489554410861273180035603713191696971145227421658\
-53859125361930352324226:199:808309944002185489853551692
-
--8811428348398:35:-256
-
--472961757341800595001320983673882525933533190954393100297169797\
-9931906653571844489680727773893833490556432129528242730860714016\
-19:32:\
--110119990385556732071871166972881771142951490114068868639219970\
-906430544647663936244340794484453124239957708155928243204
-
--950911712685005613285113124954832473131420819362306322439787774\
-9569705:103:-937671343067445278042307956226145570513
-
--879814295274183624334539929331740552569451467718612745386330333\
-5306363907959342879342226672:194:\
--350406259275000216456910916623341
-
-5510885178270303556262037168746873477241029300667748255749519664\
-7790961278402228092443936180348351958592120159109985931085584854\
-072:127:\
-3239007197543508321556333059695431531874740086907067131644479312\
-48944861718637164159925014157
-
--532599980357955121299969897485530088860096014928320106613667412\
-7658734:197:-26515022518
-
--751201308625232459519354741343046361775777470541080710058601279\
-4485802280356383896946090:190:-4786930913611882742357623031549
-
-3399159309738603281217586458627167057868700201720622195013008494\
-5155275705802319966198750893042523074386045050458079803807735428\
-3187:206:\
-3305159424435509522890985455639702285024494664087298807252559331\
-827343
-
--163860953109333686549278104073264560158695392823410089526219985\
-3597217435977552163706193289327636667043413089396300868558342495\
-10158:28:\
--610429618914923394282453149830045402641204717842527067386433427\
-630818425110560716579181436198814461768944967313222910671808
-
-1169677491246850751212:155:0
-
-1636926214665128743997698266803409352776056144809201:28:\
-6098025346789988666764267782879655632287473
-
-32036789:197:0
-
--179819529231495425818261190658137469439875298005446780128564386\
-431:217:0
-
--13881:96:0
-
--201081314010698664682270171218698566959371060867314287561113777\
-01129681335253:40:\
--182882389718268918552230544463508128464464844789576352524012488\
-18
-
-[Division]
-31082702275611665134711390509176302506278509424834232340028998555822\
-468563283335970816:\
-12141680576410806693246636917646993166515042744075872007823827560868\
-1517825325531136:256
-
-31082702275611665134711390509176302506278509424834232340028998555822\
-468563283335970816:\
-12947964052188086825220046400459488806478932301299660383343378609832\
-0524868413554688:240
-
-44966555772413807289969128318278041600000000000000000000000000000000\
-00000000000000000000000000000000000000000000000000000000000:\
-10000000000000000000000000000000000000000000000000000000000000000:\
-449665557724138072899691283182780416000000000000000000000000000
-
-21098512396730698729871269182769821769128761892761987:3:\
-7032837465576899576623756394256607256376253964253995
-
-105492561983653493649356345913849108845643809463809935:13:\
-8114812460281037973027411224142239141972600727985379
-
-60281463990659139228203626236485205054653605407891394:5:\
-12056292798131827845640725247297041010930721081578278
-
-105210958105812350283560987:65536:\
-1605391816800115208184
-
-29614251982539440611171209425825912338459:524288:\
-56484703030661469671575945712711167
-
-56978246562469415670177504927986945371616100345225344293332816228560\
-0752167:2147483648:\
-265325636428172773077047918587862259576172103850288988525666372052
-
-37676726270241192487393385601963645387543268661126:\
-3162948793160806:11911898906396771271361947212182077
-
-5381521826168870805682913114359466560841856996681731280221235281\
-1509347982906963231033117814383486428722076978472087592957820313\
-6046584241121779503933:\
-9668544070174123246320200737076440955801117408066349193856053605\
-114866903799592820480948520645947171624952907359157045540:\
-55660105462724064753070630466
-
-1723834528325652138144287068293892732593026664886852512770150633\
-2776744620689:880523393623328:\
-19577384778297865485961051332688212998820791370774585297291841
-
-1515496213019297763233177841945187397678421298227998213327928627\
-88716894139006899352549523462891658:\
-2837504714791238631293154232954335398939684196417059468771514311\
-350:53409469422883270966457345156344
-
-9404536008735908917791097512770771428224998938693723982728653696\
-7624988457783138098124870580583091:142622867370:\
-6593988875807797411127801190252266506668676674421094260691453448\
-48811732719710346250661
-
-1392866713189645633121390285073523887805815484659191269343858827\
-8526805205835017180928664701580352738609190657216273081064279937\
-78000446364:\
-3994371100075737516464195988347917583672726362309747721542773781\
-23623981222779902598092910701666748270156408025264:\
-3487073880449504057292395
-
-2676049916504901888523537181437273561212503:\
-9341913943837642277221766393692439892564:286
-
-2596351449981306834637204601381844425730435831169992187762230868\
-9984974618995828593891933726738665906555705360752479986:\
-1206034745333560481629722627489368003481730232554297338790:\
-21527998758138745589857127563572880142324265819094147184332850
-
-5972458816709701659388787816816316579897252032508674599704692592\
-7058649324526265892715874715058327035883363955854176049442032564\
-309441091155243908284:363119954882801248387416067701593:\
-1644761940620239975738766021378227306491031556802927687823754679\
-29691855045229469191916674982018556672788351294907277
-
-1179031947959075688529396972036519234258725785851394295456390535\
-71085372280587925290861953121759382460651235055866819:\
-6944577951175401788316018705171160466581578649464599557174064469\
-156454663085245879135170220436247473693597253951:\
-16977
-
-2026650664981190253207120825245989396597395032888279675327874031\
-6428571783495257002384926183573616802093352971457675644937672443\
-66086144671180173:\
-11631153560785819891286797700491247192758386954476186081000494851:\
-1742433073718499161789694097861808628892528194276009183278062135\
-44214369556426533
-
-2839636837334372650605745847855168203149142969651746071725807516\
-5633540988132586349575016474518431300299708784295829212402097919\
-78638935225269061241787155:\
-1906569338917937819117576221675263213381604280817243982366441014\
-3748504584308116848567559666016129206267348790454121809997280576\
-258634989:\
-148939604732445334
-
-6371345663036222144347827991463755679970672243967017350001151581\
-3149043621560543503748545334895102360498672050891243434943238417\
-147807583195634840:\
-2803012481163625225461909183974367795369310930636762769680881703\
-4432088350353366279882990440057382400481292913134:\
-2273035067040180000190499573423209
-
-3448761565369806483093631443732798385337886837688124530151199904\
-35214907404151562329499651293972622329230621111836:\
-1154398728297611607347339889796530761810873173035278653857672812\
-71070669711745252818396963830424218:\
-2987495984559585
-
-3939766758764969916635508714517181254109527059899723535687606136\
-704576526260284945948460575945132796870670558656976658696699246:\
-2039193601576864286342975169071164596968234:\
-1932021930491755924504494733348282114697992509296048596879364255\
-013992177897790479689
-
-2599570067192469214877296440421668709321992436666111483543544040\
-9558626508316404576861534763496892008536679796682457407142:\
-9865947223638288117488793858111648559036360190603549966937638974\
-384878768890886202494341034:\
-2634891519553273835810191600375
-
-9953582546881861626054758979348156073957328868768555275026281270\
-3558132981561279486898511993570779719758639416109225470113031476\
-11758278075817:\
-72753887765933437843645860013004267290394240181603205482549:\
-1368116928528260130222427481511416637491457702447115334585560552\
-89688431510521935105
-
-2777707354230450548824097922478859820718131575494711827631509815\
-849966141849784996342423141941423856370057172664302140424005921:\
-9887732931045287681192967993534615207992429003750153183843126191\
-7060602813748941:\
-28092459349393082079339190162534632411372212185
-
-135175390055754599158926343035891673287590:4587240067074273761847622538022:\
-29467694753
-
-1474508901852067097539817612956066371267340106475397703336120311\
-3477874932185558462473899178369214022436285310129280494436591650245178:\
-4880369721764333040209711516636996332699096293749849371410907103\
-371872025659064629729192743174282304112524555885248623478:\
-3021305732793
-
-2458344447588213641014490759478425477739674803315383837923650388\
-1993781110774393121943801110702528757067967698929051580978401073\
-21258908424060287326045:\
-4220549808710022650484813532790907621975000231990739804525754365\
-8980362:\
-5824701896693376525879103155093475976637389780048291339267026554\
-0931549290645770
-
-2235359829795993754168620762055024950392775900247276637443301544\
-6834872612125728471199341647165418100481804191461888838714869412\
-86190239242546459829:\
-1079446102417965701004684159063911518960227791488787275338443605\
-347380965151141469660172384738541132220010177148:\
-2070839687862853380670878474716925600
-
-2261859020237326202277047516915478440734386573562935959890434522\
-4642995494057840711903761496596915458217743732578579075270459080\
-0633340:14203382288913876345794743990430:\
-1592479153365299674692434597912939527498958604158881610792107099\
-0007263922267553892387895651241383531760
-
-1627272730547121895847771240538443456605751355188756262440532414\
-6146087377529161595400371637008556124469065:\
-4556444082143966348635739253264:\
-3571365523663868043578518888635769405026391569324510140958668270\
-949379670607
-
-7053322761929289086579214480771179517943045501137109771651701088\
-637150889882789201445500740549670389506:\
-5820761818383944703677222410067006495183070681923349620668953689\
-735114782073218950052335558230765131355225215024903803474:0
-
-72782874795717830428761392759834069051935680000647471818367555:\
-676006789231214575171585611498648177407768:\
-107665893235317651024
-
-2678488124982838045802785770118519145558475116428679203089749164\
-976612334859762291787998110260325948674165281:\
-7944336793457702698467826157627761976858612495202494286895968701\
-65:3371569200324712887203021916554964731360476
-
-[Modulo]
-9:7:2
-
-7:9:7
-
-36049713:3409630:1953413
-
--5:7:2
-
--14:7:0
-
-0:512568576:0
--0:512568576:0
-
--512568576:512568576:0
-
--10062526826820804:29:0
-
--5:199461981:199461976
-
--8:7:6
--7:7:0
--6:7:1
--5:7:2
--4:7:3
--3:7:4
--2:7:5
--1:7:6
-0:7:0
-
-8254156815303331281824478486972822803470138521315156647307553049\
-3310587284245750487869183215107304761500042605982935676360476706\
-01141527698603403:\
-3106222408827874796097424168822651228359402578430811:\
-595826521675090943156444889338281014934863303289705
-
-136863920521571139850391995526246731:\
-271472461994419020251392394864015015809448271748774:\
-136863920521571139850391995526246731
-
-1828810863480002099820314884714568551379787631093473955109129851\
-510111922379100046301719263372:567966528088927995495333:\
-385016512426968327768361
-
-861:7863900424362475800352483828371:861
-
-31298056599359036104:\
-6834101648969675037772759079916190769657938079502342632053787936\
-8365474573457851465113672049521142215618176993202488827600681:\
-31298056599359036104
-
-301132649529789235293089719211083808148317022029687377:\
-8985923799959631221206612:\
-174445061721403490019281
-
-2281346996471575399039236209159382841371310520671504115347726755\
-6405318252398792419321309385257790020895332595371743866761791127\
-088953387770:\
-9148250100428904287337426958133211831148659494946573378694903126\
-9368755379167072338:\
-5712279541400722125363135520469561121058328307700157395773665287\
-3288007253222581108
-
-18204134548129881201198951067056774604374867858971160:\
-2073934172352760752130567032660041512076751995427049488228564629\
-5445506418304709424209443465714405592187482184410284216568297836\
-202471453:\
-18204134548129881201198951067056774604374867858971160
-
-1965719248782007406536742098914361273948365800827075363669455004\
-986089949754002988457038216772776062129273:55:8
-
-242013738395129963274394550113335771936345:\
-5855690525992972254238170169720083764160159959672754491605994128\
-073126517:242013738395129963274394550113335771936345
-
-25207834098049778316063817949139583672551899941064748428641:\
-2394034335403109766635463364608199166358381072109847929528549615\
-46998:25207834098049778316063817949139583672551899941064748428641
-
-2806019740162818318268355414902530432876592478224294545991479160\
-4283116668034698476687974823971:\
-1582972323756438784786521922113831032463998151772165:\
-1502639578247286068956607674581436779911413521925746
-
-7646186835577905185055298334837136208896759894169440852778842148\
-501161592245256816858212924947738806827200173857627:\
-52896776132731697503809705:\
-24742696196904988498029477
-
-173957948128989810779090250062796172580059019371598891820856745013:\
-1799947313993959943024637237734385080822192208938376976998702929\
-3875551371653028911096579734599831769935491738680281300932262194\
-4984764:\
-173957948128989810779090250062796172580059019371598891820856745013
-
-1013844499640750066199242350792839164:\
-19498430190523094593606790431509419:\
-19424559924072241925296038785858795
-
-8622490124309718848844541942762:\
-2809153572052317438723547427922294488297174937286864313874241961\
-8679887592231751654390695362494978870866660168195696176431350266\
-533:\
-8622490124309718848844541942762
-
-1072609375974667769429773421465107051839877399085576311546582931\
-2311070154546061306145007166868107111741792231898435921633768385:\
-1463259917133913245195500729566820615925140728085869641490936807\
-875627045359340:\
-1136336627131206018599354228978585378999102832169870507738700505\
-866665661308205
-
-434178716356826614868022910336:\
-6634862369769044245968610325063754582:\
-434178716356826614868022910336
-
-1415406337306642091120413528271804224015406023026499:\
-7034899662310880590118948531539534220057245091097123989790225455\
-718320598907482500:\
-1415406337306642091120413528271804224015406023026499
-
-2119242142523650184634691519911880425707508853468661410230000555\
-581608937:\
-2008383355777044545530942339055540267683709901883165870378113231\
-22625039264578687:\
-2119242142523650184634691519911880425707508853468661410230000555\
-581608937
-
-69585923602069681658329224976930117468163915197373271065425178:\
-2020927964630024370658097798162044021281840678272412358937742685\
-874564410640015186840535854739937:\
-69585923602069681658329224976930117468163915197373271065425178
-
-96975588332536394385315130323058:\
-1315802351305852717882890944093568207768868622073415386004618717\
-2175427025633631880306918912341930581398571945990395254404556930\
-1546423248306886079218006:\
-96975588332536394385315130323058
-
-1005028458858291820643604063469013555486792420347821851888080697\
-7432670023176937393067923:\
-9828498588177084544380049:\
-2075442833247971646995411
-
-1189727226195844529530585:\
-6538657640728177165013773329092206385482700449306247249506942167\
-8887069241318642226489470387127398972818622366:\
-1189727226195844529530585
-
-9913890361391387217552509180:38186248654:26592864996
-
-7734726198125785627433577053431512633637067455428717621996818752\
-2575060294193475687274421372950273116057529131026941243649403546\
-7830323368528007:\
-5416039783030069273660577195279406145075794925910316773014188695\
-424126525007469657167631593847463121496915435500645:\
-4964806369541933457271704487044498217022879054817785578812091084\
-454769612571500637156272668116039380758996484864172
-
-71080186231578425712419354407360937437540:\
-1176980859009014803857106593068944458701173958687578469120934483\
-659139465526500936333672752:\
-71080186231578425712419354407360937437540
-
-6766067674766915237012186799976734148500111990982325235714483836\
-083584935230592805199170249391665243373021274113:\
-324423691845570163374834:\
-252059054229526041391927
-
-2823188323141882531578618333354253113311374951152404070296742852\
-061375867436124935489341:\
-1728156565766891281495579170663414558716728498925558384066168759\
-527625796619507427264134231896939288551956874380:\
-2823188323141882531578618333354253113311374951152404070296742852\
-061375867436124935489341
-
-262779290090979866282191640705312933450751046001:\
-1089280788909080319090197382760567576418992525818853374350259176\
-94325561016010292207663524094967470016917014:\
-262779290090979866282191640705312933450751046001
-
-8360271732029582503734310894572886727078012043023629221111060787\
-7138104216267918615216895281636771:555311145:120907711
-
-2366610337862898747408792992366342895990689944827378360469117410:\
-76427322404335731456359122655716444433:\
-30544640615708299605352469363039636872
-
-97771381685586783382636393:2:1
-
-435337671693078154773623349696989:834970971193485102214182395:\
-506732218892181192932591889
-
-2322513198662380013738103320830701289301787295559139301156091472\
-554729188662496855277024270062871128249398241623259939409120778:\
-2:0
-
-4680113793844806249835648380663376025372596959777178380:\
-2904997032241569138092132512949608009650334804336242983698449850\
-529852963482246181:\
-4680113793844806249835648380663376025372596959777178380
-
-2117036483187135:\
-2956811587252136030883436487547510285350147695210005035315279431\
-098717006229487861087796324851514192381549211074032:\
-2117036483187135
-
-5405482742629299751643548818366182062777872542836164736969326959\
-5853544020603118041671461286137567987302593373027659716:\
-4573526887169513117846642791864935937856091980821696964895032993\
-8:16470976317121249525195764490105435306011497015289420117425749982
-
-4359239142132654586747373757743417755349625230737312986309991827\
-8424863374421135266551983:64803544028311:37353941578659
-
-6890135792819098747339200650197811212669835729907537732727533511\
-643927448939258863466836536126445044614:1696179960288:\
-1324995865638
-
-4586314642595210536059912268094819407838151440257177384187072112:\
-2948676315159331003320418147316303300898329201084534802048646109\
-2015178004559585679:\
-4586314642595210536059912268094819407838151440257177384187072112\
-
-1295408061166295007189929428327291997766033572889635238933149973:\
-1972670797419796219560042479665734511348274052918937432115112357\
-6010380851770692946791:\
-1295408061166295007189929428327291997766033572889635238933149973\
-
-3293867584681053035957322938418784576730188582989206165304195433\
-9408357109851822801814954109216343414383237957096721562712712888\
-0653015247183660828064748:\
-8765772621072630220689785618513364012217258182568420497034708789\
-586373847828131714253297705781538931737255620107899492006608937806:\
-8601837373552535609108321170415754873427613358207755850219844413\
-541399748799344512722771514163410191291986915042108883348141430988
-
-1377746154164779665651413126473853834067870962817490604919589355\
-6407321117598745222627688834382600647541603271142562521784054:6:2
-
-1667979945553031384209256450228364963479415272610809793730506411\
-9303788198076909155676052962187532066482528524026964557345352216\
-5283446668047080:\
-1259826323514238805985170200301657600905328450695745758777562588\
-7186049156983679189477135784008594900590887239:\
-8186664560221138319073860758641161066866118482696737858152118048\
-749012625273296415253954330502016523386663032
-
-1604558310259870720456999045309843418780215517:\
-2314764593137129686707089727262818413583267016192300531282204770\
-7680963809189153750977995631646696992678572235424774049002424266\
-88494047914464727456:\
-1604558310259870720456999045309843418780215517
-
-1409736422781005655489884086727910650059319122250699179352885575\
-1322893090584507459430329601684018675016713:\
-3037097985924054837918:2373301421797167262781
-
-6701198625704:\
-3208271584698650102424018685293737567361186784549354155908725982\
-8050085877527140878207342707:6701198625704
-
-6570726263552141736792215188836614380398234183174708281848591553\
-9115168019938378584836876558466414158281554497244823448201181:\
-1502182222571155013035645850314652637622098563760970718145694442\
-1198813038883709721878584487611894267955370991921368152768464674\
-7953186479:\
-6570726263552141736792215188836614380398234183174708281848591553\
-9115168019938378584836876558466414158281554497244823448201181
-
-334479763778167:\
-2620180822092752558176129834916304534899606970427451061631144668\
-8169619730877675269585659135601795114355310342255614595194757773\
-7880241235214292696563:334479763778167
-
-# Some that exposed old bugs
--19182011317708747655415793663840398231387658659684921854518950675010744\
-798088074160106794721561977563494710663654383617982647307741145787165689\
-415568325855995687160688325738126476982782410876428471011884289880631644\
-788665773228578260075978399410972382915954067959276715042755056729572829\
-093851913104244223672:\
-110589902576771067285674161059371867150853087104563757926013065022800986\
-359888876672387170062905874195180770816843413908369113777424570833424320\
-42777093021:\
-109391537162363400163656468557497811793910234020743027803411478222848317\
-478652922638466903221971706458039541796317994671218746507915453121571156\
-99186806428
-
--12729002947374921813333325067985579104471306056810166870370214872461518\
-835258302087462325432188644174454003894356884235513517741560628902891180\
-85736535643:\
-857393771208094202104259627990318636601332086981:\
-347124740076798815206019311966363093945724145995
-
--33561455954313714494272438259200225781962996013006223887793125858291980\
-416548560804296564715491363651855619074936805970007723556609659667595500\
-71261003601:\
-857393771208094202104259627990318636601332086981:\
-69829137374876952908916033728673445025
-
-[ModExp]
-# Sanity tests
-
-# 1:0:1:0 ???
-
-1:0:2:1
-
-2:103:150:8
-
-3923:380:4033:1
-
-6208938:141338444:179403587:74845992
-
-# Random small test cases
-35541290007:27861071413:54405498455:18392163817
-
-33810311815:21623687837:67955609697:6168450286
-
-390846234986723490867:258069:77811797476286981199753:388669864014945308514
-
-# g=2 is a special case in pow_mod.cpp; make sure it's well tested
-2:1024:159387639486734986734896734289672398467:\
-101251470522689220420018278313264853126
-
-2:4096:4634968374896:302457470528
-
-2:8190:46349683748963469823749683276389476398467349287:\
-22477714489988909289079275821119423277588139290
-
-2:65537:4634968374896346982374968327638947639846734928734603867934764974\
-978569847636666666666663948673967394673496739673496739486739467:\
-39545100683930137608837226660935619825254176150139370772680647311426\
-83367133155871655171332348089412143539565993577352969480643
-
-# A very big test case. bitsizes: (2624^2395)%2565
-79929780860261081309977632552711610540802328270286009268787208946266\
-52959801126270181797858326539991808408501955736107211154089990880864\
-13303849208224219100591662616178697815457369194539353353497852835501\
-41050889822915371610531527622477756791100346237932148802218221147910\
-83764160121545158487346802968250797762918640822953726116267698324397\
-97218709812746716531207101626249641544666652454598936868588048379676\
-16272912941048200311549530333983535276332190445765429717475889329196\
-82723327383286444096495073061099816572815545646462399372759381873394\
-86919484956198277784202729520512749754342112052047850740549446316888\
-78036856294503455545058266059097463500482961705306677988487417742491\
-15342399979893391684184998084322821589461452070845054017545885544579\
-571298686351226398527864005606439403913215:\
-57905475544917604320471424647112496473975795682168523689996102576776\
-26237088778306631051069455546703439634818835586436374397201459270953\
-73320224593906109498830519623033054321336538157343986271182875008898\
-46400895285646814945099135578078712638653971354390893897513549226862\
-42288943235147182911794944000641930092937330351756206882625430975695\
-44517498509112574132890275024912111320852904074917394291149467803521\
-35858911321807178002982306495559510988786798025982798386952917933172\
-94803214105228859170942097230151211488601051217081893388443911838163\
-36005486029723368697022501011466335322002083542926898677979222112122\
-26602746563675308094794277325137581108077975533806822750634437146271\
-95586058676179645844985231821190979452929:\
-10399205046598242703229657351883132701652276964362108506952937688714\
-32748288996020332036899375414937330955428206666889017559888570519250\
-50646752050470991826964779958550793771265289251619085920928563751890\
-69887180372385733236214632572059802975058104127044922162389962101924\
-84687865663461891419811205882677932740064370564080283318891658075996\
-58544432626283448453420230409266259464245167575870377225089095472270\
-35936225873319683727097162939426767650247431692626091054378261933883\
-04444592844359283277150336016415487591544524543727803303478523219741\
-67585351918391390323730198435093034895278122139553159165456287861721\
-05733915744785361299323192153909893286267220726431407206795271107384\
-11115626646378829487932946663804144605711055044827184543371896600950\
-5066861013496859002404865:\
-76383126271403199465553629505580460064061138700480822311446783865005\
-94033351331759734478813350785616549057262115034183484701333480536277\
-68750392900860337148760236002293999903452043982157916536463831543329\
-81510716218290076553514718078562286562453573978032941974718159086704\
-26254141182888039292181731039710070744775875012183282365743418038436\
-68118132938651461047089720835645326444415743163725663534054526664632\
-63369477979502118345322416804826584935088694928774075019074758940531\
-93696779256795084313220287359244619510038817488191412143951928835003\
-09516216069636385063459729195557820282023577637677540172121768705892\
-64355863735811421469235193223472628311338081133201771681274202506343\
-43861119601917402017293095701055272115112783553081034528116130152891\
-276971073856411987253305
-
-958568327191:\
-10820434407851188405104973511902906513518224342681350271810370438073617412:\
-385412694768521967592874726457715560537359750887572236310781387057217187291:\
-124514485573662879135724475226939854111051534076732305767767212261825204773
-
-993:\
-158082274092371197688912481356696199899964270448955828125938845871237934609:\
-195335598174576479907825469879133749630277214529613044392254617116806465841:\
-76319125426811367239700120840606231265432388418754186363393007030575232763
-
-5837:5387594231:\
-52910803894426776035608204231136092295842162542576147924991587830017346711785:\
-41256038256951041015975957103736087906734912779021641091323861709915393683478
-
-11820:\
-349248154095284306437849303504509069624812572044321414531019412890823663:\
-11695070112125499434524238623571455233638695379976237857792518028967433696813:\
-4877591936163920485322716677654737966141266950607206024720481980778956876733
-
-1279509:\
-228828116455132585158359573618073983726467809680019810077325482377363026:\
-596955405275729008892203759914236488647769846458724773926971979942130809:\
-548455744959985761919173432531376978888129348803576565818991241228678799
-
-1169325226204036541181168587818457846915410492286163370049583817559172758:583:\
-1347789004686354026667591408699204029024258192368477695588810277715014901:\
-986753196897611638420753041983500285520492197918271348656818055904410861
-
-39684855714221597676995827906679339738237777820353232844682939092337386955:\
-79808721821529030962053171978817611068275131312667370272216709366985607610:\
-168218000729293476661981768796405354274622797227127241788417326533874081227:\
-10243904434954110191313565832244070050272803217812912164431747671168317597
-
-473396006114590115230521230276516897096:\
-387145532418575837430469368595868663742:\
-554862946848974049157489689418354631387:\
-448855900130388136390865414336576134923
-
-383239913102526615892890047333017777270:\
-5212692713946112175761972297467118924556477:\
-9600330398725582192064124044651400063154809:\
-553434761331054066751131351244038395387413
-
-17023533902565202029648472226171284665775885307:\
-172062909283726569049023770937247425801:\
-2803129820108668499802071463467295777012106623420016438138627500\
-520764503324471534463345465793841061510744977815:\
-1087221030676278725112163308497001956646825599606083907052530601\
-511129847691028000053571012933461738616679305207
-
-6861608600119069162748766903320668621565184418412102985517914652\
-495806067714718757017641467375130420763543:\
-6090170638405015131997058617056249184350028938641981546887188901\
-427704577888167364319592127129279546370159:\
-9244137284483765901488318500741614548852246750950515340492572279\
-249663219793564958021372197661101436416951:\
-4357639256086891490742558173162011739263189633058589469209912059\
-837628983627026566654010174880786564650028
-
-1708391349301269900029298214389921761264445766152620652843393219\
-358035361114524948237829535432550149898389816132:\
-2879295558693495162441272767383253789140301947026867788739382060\
-6202058461437115060253107180150356177029255392:\
-4562451461011443048616592993727831094905333529601929282014937177\
-804484518010765376407040702135536959480150175881:\
-4780971485381051463987885157471185516431563444901967941411376359\
-86642717690683975282976174121121834972342669810
-
-10517206412589906914919094336031596865011:\
-76918459253520716071622848977323758816926:\
-1505994032870020776188597437379504956214103601873594169817828353\
-64671206273170823011738702809865490437980268482169:\
-6782959072847327960243512935142614796318322133888530532951869324\
-5770409979689571346380672589348570036123781607470
-
-11150372599265311570767859136324180752990207:\
-242724485078592151169084549880604092836:\
-5335081937310201228237642071226891497098426337909703107583644285\
-670654712470768061820964879543360755501155583507:\
-5289945663803755598608137950548888139591380435852466790487033227\
-703935262787324650046364967638572584406632742426
-
-931466513478626427306310727788682496419061:\
-217994111091681034507066335081667319859874:\
-961964829688733829104056632507823404588589:\
-833173750092106303567501575871102318441517
-
-33561455954313714494272438259200225781962996013006223887793125858291\
-98041654856080429656471549136365185561907493680597000772355660965966\
-759550071261003601:2:857393771208094202104259627990318636601332086981:\
-466300477512220407817532870461493708182430162598
-
-18446735277616529408:13826086040399511551:18446744073709551615:\
-9742888130495268572
-
-2066035337354981392130:590294614090054615042:2361183241434822623230:\
-1781635733335354182170
-
-1134474769362516449295:595082722712944107321358:604472133179317082392560:\
-174433592678807302234305
-
-229695905726779543194697727:2066107393815150067712:309482943713951236396941311:\
-255445792852673371383518814
-
-39459263341931705341281566841:39614081257132168796776169468:\
-39768823762042823743243288575:\
-18000321392386817821819747971
-
-20272506158886027804894759485695:549617402368:20282409301420215520289961803775:\
-16076875793871874811256029767300
-
-2596146262862918777502064164487167:314746245562020587327614615663:\
-2596150595671908851028294725779457:\
-259452957580212247164799070673210
-
-1329207713384983037494489787788165119:664613997894875751198207591023902719:\
-1329227995784911150537324190635131135:\
-74931525087637573584762278346674289
-
-10548151117631103898774914151334543392:172799619169629461006416114606604025663:\
-329651139063474322636826247400920186848:\
-254360437154022212841099277211168659936
-
-38376141213232727558396575742:1329227994546975833620537847773658111:\
-43556142965881361263351233020478837751809:\
-7882266656394285243334252622522460065897
-
-21778071399863316876858889960666322788417536:\
-11498820413764356772438481831653151028019199:\
-22289866796490810914148393466930264140677119:\
-14729964266243087437392288444808082264778101
-
-5708990752213998704593329684646961688917049344:\
-2854843834553050659596636958153505154652962815:\
-5708990770823839524233143877797963503100755967:\
-1213314932578782698488057585907187321685706398
-
-730750818665451461617337784521558059081734815871:\
-1393626454453328567841481426032383385141247:\
-1461500243534328050602081880071791826653075734528:\
-36589747654349317493366392017756653058854469503
-
-89070866165185702046997354469363290973544511:\
-186346454039417235798572176863886743203694761680896:\
-187072209709109072999178427506126808160274875473920:\
-100249235510137322305244318500270410808414700625921
-
-47902131996019100606144108094978428095571288664305663:\
-2993086845361695763824823322725006109313429902753791:\
-92787815950867086729849642517788817830178254376402944:\
-18181546031587637786495774142309067527845892702867455
-
-1529548788145367384096184954269576428877915687091175424:\
-12056429762861608322742191731114663972215007089166057476:\
-12259964326971363908120110422500131917968192676667850751:\
-8902920084964970240236816532130853187870192709742265794
-
-2353913150770008068587063363810241845308506574699704057857:\
-3138646625189363653324706809064694288267491751083345182720:\
-3923188584616672689804218573216512748240601760727849500671:\
-3489390974396854920866482981414347185686425117732037645069
-
-1606936511763450480099762299205357820433296497388387557425152:\
-803469034102116550437458728792540626818835681925841329078271:\
-1606938044241269568189324896739694197295702418787910950060063:\
-1157562321286461926797535419478313302393081562742400458360699
-
-3213876088517798030634845491953821235713023677006992616701712:\
-3213876088143653611478475940912961815791384862556012511477519:\
-408162263241783712508107448828540402939725762911344125829726448:\
-122281118805505175989390918459315270668105883553864623340908704
-
-78984217182142549712873118981592233473006640114480894037226160383:\
-5760069223485436434928560149104616326928233898135325375027216383:\
-99552222248912332632914142959201125252095559737149959554534998016:\
-41247250798037922665809643987819996157888990901800784592830922495
-
-13479973333575319944101559938098667180961928064580133721038942904319:\
-26855457127760743210990263746907866885563833723466429463362889842687:\
-26959946667150448233089737658744041109190824095473979716229010554880:\
-4607597240742150841264334986939105818611232634350128984634238689279
-
-842136766011397578903644245915826593531412765435262158042277347271:\
-3450872811831279520154373881535777460856934989266388205922935224893384:\
-3450873534956341851896676659253889011575130554466345406250460450390072:\
-2941993960288658419186702570424905470425182342242431371338739031000289
-
-53919893334301279589333317246750913454504659246313017577474407530458:\
-6739986265053150380496772320847073259208890036638151707361168850938:\
-883423532389192164791648750371459428054925408907041210171646064226992134:\
-492758336596318698040859328657127140375877986248595653070848941543658036
-
-226156424291639621926579153190770264338318253140113139871821757473724825599:\
-451871190736965126593740420689183849474145722254500160020199016340436025343:\
-452311985864973039565107702017281000194494432609785209457352422582971760895:\
-206371772933061478243841113960423056774774576761651915339101577209555247264
-
-57790033794784404221549557662327731861420013371578836160427241519176533147775:\
-57924314171510248922886625261187774449046378992897298085839547689432814450688:\
-57952583724717841973873591369185127195523836514687066867214702092941619363713:\
-30824716483241910380864974328660094362176025123941170601847876346075141284097
-
-28918869551816354203281711613902894032425850711410612119692317832977962516479:\
-495866234740560806246119743419725810834297242466511080670627014383220945892559\
-936815103:\
-497323236380839503266215595149699815784160894844461528162205565127963664108464\
-594206720:\
-440697051062127950986656813740859110279731333560329663474202710140688604235456\
-625459199
-
-106799351796045504119751438634759911751541780368079101054831703056799294300145\
-5704188564864630783:\
-333574826615404906327500304126207076918083731520030795572399809917427817128427\
-78688178916162627:\
-210262853477245653824628919785807520574112980102524347845695344069257084608033\
-9296565121614087164:\
-409104360798917417291813850051124595330806127838297995165812231135684569475004\
-40718722077162199
-
-458703222792498995654766639758361907295871229948786413097609299221006105306773\
-5952825387037031559982071808:\
-460489769191176719281070634883090802854130987372765146464988196226296563929972\
-3933955474653487352197939200:\
-515995193383849441469102286446062601363300939013770069105297836831971480370953\
-2563214502450470881158234143:\
-659547703225795194033022150219884091213642523951015644588235078686412285627182\
-367344348652198750000621152
-
-196986157679658721490891675487601662607621770968694415540998524890432131851581\
-87202692035255772512656817673891379295:\
-197010019239259460322391226657892364459377568182195309352825547309153108344776\
-47441883397217965297498845885498785856:\
-197010042724685309927891926533239752567678950315810596221680825514112627345231\
-73779532010259679430892768332152438720:\
-137179420846547234067406976601358197278397049730470539175774522873573992073467\
-76021746214098327997514887107653801985
-
-847391119992999934524199349353674514854291751712505505959030025038182456175487\
-06410023206098493171208237706404733847555014656:\
-846151640054596488392544893831962389136827375615193453811903893997804174756499\
-34005643884387451031908122452240583849211330561:\
-169230327991833950927130406588863731440469748857923375419335685667802027986222\
-849214463284936419152969154833126033227555799040:\
-349189575910521174427529872574358060849452576747366879257873145629782075381737\
-69987118124710215143697594673767867437417496576
-
-363773922679155849804490373799047887070255597319813798670099566572410188562476\
-715746569693396483842472337060904644018022256610862170112:\
-363420748144189849661484420028667943524591114407411070567578632096069165317013\
-971108438891512258542050800333653426247960655590970098159:\
-726838724295606729158859740316021156162084950884048622161133512067230696906825\
-631024756704356676668490311500502220280677989703309328383:\
-943346883921579117927789498021289612809505916892467617091559887193179680886674\
-93495500793271702231092935340075784743548103583099497435
-
-726817235936247126263260430648607055202648835404933070147906688351677352541780\
-455761429906966666196747516786299970565697677097477079549:\
-234093052017191430607182115877842057523848626380910523577170250602065847207693\
-0698964260600237574820110174647749068723384080950374168331821252671:\
-312174854958917499544535010352990586570582075637553335203799632779800065916509\
-9371268881853279967461640185705909541299326557227519445937390878719:\
-145302853941392118922007506272002487299963937517410130047273428475172876526225\
-9076047341515264479230430769734574243097862523252932932825253141972
-
-671045713952809806399123039169834190798019141974546892007029164991525078219923\
-4391125404959464804845345485366292987522589442110638524087511900414515085184:\
-100557536540004987041680069388793478160856178388285075606319017466522431611276\
-04372666143401938996140992602417239266174708861116004272166930318315730493567:\
-117322411125256880287070703661466827296660099717666151256364253067407537321774\
-81453043340262460407996361047696194779616193209570049612020833710249930129407:\
-427871649943734485110261187040991584740792885674754749209956288838484438455821\
-658897465708725039952417256302479230141386301923866335632805714670209321122
-
-278932655326622118269995036975129397274804915871779053661857452877736059384127\
-634121329158979878380308762008380717864597603986741316529923042329337194056562\
-72797696:\
-899755306212610356318503741485448444043870343919397771111093956461318054874347\
-506925592118887949241136986225190699279973940023756363811386274444692941093986\
-107360:\
-296928310374906891112672916920429076733917707224207361239234925375858327047910\
-642616560397719578137488697666937525679246721447350165597934983551162282236564\
-62909440:\
-242316297874126744650921408580636386530840551386127655793903111999255964792429\
-551816003299807569211621330176181568265209473311079342632474787953347234746268\
-71033856
-
-124148179473785515753483900976495375463175846772040915179960100489407818801140\
-386153814821042480678618640451489409676707915268113955322684015273909012967691\
-886782085152636896:\
-123665200736552267406507870543825531794177933977409374905646479219118774517257\
-973807622099440598320501885812096771745713204136436987907373703825843415541022\
-788434988839731455:\
-247209634675622497908595434127935436962923052863983571692177307172631537244843\
-661156548338303197203448146561634356005137545974130825860468804615247631357152\
-530153440215560192:\
-227151603159069673471024527362679445256445037105065544871000576317073123237364\
-604084797373417939957837288408603530805839725771160247976092169911184119068741\
-367018032387764224
-
-531137992816768042180194410275235231014748428305205626888268705039038344990275\
-830354075384778147544927229252517401075105596362556330873429304224033539575611\
-976005566560186153909092351:\
-265050813464019341782591409356985550250304855319320882107429943555822097503499\
-272972083491060855355721323865630537832749289776999351278833126739897988795898\
-656735540681074755105718273:\
-796706989225150648264712637003912871913902616519319137302870669417841387363802\
-156172552248205066036254625379206874854815904799303523142561330397016416523846\
-066183201328508392557248512:\
-698545628118937771982906207048042815086452530692273826870263365420275823865920\
-331297175545784912827197669087547062385185417204395003585916875778749766427837\
-598020564942703746008219647
-
-228080258987601429783785474992174427586739769646031092021538411518877634348882\
-491496233308857187086201212813372631859510335831683775179841580083317899826613\
-3892944092033301325993915393173880831:\
-228115067660377094123994450837180666891393694772161695038634114516039674934627\
-382146111380516563790088849487371430448828251375203215238931943113494928476625\
-8187954558355770339844535454225399808:\
-228122032369942979810406767036506165373627878538481579651232185585577263193263\
-452701501572769356495314392670830974581266353880536039591679031450102201017921\
-9198761933328112699352214481187897344:\
-188118364158408827608598374748027473663722746113246066857055629489795083275585\
-483993987700818043460189047823239966027642347200047389646072848784274786337145\
-5943463799612120436208296575300009985
-
-979780399682822443491892785902170763924781879549280551093039986318977412490374\
-820572934041688531845643651915891882538449654309523548461769956416513227908522\
-8686075817644680503147936264020312601634275264:\
-101039468281951584297686560036548091942411012440854522378852376905153792578820\
-526491315518099612383332261126602577172926074632204522288033372572884662174362\
-14873298305753687007109527313352488169563357439:\
-146967246829990890290903656685270947056224130697706076691594301841005877354951\
-511693670490721223810533170764128995482312897933437990829587501929497133433414\
-75336493704107769928389675253505708564947140607:\
-684959371832526206686430947871316889249296213907562741655046402973404058469411\
-574434903666572653568622512046494498859833252797479733824280863933973535971999\
-0333020252722024471681015912945572412442218911
-
-841621744223245671643866579279256346136911547623359222174810514260914383937727\
-121410429326128729874900989894412586007929203561994663607708217810942721737146\
-26491757503017538570326008943386405354500810178050384127:\
-835046574370828214420674838257200536466910917751875501945774587594889789444136\
-302225444888660356416762449041493258337910008309807587888683709891384336253332\
-74759863160712788474606079777577457730028128186830688255:\
-841621744247739667719774695523853907093039222141056136701719295939675155834223\
-141149684242371435095129786018115963068262783083124493806231628599234421585579\
-21928826576429176563276365342658873320656199051680677887:\
-171641776792948162459046075712632105706046103351331224035634488479044326436946\
-267071750589184208741478002039826913665286507072870450357369747959973069038363\
-62541506807137632260196273977092987625405622494200180028
-
-180736893273821241047722370828860910023880760767859964994951679501353749162120\
-203605437832944252005123541868958097681238184666838092849379709844193917151709\
-558226899081130864324270890306027182396849038235584045960808890367:\
-180692768076756988816453192173982571011886137644954034353729273534664667577005\
-041823639264451840815026890293403282937017290451562783468047486914361168600151\
-040243775282134184694362345916240250193020190224655532768042676718:\
-180736893440830578495937520520856965281294962427974927513923803474809907398510\
-127101312840561052766886364534727455968288789428988795776836882103119479700564\
-862711615006875176289790580203416819902296133104410194257483137024:\
-856661788868556497555753171743185880393161183385341462428419381946877665836578\
-199962988646553041182078781233731204095471916278402165655223689323271298503796\
-1339922330665845993661725775666216703697614062773907041502101505
-
-776259092418999167049925214245436177424109960493498436136184095312197123376004\
-795375790473411612805585664979784011579876806454284352298115639603045683926030\
-903537688279162857882362427734768117441963255335355552816137136539678277632:\
-121288509543593157536898204330924655486052832909284930071758744941757945950880\
-258976854032621353240397386639778021043144249994876134221303021551238324071188\
-08492774035671616221114539578037521235144220388652802165110797155359064064:\
-776259219657772090649453843996866394475774596684687648535057403628332034108355\
-611066607174117655553905872561239570539253021857268837013419025583386516716964\
-587659533104995052034936360834479172532993217817302565615052417455676653568:\
-305302188836470524166781962849130967460893135312268963974479972180308406911754\
-538859753173126409205288056538854045449259583208628406288959956034674530999435\
-037939418456132677351720402924266526747303451369055972673944439836595585024
-
-333400721643993898180167291500008858549337724902988425809863309629155281476569\
-602103172644528608068413148108449964895664127197189925898208663108138686848445\
-992492080997292009093986461606065890805476262463992002450774394420744247201036\
-9728527:\
-333380371857846072967701609460817537597789582723282597824650597501849679335199\
-343165565712820123477694623247671362715837945406204088089169100429147171465816\
-269689920112476023715179203714249590278743366983751924906793203159773370967365\
-4124545:\
-333400722264999950588128784924189501288148781675075833874370073621442316760550\
-969457847490067371539360403905027952438931451912805916056294160663364958654230\
-194140933939406783324948407102983872817828497801037425452968782973312618394797\
-7359359:\
-191012848913510661841936492643766538604255959987945238353884924715878564806758\
-593327616012865164078752970576943597333733988424992188290404523077022324817809\
-189178118148526234993783404998498531034729518740537930828760779143026209264808\
-6551290
-
-269608431386678117330124798600322019513330037348510807763587572608984684820485\
-099507560920847896423415812921260088023923470440766548954896480563235486778166\
-893803674160051142780406433220103092708748615194963012338074677237186965242392\
-13837015188504575:\
-409699419814540648825903090993494587168941422131012027314724435806756415002725\
-730002734134641050555130553488952425241201226890060478767921277139881665021963\
-531696929957863896374687190132914171366526591020508308973068460775468838191084\
-26647076865:\
-286388629485329797488072582585056868548431161022570422255787002697298702709256\
-813771944129479856409438303437569682751301894627153626144370650986351427299852\
-075166843646142669895524464872603999221366997488770858351184230163999499423337\
-48667743685574655:\
-731316547320299473009802948839718933699371968857389661733759578532296057021760\
-846862432297683243528454189495999299873352828281770164022772481254538444068775\
-853418331116795185936220024821351607176607452472034832022557886060922843642335\
-6447770719100090
-
-765579029331933520349539144930367940127041808604705953021365376767787488271445\
-567069445955211807579555895347116551864815362902663676261831877992582684811375\
-405761076827352616764484775509105057267897732024773034428016364008259105572667\
-3957089914455994872627199:\
-723633710948987223659268564308007616554309560380963432126033511509908717585273\
-546626366634744211578042747465871860594199818505802949748443789251683879775797\
-686215215798462109203266446923665330390385070823075823795278323802663655165931\
-8933324089676017271046143:\
-115345488557755414330776361322113119157258926529173637847203665301440120885478\
-677335178740503010376386315421509236239988383771391812122852150074951469818852\
-727753749904943486716982108725368950052795547672135658466638620098498386809740\
-293849492614104744086994944:\
-728560892737633947421554702112353738450141789163871676818635153973748693669573\
-448479281687250797619040755589520842213503985213836318323035348343126193465939\
-757353692921056693815541766204961643128445990868294388682016195348690362004520\
-09601759079872048794697727
-
-264147265571676471792517898976003535998795143544348208307292049823228793860705\
-374559427272086581905030550570828405770064408977632805085552985146525677734256\
-322488754736438903318375960318613966766018117061799930785997358349430586513103\
-312038916962237091109489547264655360:\
-799670723747643562513858745954268822441899872123093356057006480952384548460543\
-631942199298579918456981801660713366162422040853699573046905509957873091593368\
-133494238336537470666970520103625275991862213504434346604932739824466577304932\
-4028957831645086285006850763061217:\
-264147266550926731590824490543947454035145979096502036438175149762592264948052\
-542099236682903142675633548390667785906943794578748446518858770545408274764751\
-076017093740752673070513703608300017969039297842666469024930681887370863818660\
-285848994819152936053058696319535103:\
-163960117509537169885185765544751448072103166533274802711689286450570501314450\
-181013914551560146294140894410969131721369255390050395079891621116407024156723\
-924187766467630524002804723042815349651807589429463613653227100116585010070145\
-598003641941695701361320654300586127
-
-113449521136226407080100547456916576118865508424180848840856809509142657150436\
-480660810667328992315026289222556121139623497885164415957298020481635985305605\
-502860080953192373741846127188631866780846841609265891993111931115007469073288\
-2362222585405239700656024934387045151415468000:\
-113006355563382985070438933906844873784360292080648809339358581299294122162670\
-237023460411912253275887025991310920185401330365056885920514084695272763779288\
-227507093022125848698309873422797247070352573134267472557093609294915418676935\
-4491255378244606632152899102642090595430952929:\
-113451252251926523113481577009550261072578737383126609669712152864328986904013\
-726400467183882710411514321846188826070133509941606299192799418312429680388185\
-237849562812275619325288787338695413830801349366539767528834797069631336562598\
-0387841130399603245248753787383520821927477279:\
-372544003677066035405845677926063649933500301956988140070003461836409427635153\
-936260873454884884874872009940847169071403853728999948362041938364702514916481\
-082000540185716047517084923352347661475097928347881890126582391727367583267206\
-393623530525674298394598905509422410807081963
-
-966917874568594524311571965174706744093609326805553740939445155015236530109245\
-033989689780678579986507554665982300735351491240973975420693019886517912302912\
-511033560991971824155089718640294034542841356774685799518971685297763052248371\
-7469711426817903212413144671394300484252198769176084480:\
-609080295977572689832308095945886194467480543485618753872525971871550249966312\
-822006640286707535097678388269312872601063152144665166593919160661696670770012\
-743062660382423279958730175949013672525745171749316593443910862522017201177223\
-8908501840931275225406292153278460133489486073333547009:\
-974471934985310293566176538924921918514518021155658140874447834136755022981820\
-334829060040627153420323935144848734558814608844029992218681633839376775005733\
-708069440845733194737993558642051221056493406346308358956825022947724827679150\
-5223900426631914166797199334491131683601712803162881920:\
-394728031137500513977875623763694998080109424408953800199525424838888318255101\
-044822035070974224776033481256740912500655646727892323826641816942077847990555\
-737788184386590737196029377013569942187918921989370709925728581168049584948563\
-3240371548476102047466490293292879139579697199140874880
-
-209304571597029880536327127350730604301303890590129859247148403454779049227791\
-000787049827716519533789285419703922838938419119521748941457364776647918082787\
-941193483581643061458333557113287138430180563179177328854984566574876878384530\
-37794606238598511641155256579623743343806000539885327402944954368:\
-209279024841070810156553453175825960416360150761125175448249915520950235542877\
-360994750300136309149181066825151604457653711203734155990449940960513323208342\
-231157505645877711097261455287627206443335834682522962423900751115992671106504\
-92500016532899134210933050551596119461807513511116855553321598975:\
-418558049682135669341148657057337158039854551492960163951646072735018411026570\
-007054422575498875612770201867133759988392550729728519832552403006144140193552\
-153931499788766795891368901118721291220761847511166344568736230790146097003916\
-57957403476843827680630012670026245538630459324327636859848032254:\
-345846932903649047146070812047826896102950579824136404476234816108468580044146\
-291819070371280880374028615312562779390388495816606025083527127005543935189606\
-624949010774397812503965528275760287005029980654108356910082613864872208007537\
-2551777179070637720019619810793822820020917387755348545183160774
-
-205729651569860332744468761005074635557707378722726041251039513224449459951372\
-746874236333529540466692983362620887350196678766665942957179982515689132953436\
-974770132935136642921490017990191429501318761597984560961381403053751468025261\
-7330678898606464808467216356069779351714522738030869328034342063079423:\
-884802089814944721368167913913788796264207351028519141178657049255429962231811\
-213471239485727840742721413217191357189302492734371482547349372948881367352872\
-033225203960519276368969491322677803673533067904995208079702478431589129875151\
-78023540558315546409960618491305219699925055693238918058582909723202813440:\
-898846567431259343332002080072240911623905610443476436311397074791911428452729\
-756791719638955581851459832631885672066788520121311074527003147323940523864051\
-197838996667043729638804493655732588026711408558223326986240742586193054060673\
-73116180577087232182040703207053652838392918223507389069606867244494618624:\
-330976120980886415880341776439141766074475070923522670247407044470660056410339\
-319047989087036151909966462358797141078288707480465550150995645272681354267129\
-654494998835125535045689668286072397759521435877473290295637545181814670935040\
-96018320630022436269224758382752228054160058737590227855261477128282046465
-
-828634133235552891547949415996038020141374669297375123103501773454571754706122\
-914392204861156701708904011181338903063635143258893810617959224029486063329457\
-205028044206122996724902658213854905714837419353001726739501457021583785683060\
-022681268508478863876190541771622528094967653587662228717709292407057524105653\
-701288855605241:\
-889460011200789846558643724867431071648613289163004721800295399109718355338759\
-465396536214836616175019083618512400307417342019562430792158290417501953071388\
-907983538193217949876043007563884536448891075853968550749682439929375683628205\
-752681463645592019336782190426373657100855961915581360977984304404165600753123\
-703388161:\
-165807995089806536553080841379748499141419085711400164677283791796106513225069\
-933739851982831194393630836086467724121390864368721934138973430682848794624252\
-423075907830879747804132552275021019146514591380754570367019797503703664587896\
-993738784880257782274555044423738596580482485691527467335988696684937865639685\
-2589594599751679:\
-110635934182491981243859603763270543062085123156112531951423323825319710149786\
-262649487152256583001266676918239684245590236339101515601037814051209984411474\
-123159350277508478025415109219339194646933369161499227288905431119864676760349\
-219188381257693530391521680321264934362184406974021062841858562268094830995002\
-8192127665970318
-
-150541419965910120885326072252950313344189183651987156815556666099319358977548\
-757540464956785407394966156474690665433860757820788208660505875454348822149567\
-833646306056756976268576008371933441783323146899832241210042622842820170922170\
-013073943000246409301401210947583406842573892339213553363242404793894576585917\
-15281979394194504179502637960396672:\
-458811110836105842892163217003080194920756125830221894885553163087430983606024\
-717514426394269628398547471083288557731642073252835200932599858655380701054336\
-739388989064110577905946637280912237005530686120766138816543134470793817826293\
-866180382873417692611530245913473019173332765419201619992688495465334977679026\
-16567195598932572455812410567033855:\
-461181854392848886965768146957613797147072606861590104150394760476730071739175\
-596911091201493515279199847197192254824197669058225673072549923240766228757219\
-299581067077447976564125089047078909578922878743155083031982942509181177816886\
-002114132413025677713368160296348727689034692287158664841219202959513613314130\
-26230956943832864125398233169002623:\
-162590279346602887977164044364443036449074286310852753145380867975929623403717\
-268705937818130556165447153611768482840789969812718919936741633256475037595880\
-589124428114502700660340519613372248238515521135116004539137604390650325070039\
-612466795694588288270783032230885065879047955794602938171974629709520283251314\
-59511059861134786141425569583552084
-
-564215126435806420341075934101272051464484951545220849325716367147299918729635\
-059264315034631721012653124597426754863468803216200776820224611444355433544089\
-016953714499922832879928217567125518716263848096589402254946093084047791236233\
-041537620782525730166766620470289090257218611836032142113856043568548993879425\
-857343045015661372720768054473990769502917287833747472:\
-153985312207225573165801361717786415307948003209947275839192231423981964556105\
-831862996273658574402514739772918826503389548822333466586133449248493261025380\
-513000108958388124906407295157074190586877472638369698800058959415862466401009\
-134935248102799236934960651547161557058439807546464478323842048499236473561533\
-16224450501781239567570407442384568180523024:\
-564215143217890131185890171875808697353084826602711923044639015553408004509708\
-910415566240312984054777798822673770842058220177923549254407869260660786051572\
-546936867292468398632851404852714077388847574861791706472279552453122259355001\
-461517546751407364441206351253202963908807286144025173428972804993699343157175\
-636744120098500835969469443985678727998677464391892976:\
-280307553102846081257541846769604254437229063221807779862025516083645039959265\
-055718231538583268565686285413775596054577834139317274122484816751543024366977\
-847275685572018333067845653917320453037019259792834349890735111304353171755970\
-499652255412351191889178879306173768770029810064429995148734076934059455174169\
-846606500277900935967350034371625167814786968465071328
-
-156330997529958487918177086881900440884006295444161043164584305911546310847924\
-024175009312456535487055875848720644484680186956347044362225642378352742268050\
-758212419446221677535836858478498438304194805882491490454166685752342090513455\
-839266832875839358373607977369552143320870423678628647403216466406948804712068\
-071326141631606511494425644601225915396941271955031509422471880114431:\
-104079318844838484272635474910207430779781510675090297991813928494995314614521\
-465462298090978135375300201792534241240585186557558393772320572916584658686962\
-210658892592424754545669607259944080726279075432472552301318052643405622090465\
-715301497561100132576170262836582815019435858892490536663887532234587320546911\
-83561044250986692200937236123240394613641778577730294737452449485455360252:\
-104079321946643990819253092012819110816177345166777894691533695943646152920533\
-471524764029748447855975389513264451712384893364577346908013500942202327306962\
-342882703907172147804714001620398701185453541494006698123775911874807200340621\
-933187849922703670200018620699727381486516617362232575982037404614229700995691\
-80609675206658975547530939841011183137196154282848918198966096478150328064:\
-147394054680024029448656968741795591022064260997135144671866502722895020822951\
-300747727605658269599951522355026658564837604325782631029718165533341359522958\
-964854562952773358755940140738903560261989383445929458033472219522327666099054\
-988913964570433307551281841442554322619577432710231080687502794019329786538349\
-1161555081277791430319129659894494481743591713783944415888427100634337281
-
-192742432084353737485842854839651647001999897056173812871623545743516531988117\
-339965384701594199968858421836038634383751007277236960802615243995875484352722\
-412933609661767131538076407390574057362143783589050340998588110618896348883696\
-125563943789850482263335924348264978463696800136518277159728763582468261584108\
-952187726976751241197004762530942245967214454546324023837383825253721452567697\
-794717487988736:\
-959962193221060261422644519806640804198576629442953062819145414385117049511633\
-775715837809110979377194495477627960580385163300794684707031449896541743697640\
-300188397005993187221669181657827870954976790909453889666881000647263703290533\
-524554938671081027204878119718254611483250278714622283503977477943931268683567\
-228821203225209559904547168711726849817053683598748661499869606954765369133370\
-92229189074944:\
-287988692297244547960275404946170019735797583233687873238631909861129630181055\
-189937592294158362052357338925349968486342493580260686965128392458005042878845\
-787311719474658585332003197143332858202877105771179249083989766854910119274936\
-842225402329933307146112411447523761159515134744334199364909386848804189892410\
-642391088126216254627620090526321810543360916515537224247210206457156899530409\
-061785821773823:\
-116658763061752490388879442993468714217074502099780965508880493294489615320498\
-598916180658715224704417632908736433904267337946139013157407044465122089802783\
-402958839940493450623334698543728134227514977113292860752136122773954368172506\
-188585803287402128154114938464056710514970418494077099789909303447054979396744\
-953534970411543454895938681122288344412978480900638676348314872424347571041040\
-934996425995656
-
-619786266658567161458334382543441083523001148027961994136463415241099020928995\
-027348108066376027576593442291905823546798067190985799584383502414253504844440\
-730247574898188831695302726465094372426547724102755426430985888819994718208395\
-058390426442949355070523840320102861103333260796003216406079590341075332153591\
-339953821651864082320219470134100954234839910065134150444399772935075524549882\
-1686711454288900391171944842526659:\
-708316352175880235861911402338223989844354847640203402787955259709095340391209\
-634971200147239107038172468635365524442887836970875407279489793714711202504935\
-603186491159650082737652479768187392853096298815404051593962772271625178036087\
-090235031173946705489376232274233435142076195961429400513783701379969616761834\
-406298266514873959908015450368421808843890754846316114141675745722301860170303\
-8186609114675801882755362128527359:\
-708327159071245727607641677856430760645108002834121423472231212800750464874953\
-994009996794996963892199050747305909874742043008824389073021408922823225270950\
-434784337183894602736156016019366364545812441288006044438890042032361728432168\
-647126262798386716769056482631622196248090362085776986511218520225633464194661\
-617883270231231246633118625078236896634828818179714270386680937604524829027569\
-9166178896599889783855804483371000:\
-302060381822935520393057552646980656167218247774880233099665711638991555083254\
-988184339043172276582509416808617025829546481721511566400979658296724433339381\
-138183103744717811455322545336544390098451333751418058080669065089698375948663\
-911223018430820919992809642584820022888411757631435070669578704942412723345473\
-703004410637171918163407825473429891681833137319253906550154525572046389799615\
-9415772989740353291713158957011339
-
-153121807390302739814320555790491322156896526370099783033527376357833528629507\
-072515691840100734691181994318393269548229995135098319990512192626937617475424\
-997690525810727128795715843264102277360123945461634057007045209878677307238273\
-136848869249575375012231391768983573912372523393596396428337722854310251146437\
-239953120196926275327085598161995670186316402932609647786505944852306498255543\
-5549425517304653828321632266676000978771592890871297:\
-653316492411524793195892078547995825767516477217743425556207192884824165114775\
-887614442622963238321103829199042465482359783037710576054724960495221679655768\
-102679238927004930412729935015150226360017870925801117314655049626936769818734\
-136698840856955739890901597723331451307695069775326903870772317081632928639314\
-223760409198708384384900487404031387838282988007696741415605210868542206809944\
-87988820262340914486548869329656852304620641304182784:\
-658420452057899004207635147423858188617237713694681182960969189672458819472321\
-865389487378756656005747201783161436117773895089844774512676642936245146868932\
-496317002372523552012535615409675967307886968581018437555486380290655194321212\
-490753879241593151391416092988244869095332679547555898527069208024136264827587\
-406357645812242365718771152871395945234828080403153694761860209053482505446893\
-76096785758323665651986023230985317443529264307572735:\
-427098318891833150606691119955885207789571852401748509159112419251105429122047\
-630344479122893363065151314789568427503012899811125982294967632705944062349845\
-198892639907564700515687683476929508115943147561825217902155847790068439569814\
-968136127749809472291056535294255579047357877479140580598724255984129295730809\
-046715535219761247042310918587648037156504410040932515583047680138614669150889\
-91584985713380361876245120741860499998309141578063426
-
-119691784090756354618475125889953171002036134515807563748079343880340594084231\
-503703696613116495657338394620973850999136042045776846616304492013860832778811\
-876296550621270497835164496576749549491607887309667857378295212909075868976019\
-270457554009833636161345471184655988634635109445455685549672896498242279296548\
-581782062314473968211379339320195545598851361344026540909992672508928806916416\
-6070460665693449677225330807040774887885863989834766872962436454378635264:\
-120751003418993136514467777966933214451558344083693106320774693531277965212748\
-123712723108409908609524943671372664643442820439616246054114335461385047571898\
-470435877578511065533412260433147378939396808831872774416156636119760608984686\
-375845719493409304186182273867116770354858381276841408315828240144548252654063\
-587803984461663506790631022955067453299217870062362109467777250060681435305211\
-3332587496286737780523118478748777405220188226473576965343499882873225278:\
-120868694455463890062105000863748067534460230373773776112403745267479861381124\
-125190846118847827203298674888323045418097901644329877738540164830443413631059\
-273497896767066740208861206611070835728860977413356308230070436198675030465026\
-104452845273083395291485424709762497423540532726191452535634477336654999348196\
-997365083216604753758873491788084713190659740240400641739766777125835378858604\
-8393559917823374804348084365752445214581069135270586621303802552945475584:\
-958194759315416644126875548259533242624955602300731820689682836016791464332203\
-610662447114317797562459804443140515271196956013571558349703589323614834378591\
-938642181092274940644952240084099929826614029057350142494858158806435906750389\
-637468377205892531502218773581812451063196214364290877065957720575387909171300\
-276632758896753184683770343175390824546838017656435941331331298229265536628804\
-262334171225139421241085151179044502022429281286227203444516024441896960
-
-222312083207177133687311925138669093563928497099927117666030242446307491078382\
-979424932869501410520911530129235023661343294916529463305250947205042534007484\
-680871586164029714558637507923404030751686651125368687405052640066803140940597\
-689331760866640108160581451536268782896738408905937044691993708685252040548299\
-740910389022371269440063796535182866312087520132122618643126958518731753485941\
-963028484337400180363745363062544373276399647832332115882636263663929040532875\
-45137729634304:\
-551972315206063507668961565866195532640067153199730413232580696204342127335474\
-819404406651224302958880776551238666093576090792093189432499246020594211834908\
-026400210581296554360146614372887335978753526354636055817275779279033657100763\
-646489845563689520138636501101498644620525615639455003220053189532031342350232\
-139331381023004437925641490493987718296400242369486185901958756946221440080276\
-584593117957373057779314982014493841672253508388481953692431909141602700300082\
-2695447756801:\
-222312095532780792495729747304903173001915640076007811590115687659256710194618\
-602357645860386245983780889492087709710697935903115249605253792576276660553224\
-762447066292589955536234917592485038516259846884318174800149712368364251954915\
-530741710063434496140219128568292832105535524487039562653592710057343318324594\
-207899031572702955109290772047658923011488632173711704642888117589900223316658\
-470161939008073537120018952058648104319107165880786294565056218031781875036082\
-10505947152383:\
-364703482242040826179683217159847199718534303447383460181587832695349429508740\
-828381297990675899010066835083876695749292366947544741796326541183653367663448\
-858662489673784859632032361731246952835955774475093345427254905041782190144873\
-650108478410002261875610182455653581061846491564826677369668524321409245219390\
-824606803330049019199929037577685492370506122870140121866506987832313437477692\
-132622232761651090506331850971618512485198032209371437083104544806336122122736\
-2415161659270
-
-835470119115520366465485095342106120387419298920149693003803589895808498182504\
-983286202220727418337337207909269990257957649105806780415934737679480816773820\
-273516790011393173384180265132943339477110538055082922309489559954517547651743\
-068351949242116841876424691199418459581205772134530173804916500398071970155716\
-922198041212121295839192394068512651615408411517444996976338436334441134374442\
-713655164951686636568673104074437978097901431528740467913275058211989566315928\
-70173066361218199879680:\
-410293649748098476201089630699481985224428497808971949270996133109083534591600\
-670527701955888156758454388111767623476138314652381907706003734896671448777355\
-984194654234823947975205873523969152823275400916148022876057112565895945730947\
-898902032152375738320212407368207184938289923571482058289483328400078849451781\
-494817989808064786401605330488039627168817711056510709245379074893123005265440\
-198622563570385829124084707962021763868731837706296040997472466128022701381080\
-735411984967128336633726905614335:\
-820186817556158186367038473869064839994319799765456959587833370810414083411158\
-254801407589470287722544233582367854026817545027881527768493255338366870066888\
-883492431923420017990172932704900043518701973291327881583990562288988556072718\
-797041582835554822801600149187529479456735632658100596008588685836761992714026\
-339410172759218320101282566836998419830856072288278488644518761524617056827770\
-234653382919693035187143125872988702135622344643430943915449281279745854042337\
-638536654819416181782103701159936:\
-675548500020711187873170838699317917071067460299127044209115129964576134510219\
-233170044019109685636566374840522184243533887027762119168428418928815966546246\
-335720281364688363402404806254650044381401966370921504063539292432277193902087\
-920366860582143125494711216824784927851927917872947951215648384329113756987750\
-587734405477772996825311824091354200813861933343740682982084916776684037811197\
-351928854247212562050174291245613540754928441172715138221125528385004514860228\
-862293768600598689250813502259200
-
-756488815892504791004625569469850407323005400004366825207404880603579388162651\
-703075413006205741038090446597811692301531429251478568422655419814548515970242\
-812326082916923728976231890961858169567593524916371244544560188029929155491827\
-134623944636360217868055073268816228683761207684283469651538626753605200082212\
-376733114514981571862595679873708623166882437418411440280485090986420123182846\
-130264786076551202656316182175195248580618478705551455804205337921211363902792\
-1328660178276411994304854590561064213923122475171839:\
-524919320813988798094429054599723054652749576385950359071221442940266292048262\
-089959423438843494841640614151978216142379320930875545712205112045956996340748\
-510470311175198406264181115585735800827638688896471067176058188165078200739564\
-779352830424664799065003439382184581149262885183468097883789821076419894338204\
-684110415290954932314416633174988108986552716580951622201464331628605646922071\
-727967016015052699481645695546827982409220685913557512674201556843047948567320\
-12285735168099112790094833546362752:\
-151297763178500957676005793079503871808386976657240934483207847471025772450667\
-033546372863347216073852970411406489330952645048794316352726756320864428846657\
-451417794208787538731351412830517858010136176764071574554347982143178338298753\
-957404515205021833676624714923202238014375878305791745907317350603526871039417\
-499008665516380550421100807196416795115511752701599028142740630508483652342112\
-538377218527807228660221741802043890941250573340365867868658881226714445382883\
-90455437106126668343798555022177143445970739238273279:\
-706246357373242323651940744685811402297938886335836541988798279900547372639640\
-434568794691568713897746219715011960618387422314425760839536521283782231367426\
-638149049640380535167357481834788692421108386515754582099692858890072506755881\
-340585423333737687422160088887489190828691572998521664354872661477038917752581\
-211449873821004103651684533487921980935990783153174452907652978410436458340727\
-334522712855647100019370079018999372936157878410676623861134810944127539967714\
-8042656086991768134743565748018330789804311913260878
-
-134914273957711817215491954130516625575218760622755806963876531979253214285747\
-641194554588882150281649580177869476612323276133217267570313678819356975147085\
-659263513840461834326154742273172704464743046341797711860972635338575790137015\
-259294043624888982908506563507262489906750942708846822315725563835081866809000\
-550633069490295488246378567577889046897797418739651556054482104963229769323366\
-477830288678375028712217783183759725102446211871376735609188495755722263811895\
-292592874257800015092439407743737673877281314481833548368387462303548397:\
-139547555813926683976421720270092560382963651902738755917245910012093643523143\
-643711670238254024616320509185269101827510000276660615336935193934446985558649\
-188355292374453790156141807656886204517479036372370432904348878607173593620472\
-446809776093481990260083684041394656025353396678394131324792231208955534221337\
-904393559837473569151592354948531482244486913419880793232269610976638201912325\
-512816802252531842160042924624922163707026881531578965042022203590528024136270\
-702522457610210729719877148067364869869193140363617404084902603658362880:\
-143908416933111381584810762138139711092365141100300394517267863550302806783470\
-597896318187669188526217676933576504844775887690776446480013942663676114056640\
-475030203125048375572942808228473583270484151796992726677207094887163056882629\
-224114079873969900375787619394103957169821647387838649446187620260920070333048\
-993174449935551298063499061276379132530173432160743068632129643546082545472796\
-435903332238217544615526557421309373919305927845490931849432719976269209443476\
-906004384628808389021633363107647214209685671746850846172055278056406543:\
-119318039859070569138149041519071295649436048820652970732706136473549711088970\
-848686008035761997294270119817035346987165565322649665312074113561945974034283\
-402248272206934123057945527272928729703511632790319407650864924750777574600718\
-280733543180592586396135755088900095726047018815794492555324551324738555073151\
-955747073423510267799209107297506834135891525427123859309210608692110492650024\
-632686644556709428361603523869111161894211225929164802872598834129533528491365\
-151111244022664430609675158094720423643928998542728274465765072677699598
-
-482662134159467834812180767481173215715676742301631186501951391004198900377207\
-373589641343944384391440443178479031774560347819945250859069133111772556486191\
-096174425987664662050884831693651483182498574572407306200851620931672138233584\
-102711632254415860054789079384921326111412108618469341200674908446602081895559\
-527255068713571272693488779379312492209860974259702366178875806932512054439761\
-828304067214994678088532429561380223412984555716296603419647510999722983599018\
-402702474546842510376859866939455609421448723497378122855119713378396044836445\
-2485403771007:\
-482662134040067455805875594289390615545451031210555334083920141034036154844025\
-190757491350034139955422824242226851892262797599303963596736212929881628361851\
-338483867799795233369182160622541109711048539250430799191302255272447158707866\
-862214935616821935735521837178124737564314545318714540695685555657641731255622\
-471250984878511384547483927097075638203154103482553439380006457147914031074042\
-392936783369922997050945257733341963280647502243949126766065410802825915931599\
-442979251639378705636075101433244816559327337853672003799785649369942281793252\
-1995434459135:\
-514839609642239159369321098522268942457500528221329005145761642303113681519367\
-531450222321604640702865371254668166252308641479614910656095549944250474961480\
-457341734093153707140358914650438176117877308143347094568270556746278858613185\
-342984076062114817484042609709590521191851744222509150728812293017797169351645\
-480717151980812916216236707261110121486780096876744840696345828190952458663072\
-228051680212498645730442049017950970524517868146539196106917772713460062960896\
-643525317004733361589889637628324517737843666539446856763635201225654726897621\
-7368205262720:\
-573004858701619542920160672699460675807124555479776167761129859754838615143507\
-096345726469845687825264388039902688865701645600784795709612302732976169631710\
-068439293580767467191846584118836737804874997421837507104364911918592327812247\
-953231261568475026754847832752654436240041153220337156863708537770698186191567\
-486161376166467453144600329093584201525180299157733269208581982071881412637579\
-738514058207399502343387475474891305333223059184840470167478442318071873366760\
-589312307283030687027684698011894809280765264781686144320570806771584560428897\
-386974396543
-
-504534201697040598200323807850877083840092726321359192845030112879520852529467\
-137537034010743287960022395701822675262054678747259278730311755008013387473920\
-354043297108246407255757342302486052070343130164118616667085280587121148105864\
-415135432677051671360120711340918556964899010059071854990133378162360385608417\
-690083444034475458423361457004206906395460683178954334052145525543540635509428\
-408343574244943570347180864652172435075911110022028361708468238809669180375984\
-361505612202172572186375255539865347539711509646231066668711717562116288021222\
-32419817052896834111407455732223:\
-593569179756566344675504124808668343648047094439834660131659156801096186313561\
-147311170282773753363055437659311168930061360938607681614587369252448092172541\
-783477388760604902312224165491550871038736894957393218255633091564070849449655\
-575617282381447175886843876269626913238828115902062470183540295482110793362293\
-593038058079025122648803217146549622715193186306695535505995655524443142875307\
-579658164167976120941601819942840478401094507760707482029306077358606545777206\
-950260429914781566838544170204495889621947151172402282733108226057509979868045\
-4802805093052908857688768774136:\
-890354530294283922652748941729925191878159619714541069989902378413631036649607\
-911542614012588176123737588265530607723402122084237870905347568338169257517228\
-235169532153285846886109349580954281772568362738068809533003821191161082852056\
-341523928947671614622150132396709249215828040804463577206121524624490277680288\
-342990513689892270115100636920983547664412774360602192809371727815659313360846\
-431774716832213398446346904492410653735005021439797698624044236748179376439483\
-829725191476600046769980993624822605302919181861367625197751093587453254287000\
-25939697047278766228426746494983:\
-294572671559777014381458797411928530393649334448735884939922374161176733794147\
-580811826609389858101804723338365550802992860518164761017012063517325957125069\
-342038031326190968775104312468849847989584066087428010276835422208951026312225\
-860874421325886914117597531258270231537714530006153667665531709333584476558074\
-257128148269263950937978489872101757854851961187965374831230685000391027084511\
-231088337870661165779138598040693111132726001036708539213418003567035462138019\
-020290505931654504167851814706825384251604912298085803798632768939951539427831\
-35116596641880856560800917256770
-
-172453484063811385695144205778952736401660556978434537374640673371143334353576\
-570642366217082623359375558207626439782954816479910694843304831706655996627232\
-235892105585877720959851948802987934183715641428052514126370019001198819022324\
-604058913600759295791187782766185494063785641325690646469224808449402832897524\
-049639358645979604104491506865896292786253274510478904175661313285781016735698\
-720085359640008042410629230926480476718585874654572510645515609853634400543581\
-095227248970923430716360968574121726268352196864398080101472518469054986415767\
-1530664495100199680534279639039858273457994404462591:\
-985448479956738527071379308532272419819886442085170287001167137838671086267799\
-312283037745667610293587289906133513586493017516072856123288486063878822224621\
-927231080940671911186572958099076844227770962343574977271896011093978335955389\
-265996939038718592603124225853284363150741511446391176831836401142237444334536\
-516766813313107880948723844751829763055011704014722992787444903911772811849420\
-391324295523327165151755469837052218545692271949446523617241964502152200350605\
-909604877830771525694407493301422118777172362873370411634814849822736997175761\
-205322169847345870736382763705709391417224317632511:\
-172453484104601181956659582737914435020386272293903728088666065993673480227134\
-878510652321222012344152109444777211302302973769903472916266262841616316221298\
-942500138521065976687675717560251868908718753562584155082779841774375005952172\
-132315374372196974281476943240846694502463959252590941598802908940029524344789\
-329496833948193353052599527362616558694233548395437988743633698611799469803410\
-889328442501630489315589788463183298878319206661639384204964707600731845058788\
-735278311029859502119872600912650357733032135863362145677267207106391493648734\
-7703156832882588010272465516632045319666839727374367:\
-372304669527507317235352753542056161670850110027270225868451499060199969679716\
-012405895916682413602518537596497499688012911970317452906598295056919671735380\
-738207095623789680919013738873742222230171699957533537366557937022729669671138\
-788088172159707796465972043287300084470564149574009584107674748446598156638975\
-496365478748743280933467679259128874198540150466633828482035726419951475578386\
-867503043308391274504534730501287473188467697186301802126020885918628501846552\
-041519264024703307572266330247857183178884498165748968478042680268251067327564\
-75148563478581958963423401208533356248482167371614
-
-403962479508663087109548633412217892417617035204767650431859302528229530742895\
-742033651742462459783834500313924115696422574653078671661435062805306468214482\
-588477458921865739093810961801773134879136162250419246817794766874021354682230\
-605950475438346752103393154640268772440373356691666816173825329547376129696614\
-425860046866190104850391483673305179185789649110530766305473073202379303858407\
-959751154257081007942759986814604359908065938558161711792085670165859981075713\
-055157027113666925697443594515843173886660276090934075765996176171153488557808\
-7589056445717173784815273994900632757500093911152413312330963129335803:\
-242377545552467842234840420020434027645818353726725481410889260223050170290156\
-161155675527731583327403678747755092689152937623685123083644515825430403092253\
-751548658290807473847925596482338804222507800847258646309987265109480716251421\
-173286865698565132982137921610700582454103035908835478508221948483529616781271\
-603687410045303194086611543280610432636406279236967231038368911876364388079055\
-683796043766099824175928046018542771463683799984282292513398330531403036612837\
-660309567830603708722911213478083874411301203023264112990450272681237371312718\
-00702097663252053173585397512121695417202951066338965816216909841956863:\
-282773803133376800536941864087867576784664522460860796643298465676050190052542\
-833459754617268935494218095584235811237233836250063631464303263937490306171679\
-857770239782371750923326892970152496017309863072565551051584835535905009943797\
-156810283281235301929269431559680730039766284149705806600741502370903978662148\
-703591399461875675015276207174580071286758739106355959584825913147748486084637\
-569670147973135003281266681579532611358234483736521638907952518322313988059226\
-160541032074571167259389432965656934700539931759606746231970771705272905999916\
-02513308937441091082589576001556395260554024570395436038531438203633668:\
-581988904342232530948044007845591870252619757626351647242472066895402452288878\
-709042144324910701138086373451385660059597466730279800379607432440569293164710\
-899898997255202859187168255718030294581656869713657596797502083769985891634461\
-687487341723021354550278938535644429211718210860858559320983290184434583734130\
-873025136908851186214129949483403068166702553532720795616795471533394760299912\
-826869514512595882295175000653225060472879095818624236630873555325725907576645\
-856584021562638827484452521161834908109120260354665504664323661497343785729804\
-1927436702300476589084483375730789091840695585559924682501773026192063
-
-298071770121670991705190569380761255324895737173501053496018683772491375236797\
-376613685120294690736924237525548368089370345001836290595816278551023868343227\
-805758446487206383806823853079140505139738679085728261401209451765448708135408\
-450396857062442004967709015947017648765501366437692258792826406915912340241566\
-910049101821463512333736382409292590036535731503233362670502145921351856552724\
-450928617826833310549019598241797088502216114384862048801938144553969250541971\
-139543262458628655112122701491905841740280360046391542899807180883310215764780\
-221235384234625815076584629495505984947616223694413206319067667558940036180274\
-160661954560:\
-298071770117333476703804531166340495372758318857327150803671678132040695064016\
-634151781401896216312339488759227008714048216730463196606600476956890213729209\
-111003912523137171735063423813753123761972768398032269726070690554696798786901\
-315420554912578345622185900914139448015734774872389594376627524856933639458048\
-392427645201996545685467462492157360206606969629097494816941216204161322699629\
-573755717237021186146639851711820051248957527186871682249550183098589032478452\
-203795258104490042411580265916552217979801988667901158868057022859689080823983\
-813172981454888367624818098200775358066929805640819897056391260900808803860261\
-358851325951:\
-596143522459597721662693739712559817395899374121788438159883061362755544963621\
-340151185115957588108668098591584663285213393896019832141182007735033893725627\
-088759800011431132472663383591979482586114457942271963656741800901763411531305\
-927875223631530143141348225978447806611477223178617732602198510500755642465185\
-229594183093848951745422166042285513257194559634957364292350863530578132262499\
-566571911965830364272986784781834923134053882806849432780058535477881769133186\
-617727228491964253121334046012401031496354473070056520173279778404507152671599\
-536374791038172215652690152758040911382336597106085574215420770340944519886432\
-012762808321:\
-228189190452373975998687067720046402676850276224525352264828567832831069508142\
-881842738790829520407606559010724764756179733056929367197818687995101531487417\
-540164121663830097873427530280512587156518334815653537268374503709689585182374\
-425203787308377135963208255579470796173293592029250177512660045745607720995794\
-260565794021742758071065547703841895363554855982040274196939124300757983148672\
-793335089730621145928749488851840055321615413183485343177905971082188532779804\
-174536139289840790560285505424564589976749068458299567203033333705415982044319\
-548707144770805441630156069877698728165858208419544860258754909216438081994749\
-290874784779
-
-549576895392555215050122058829785748470937386456930570866557813363668877971204\
-750721728277961197386655030221017716165921536808367639829982698695049399732541\
-737313619787427238232802589119968873754889339204072488760713545929764837122582\
-127158327126738900076509681659773377144253229414868414721757641883137593649552\
-987106569177270702836296442402331814976213264343032046939547732755758021651787\
-327866562104512308683492328733943282317930252992555877578121840181526378055115\
-238926782662754434856800830072592147890054206594596974167629093386856799357852\
-978525202457797266062408497155861632006337843899368546313308403854634979531628\
-5236895844700009481274852376575:\
-549878925785022673877927070783312216320021668280261080607911260853354967873322\
-810541105735080980852887074251225563641043674045952273187553569408046608782877\
-370636984301129983238537615146470167358062153854124706440455736687602218167940\
-311021784702208677715900230797134987075892750090047585628455153374983792775568\
-294127491225202181568625773821010138436249591498329908508247110906027360908999\
-243072335023340827252823243480226617574736181198622389466469996491882195687020\
-917814719167883132553075808761334760160385253136017250936480296542951816151618\
-601752734086159549664726587866498101779888807397229068115172907674364955354196\
-5507788687545892312234544070144:\
-549979597300651622463788585456698759218710876850585303664045294317149902903591\
-121944574817821700747325948144678170705535664738446778914413565790221669894948\
-182722220435315689076337997793377107795848811024837398947657522470971583543647\
-027702353840329374453138673214860595121296005460603541409748668750908150128346\
-198844283262798870911984051905771919054559671318589128663446392614045400949724\
-109225219700992821059170497807114186912021349337724625757726246350243877542214\
-908771718889784207768172418760168195563734000057905427129014175826861262482904\
-135970044144334501757986344895888503762060497891996004121665574667009911472637\
-3402927964770024933756787228671:\
-524704019535404941467883214399542392144536726201816851718964819044191660687414\
-228935857562040239884388430554417370276990628928019063142977488252908019885304\
-963823496715488856043385651915051999780301958912787482092328758707882622958835\
-706576600630427334703364862556736969145050395354151202853902975947513002675232\
-267369261603595183867825556537230916179415342435123678800540848412075676750116\
-926967694442301205453636040127260202737804138135473892349091568767281604803348\
-894205885580699054872534676566088272614939044721065783039122179574394659166598\
-734927001566034056858264694834428797354116202199986894965903274099605375099877\
-6136950779694020608617019983621
-
-101230464775564845841728559986304705613817636499383056638407127744377964630689\
-754826248245368088788978044966352463118215232331556744972943605522773862070896\
-036600935621408989109285560073425684642623590087368423576276385919413364416066\
-437991993096114860225396670861960786945968121144544301365570811247690646163893\
-971608913115396879538068411003379326888093196741918450649107538941385562475415\
-584160237056319287728522698764272321135598636024863084997181557833208547327185\
-813184767729987424610054511115458669135660869620246494181444224249917383799159\
-442037532650631395781127512367897295092636575133524539508230563676101084057482\
-625359019353682835593110459560330633726597657526208:\
-792410588775426716231164932744812674204557772168091572404146183694608096943284\
-652900939788685928054641000342252235834336455968405402228636812879248387248096\
-826123436571708145650235053958556127432723612195601411978414956389825167552036\
-116935722145710737294923784152479093576914330397635301677033317083684699877056\
-539278689022858950843258922476804004778374708719854892944709424401122656004561\
-324316464490003044640187727721512470814233931699871487222430649339077930969598\
-674973301209754869606858387107949655496473915699039373011991532516454460854972\
-011307314502271830655074460634222364043503815993692398774231322338179190773280\
-404856376677573763370901210719998190388084998076:\
-101428567446369876668771509903370861498151058623765764422665978046659744125359\
-205712876037814987658349958632447005418167518868673905459766991835495989182087\
-145283564592452246666333233677906505288226720645978173064072415522276368047937\
-433566630492233743058779580638903783829317616834911353463797372663393855675671\
-626174378094501365920230683464938258009515957304101225946240574284032503580975\
-368714333766171294073499049498681256707100801955528790913482733295020626613912\
-256796653078724277211325015130403946792617600108186216752826522106944610492051\
-257917360149265461640486222299667925439867342391278891001214341522368994584199\
-820332948113570029614311030366805412684372744601664:\
-614988038527854563594121324080818688727355049138392499463043469368292786857984\
-787185677098585494895263990026591201698874504684771890624674016181192016398425\
-891647093903676091029855360096934308619247709930502305436728153370914397843894\
-247684881121120101552558648463772580417056948904282408807537641632082019677849\
-402826726998620227309975735533304953713088104828743744915505185369198699199028\
-184937679359209349913401319783419410383955977585573003559825133356603457797727\
-294316455222616520352406092538427848389025808778431243394684332840214279357184\
-353530077646723559699510536343543073579759673831728568487977471278334851417932\
-55762849108722751033866179476826664951821035900032
-
-187102682544606671658971415655461190855533149783246896441212485149068792661466\
-916492729012824301411032137595425172292201197420813535552223019926143544570410\
-135297069853163972420120846881811551650434000968539259766247781494777072844312\
-486626637909244938692326421268056471034027471826967732238845768337979720971459\
-940091707257523640912238864050109759982174696333286705437875779595450305177041\
-255432981222874755231013669605038620924101482224813466425720501362381783132777\
-578483166565776646501318532783762483136758865354114173698839027469349060208884\
-875628178656495180378671615241992854425661655137575270125441054863618952713997\
-2588012514188916089130908353990300905644138665982639991006640258678783:\
-374114006357507427288500737419070048281003684939729166381430888965543131240028\
-948469694283866505437317168534462173981935099564739230901580385866441475529822\
-300565094307521290881381949959363727261736515401422791416262975634410124332809\
-658650429921967265572689162250643464722980633874682471870216282449199968380216\
-053257109639613807868429810288731361597786861617813950388101475526738149046192\
-084106590360636503952880897668316812674468356631174552127963738520578373889115\
-527854933315234758330492019518061448160683076010284246360380242932921009370216\
-360553328027267616075797995850161460090069584163357540681492472788739341147915\
-7369543528986538649355746661723186062819385784603047393131087590850559:\
-374205320480457624860957020238680055461352070984832899068701169658296313206733\
-038060493680817308439897283518426186727757391137120256972731802611141617202532\
-998673456695523843470290610276478876557432073270596859460447352802722174576623\
-617465067727613913270552298052675213382470924847303576402330921373967200316700\
-537887963428090292646573948506333751430311425868899118317852286422866334781862\
-117878234417352010501309904464550793273559234600860195264406466538171102306880\
-433350620978167583831636005779767855017984285957699400791590280596687046277265\
-854303522969050466910011084981660871300650808812220147617761140357020962665580\
-7183177381793657915609249819911619042131749195888984378170638589624447:\
-153531895010549366737274562714232427684086399378501312561171226801161002606909\
-477273286881522944022422509894766010580006620832865979568531408808335516265159\
-365058287639926463353361016745418606406748388173557973132849946992224747791471\
-366299313968217271689234688794354668785674349373594028062186752306511255498361\
-131689212497823860849218355211952415763095503827827460886257262793315050154771\
-580776514784730735268534973119279282288397812460566265854825609666685533818135\
-833896755450854049918881147020334658725771865431580296247218233236340041508483\
-658796292834848134122712580535505063661289808419966044724993762706644918801076\
-2441109090173077906861953924523769461987828737196117791305653477170410
-
-151078351203878468970134589916228349419176985497911633052123878634121816025100\
-473284451342594609832012641506311301093381553983158535412679448868047926137945\
-132659538946468068018296511634294898825673883933814593611864955604916824706820\
-375314980389524154233309815666712161813582112359046490875230021775221200413294\
-040944212810919520564905350307565477721804659414054973441237634542394238597666\
-945567922475840744876415083863236162495784750319569801651441465590228924857416\
-654875407060765354870312398924063403059831524766366800157254741941973647296401\
-321458680805166171098823843806924038811268738360974456956796193406940830147859\
-652202853426039749840385569875321765661278734497083884782244968477779655801797\
-0177:\
-345143530040489495051184120744620602062341460252626861322702216020194576234476\
-779915793759519650405289318839374805504942561472824999899977050944038069963896\
-582090967864120887377381555059220979688475238272275627664813481458518510330349\
-335342972287417526650225178473910149302546630174412760586432109694074147396117\
-112424116577991678600581920316472316920894121033302012014921627261493383686354\
-812164265289757933234267241534982232805685029413102150871063740249862194033367\
-219879704032732058189276614127740544193554617142139886008263800042657193003045\
-097928182820144903101881314307945671646911160341774822844808387021537184052847\
-743181603149580208820030158861438803777245039132213940735632958054949747594723\
-58947291135:\
-690287044651858409269337849759439578759905532315771835762283328067209507207453\
-526963572403913394019723329428750251216512423826880571888169456281711320620329\
-143981928738594977098736671800545364074290979970015811703565904887051567978423\
-953859176208249323030962105775089623117859281093082505304098276011950592478389\
-926531292148253094842239063802695110256252098344593274289872768949790623755871\
-258462194469771332113953069621466405812245493670448587776190836321676143253126\
-273977154565389428127188142719374940047996359266404574578642709272183491354295\
-019999500192420036512897212224779719218807491452634902592533798534244521250723\
-013558529361853940146977866009705863165065935002976782176020402331459381295879\
-30589577215:\
-259307426368374740656047030890717319943922741843166527209674882455616641604966\
-923090876382832966389678473500289878140679879908239124226037525569096635872328\
-602967359860503995394910853247175263593055005961927979010413291816371166537560\
-700428996909634993850654889951181255772691932519679676741504260931397564000817\
-065144316919958191083174231842042627290722165963876124927377303428054410204142\
-393404279809323133955167215832763793476212797402659880770715205581739702380086\
-975359799607996743658395744515759167856402612064855314887079534932100935613518\
-101956312866742382937763383890166951743618276705950124275655006631249131676825\
-056099784628493429768170528593153313077778772661986512028373274168378651369453\
-62999568408
-
-481860127535887278640489155050721683858230199530232560468174421194131532442358\
-530375507922039038395043047812131418599186355766273115363209728278906900298263\
-454490668439394975134380059154344103629136993024117780843353352657912281718861\
-859336453227284806158867153907427719180531160973285792920985765196127559544931\
-212602370159541882066164514333313513903878917378371492912189984374262500285093\
-164663645859149043701265158919210986174011971785566155658952755262057284244982\
-973587318866103927625233737353607146467805088117497861940096680592105436419812\
-330196610940160656917394500194184481139305063418639459439566806986893607744461\
-561166730411488652567983059857442571879719807347876080323777488300071657155521\
-2880974209379540757731340032:\
-497403980621080605240855893856869429047398618503402436479960691778588739596594\
-583831127879774006619635075446219972275557679669095783230301894719138891467848\
-728844897600040295946267255806747793904448678440872631831142499578178834315251\
-386280688408826946289768448660488295880537573496594422045155488309050658218911\
-790782210810022655217488562121312766455339331288497859517288501388425342020142\
-280107661122933579180567367944460795341229309909353663360428458033738224960147\
-507426103313449213619303423800587076859665645578840217254967791271622792154411\
-855487974494312849627428167608382228407024615803524050972815537681008232903709\
-137554512552015303920743044332206904323309330188964292032835848105307268257153\
-3579895324587076225968633602:\
-126838083336802747376160983603448523470452162145204527781407982536703327634271\
-747597079805257661480597772986326875514339496146821533419011270922951803154639\
-123493035272795958877184490135110408766464447628415963924119243695878829389163\
-169609003001003740883191637705425957165510096578865976816438207687302207203041\
-166405589926857821484285678312215154477683808523549363941820560827811610810589\
-409942641356625293746489630086699126922868816615986286938344378462183408042439\
-442605515717729960103290869121557044652450361962342622073042765546220145577119\
-862098876932293170103599518744218955277351135951205603883428212033802011341105\
-679555551702621629592683698911659432237325067437140891914219730326477466126396\
-9977401677729509178568494545151:\
-346025088668439463084536841179383789348644957238645298773372007838516124253922\
-016802531615637101878596059409033083407921771178994371838397133835661330476789\
-067877513201530704883843029514258864156806327140376852089556129356453647939494\
-880668045462793738391866612676608464084449559675443206350378184717831029814185\
-868984819874205862493317867900588572029453779388623240657754332696419141907010\
-408579016754362333841353053766750895815139017998918018067401931345702291070806\
-115531692422533335881732369469468381702124719555462318995427920732470129969099\
-799158005843680171101766232514382948689349881122254170092083174405965832017281\
-571425337114655480616136984267967701620585685178893419076425759876823667538684\
-288682203083349593052873703942
-
-110105869746694998008396066329637626664629991231196581549610475727847247398922\
-039353902012976965584877602973481333864789136145664203376287677688877991502015\
-282167200261922289673374388782033345270119296102856746771432252417734975620144\
-661390748049060546578162843821904801595592327161481001704753177142358633161452\
-790908023699690419172455818826479050966567603917109180531380585056442488498594\
-637068451552141392495540083090840027530310740057963827584975695103209747903344\
-624373356665495573915292251879000149419532731243890501065794365500603795610507\
-898782208683365391005915657448047726473090752959667920783592108309858035277805\
-054226628250575134467145488486033750235278612707423371029511207272724621864352\
-73801862054483894623724948004984124660389758631936:\
-117446257329625366371682218897238287428068009257332549839066753738901750518910\
-368794943160338267276512713193710919447130139142518880095720492863660208497450\
-065869245085014811373388336424068391434464283880549051104966121432697751539928\
-532816770573887308769576929905491242681290802423722350882361509130557788273326\
-691208855522803098750751513150193980410449639802211428875448845625213774402969\
-869505000825940421345776011176438288012850689151886863374795116073315401122456\
-613416143992364516565549227264822174421592039665455353398112742478374238156740\
-147073317472489856252752944982465745312509731048465436477826388638996455193153\
-729098681408070158237248434429177194178164428203633643376077237259787485677574\
-95823473189944728736714125104464087422921902882817:\
-117446257329625379410842340790445987341805106632244773292456870239590528139402\
-828287151635321791896170071722787608753899649024792005345530993589559915063682\
-123582332532557330770567972522610018196051370196295683311529337012508773357284\
-425819146093674672965798810865019078521603865909076843435522230756237477809316\
-213715039449295062919453905443360187372726298518736743993381343336004929411998\
-352976537009706948613168169224175267034478098623275412836293576013808008382262\
-969628243478661953502557036691746926532945414469496525434157574159412669927843\
-814935618072460079251303760873939830191222772099050378219809031552432195208609\
-212863079229596620473509017330178396479974510494385905177684728318803423370564\
-41271085032171732086372143934429274617112011210751:\
-952053549814715563854880344672721095305249289204708534120572882835371266444407\
-026604986877371563126151002309311698564299148955009622019028538238498502655693\
-802934084711187858933924900995203282262736995362608649955531896305632800081736\
-177024381465003616586913938750153866024514728417074908311609255840179282458281\
-958081891009255299920017799566176450495530155200666435259722558704530374358860\
-814083576313289136167428431104608102281167231999790821967014746922967580395771\
-836110271625387065370637276151264481971257020998559184353047706240722290749085\
-930188994524219806265326018934023818725073144111593840028587445875848999746337\
-473402476832812217180528787367502792925237989219508713677677119870798818072814\
-748870628560334617873554628715455008761965485326
-
-216437707903550637633919416420545773706786191615023300574910080584711922281290\
-030003257264393714286830979971440254668028304200827031696872458435080675046668\
-007234022047507545248348449837430086204641446537486220587622070406451223669283\
-093691621752320477636136711758134185335102232117843143217881295116904197641733\
-327108688417085062900677428752099154598377278329108152082350068064118725648010\
-208689135918509976948098442683041552775712327068275685350518778016037232304987\
-326883608636618885937431430004560135998650059257823377022700960973922930125642\
-669036336246371049135507467603924687579148605142388836290323619323190160387837\
-368813353428198066194917029100079412545257435453634376417739968228411951911043\
-233103246432929672579670400553144876223816352215288835668003303456895:\
-215605369718840947298552414206055246851449527391101300058268892175626808146417\
-186616180504072300566013925647702043421333899582400121577928221551304294587821\
-088454962242919916014341806182078354571463523945757274462923613759087793138937\
-804805171292056394319709963014160478255063521983343997799933655600864954978098\
-289372105376784226959867515264214187156254047780327672438396236150535419911143\
-456836828675813981017925991820820376171139818578704836318262782778429639291223\
-645635630531389304101325659764814845520561247219457016895870309154993294988493\
-975732160867173637939121793429598654402162833760238389852619137642666088450490\
-778578809218689655770317429798772766264053802001122156030848317489669387972449\
-969970339325954800661553442880573851225457419393713244222729599582208:\
-216861677505760924058026133128022813563433548789659545847005372774312367815860\
-072024022761301546428638941363329932370317100952933951899840888412094680905891\
-373994861328320144051694071313903151079313008206991189008339162023723311033433\
-375660782479030397183014039161492709397845703043915051850153151582750919062909\
-600125808252137332414010777901425255237762465506845578601118123607815852165398\
-002654276468237588425430579315328697264906541176229100951072014510063137024010\
-357470049094659868052781300960189746754584163310808466003912630024651204636662\
-984807852816823543241587328051726832494098395148070677172477809810794285727110\
-588182419015290805657808465309369193428417363010403157371087625477120275939830\
-628027659754468751067390092985630814036876112460244256777931700830208:\
-195427311488783715091289549188018710390187641606600673879209002150864647696026\
-480417078366967523376270364514854750190317996619424348969057645198799781280668\
-438616961018864632071667701580814359708092828948784846874160871527883091255249\
-911681971113159903954937114594564859582695509594023527235655635270629987149973\
-714768127525987113905124369700315792154506577352947122796140597988808077359482\
-571731958164454322685782629050521083262597805384761168347672751175125687957346\
-507516634726123644344680571741316913448747683114811087695908672281983216580893\
-989791978479361426423154704707856722483900461991383768431377835492451671088566\
-402906731617889554550509946803275878956545136593551648543501764468415173826716\
-286810028888531754058160231667492322941397287414387939348944651288577
-
-399648904301305407243168499163086675249820845649954541030632948640521509337249\
-518062349794850003473794417490954092804728902981441979285046797446149277621271\
-025935893912791184765024085808602807787002514454105819243938699450904397538083\
-483396562149246578904138368413930002406095245399520389747251295263436338908153\
-453024660062003950059998323371448244783538476060131682703941973751178501120114\
-713043014876998498151130122465068000031699023906014928856478796775074169038757\
-991490689419232189727811716843502108257493128356801701883751885615388022102294\
-169028479113473602129270538171567348393261631156268104956711029597175085276273\
-821816283713273108393623388442018527469659585434357789745205098694097111555263\
-774186068795490972835013622847487146464167763390874860832021649360281586885655\
-0014582768:\
-399655002459635199071389930092979514358846645155128566692954915815948872844277\
-023763440522357648761843074303393208946619126993313187383802070191451584999066\
-686094501621637296494533533340607044391439977265773475793890056939140065164714\
-701691089951169045788257979546599266201053041974074433172294687625106800034420\
-030299528038823082331640016646800135936139414584909702973839139307765443580249\
-752097555989542377988110062752066918619463983090554282902179617405052078963843\
-432344304368908692768228196922592037699919749750415831782745691574083454410749\
-397284038356504467314298966151872011068504394109295907711561391361246095020006\
-728959248235185652000860657860724095736526534630489648085019834715063594164510\
-583190728461866020390942080398956085019169176370876370386025248406076852228051\
-2463568895:\
-774319763994244712903939294640612684263073289917054586771047667788873895370173\
-678313771307890493526768169358638695566162505104613000898318729230110299269947\
-611497593209360168812334480025348862048385305379000517248382621114567331809057\
-791285179760479852604979072574337452248902545999570172262980854792258748510569\
-525260679229216433703721192669134338547391035634019056678867719525610728209791\
-171121881865460370818807632646982458052498819097773443818981374965169244722963\
-849801649963457593032873196699405742946044291370921634472703518894049476728691\
-684735401434759912697588932090108629772151995583343998916848959552165277641641\
-627269927808349021219953166604324416757041659397868768722273963337048313725952\
-553929475645396869362446552865156720028553101440863494200149695831181758727519\
-2585945088:\
-152136865815250045155953875978339576654182300717992523362295785126199313042200\
-144396831342916118401590510589578632731557791050635044771714319899392919209099\
-007994881086971413132367082998899638778871489669374041560682889101305859736162\
-853657825067011259913860316187097548191151520724433104213416119566385307292215\
-753732584318986886964168293078572224329861326926802300565282892179813138043462\
-923759144977878641034458324319098216639568371952311815972270940099642517109675\
-117684477862870300730308985124331013246105617423060525344662613718998029912165\
-222329808954922913753395625677566876933500452677671132488360300260114186351273\
-559855236251983954547845614296450542559283481594776789685023013664381485874185\
-570152599835207541287207338505999818015146431472088538657102472704087441105277\
-0013478912
-
-742981653399231356818063033694358480459881680940755083045954376886271778917854\
-258047493188413885795021324460587967727153640601646581020943404709452930067233\
-699863137463354174992762107613084050778151229239563933546078703082223391814120\
-089863798358010292257245698346707132724536900216115472187942575584903307521065\
-694373488496706960898879903034834463967658714598567569919260442186877433403409\
-500681278734725593204618140331652229575317732306029792140037358391736935462350\
-970638890401256686106155189010423717371173699299761541434254014258878970873149\
-187808075410939013401432216597613393656991522027736710802284951314498559471911\
-431210539367333566955579416184240300176421727343168944330878331201229260135650\
-443788990393548497519544151211718388897230201521575531129401232805906201879159\
-19608837734030785644660260862:\
-829374868567474094839286444522972159204988261265205566118417522410098188651792\
-568663894451365137928227999410891464821181838825245736915548018756111800066178\
-919687487225064017654867750164557332752566178338382718652736166642980470999835\
-925780396068713046401264953247488954361644749861563496840167847866445547220207\
-052254587473135409026589864920211227479866861778888920281529797639858764703482\
-415038179019188454396183921634692072169852409505013102892388017337688742007830\
-708931540208063776061658762382635496208948752812660093002207462678531004712112\
-359418718682914290715896900508495723211964499077938285182261735074576074257500\
-305165609196196930151744448253912845358679380609268320894986819433427806426161\
-162149549798904099667309236898074594895319190720135103928792767188784691827476\
-98343712547016070896302424064:\
-146292511599542768356031313638703406156631860089759245583856433125364247582708\
-113773847224352702095960520412214868578685298534177785334100138894066707778001\
-886249648844911165211077018505757127099376467127613112004886189108108474154299\
-443219004987350451243292741854216553800863404615365716546877165311760675874475\
-434540863630329878288999047925779532008175918374087070555573080484657102231183\
-066100314684193829972281357689585928534076573894340488656990038296741480111330\
-908682072010187952010854942660823221788978803110051783234634502405444492771211\
-217914462856775871633215469278529853331088739722739380298396597022300638166872\
-831969724714412316437214119367853279032082290521569169036889437909868221858136\
-939217212573790272233636167757646943841196254162044208312014500035173664548541\
-654089820108597317119403622400:\
-150408226598761910787442654562959567373808026283342607889576291752386978876250\
-102602684348134796149274304978096155403470389785479769255388707142346445401836\
-654005941393150840810114995348032107408656605545388431361290229609685029568338\
-494715174063330050905314258615684528964589603735994682857867470137990455381790\
-454242441942937105584852969205872744819219461630964053745021272461605880948652\
-303841345618823752075571637112132783130133063313585598723994106251752723039991\
-014507309812676296900834757573081882791029377887442029842880022280822567047112\
-617642257120745935919726975315737827155551433289076107843422346351193709727086\
-784832455183466854251044296952695097638862236734868788036428461530440373368317\
-585895047003443260890225222768784935306062559358345264657948775851306603081917\
-24487480208074598202145243136
-
-647834534693645062848966542468118075586273508940482298645337097230360448276337\
-328013577785839564834654364557922429073145491154417748668174153821983510035201\
-224215380857795009567862899042632889996007985583508327885275745800803153812147\
-273521787019573794665606965021040606393538346993531070089054948344779986630539\
-385987887370641316734720767392060683189894783661736055392298714369519578381688\
-604012435454676950623040538815474552300597527534325398778321659684507705895674\
-539168738701375837293106023096542183318658120047516494779733243403345974853430\
-440356526019459130777519772361166133489925486565087840958562279814541165583608\
-425720472910109187454440871447309010924062401955852209293168162739010930850122\
-644885508868848346938425524124562346699849444912135747261940234092269564760434\
-960385533161995315093415258061492417720321:\
-424979559001764707386151881708527182591761374285327429188167377222865434985654\
-430001692530250814336224215427840806961610670816697378817096697515528765819787\
-098257055111250197547912890572479293439267885946776335863373065798726967204564\
-734362942376718225455897689417717590660962078393960022247331979541571555845061\
-822925646212145057489712819348486474125555442113656117399267630612054267942981\
-242094774219745775472544762835968512179364169053114120215959151599735129389929\
-035021901442337555922357065957498912346522271574702346463686398788969851213924\
-258284901812442815282088450457813753027004299664194519270651809754825940294077\
-793047410226100058692810448341979474313541344237710057809405396646594884173081\
-264496715149621528367624811079985474287166280358767146007868763851197628622662\
-22323442289294883906874854064232678266056474625:\
-135993475093031502629533621866117129285243929347039271828438941221898452876341\
-241101175905096630748446752331663415024874739757518702647113966338218533263694\
-958324445176003077498433111004113154836809954828641528518085915424120239837613\
-354531045006080893950724046150633298098530274515300172567771275682632725034107\
-241498997264578280282110972516937472297377455685458069899812667802866679379473\
-424556271396514762051706828851605831791237263742472750183227753166868543457829\
-037148860774048528160181523103252688126521568436101184199517252543074313420395\
-680283676335818649927888415868260783145395352666725912938277381377955516621573\
-944218427911690805763904462923926672592772062205197847405796240887346036807349\
-002585347534709508103750858684195442163479748937514612339428497667162592867353\
-1490629143948823007705955836917431631765112356863:\
-356833633926161673239649317596766982274779555794478967705140752259409221292502\
-323681767307067163689633659479127128258065300826588529675337476551577059959053\
-322240717578807428375285589676869637620635301113031224643183081610893898819972\
-321257605466848693651165728214101450252866448162503650842992232554995019132229\
-334715503962153252451466284814858455160451945668429701023642518690603710998677\
-363954688789101158545244921316063047578829303119483519141891830626615238047895\
-015243453177623888406183642338685469516381625742789371060807550180061379032677\
-156778410378314515304145160403112965314642697945528831080706082092004000851500\
-647049076558163140312916571702513594261727978586806828887140652877510243202897\
-339534788063714450178748996487293990533977462379780400551241602866133497266560\
-097045416298082176105251314070617841200305900387
-
-486048445765488583377208845066515335251419826715506418890325168301357087697092\
-050055164454099214724606936203921317725187679893287519506949715881517862387400\
-026067911616391079326242773463754850808915931017080497535430066715175435326510\
-918222818797483335302537185407476950015814825229378785902371026959670528310227\
-034891760247307053345239334695815673043914103232741345028612611705174259261204\
-070763084269536692129487079309378984982127438403433814193408377529133618479079\
-392161343507793090911665068011001763048758367605524995387387580082888204057678\
-268943517851852720406719398469100321562970666627278849505718035540460931327751\
-481543813459285125074917381454778867155615061009006439742030392447139138996584\
-880783871556426147316086727624147084789574777177570043083122093046562486130308\
-64324733100467590590830072745766787105267054951211731805281997291519:\
-493887876050974717247045971916451330752629026580494120368124734488562854353407\
-323706194967504578874336853375454116266733771584632971760646474924664978022135\
-507486688729745294831080935555674404850694151221350747799289502148172925399343\
-534115429759707772910104217038918964435966696911982991594435633641300889763480\
-591527518118322578724934264215913268612184964235112757003001121771434663382285\
-992803190418265309432510813171756905706336019108364190432386309859643007027779\
-433674397481096181939851496083157603489119882947869519830782964160182194349759\
-805689218372483487611658123065223416648558591992729831498497139790675528605964\
-114807460554457910712291128449044200618674420101649858081857117979221330353395\
-893326494531610607249765530491857997752520865051482061641639631048579744445622\
-13099391100311875200083978593181139796770817165532721051967812534273:\
-501727366132419746560475697115109664259492380716114086462757344048631935828355\
-817079719019360482122114499900702836750605251560195583638053921674881209922956\
-802758789191558672516125206945587187971366709736323437320179000337610870910542\
-095546658482222814072426822713558635239411372128958618843736711148900723500334\
-602044951651759272850128925181646496829185295580841369572173199044930530675504\
-245091249388699815782529011654360789854787223170172868028632613308021552037584\
-971697532634820055301277943936723347893309349227193461498900951516120486851472\
-838156591375006102465825021769692418887496103573946225537114242438170008859868\
-228049306934745264891502155744158325357984973604032591087212203205596276021067\
-102091007754067336823854884852108577310129903733887529937067575109567536303038\
-96069930286611903150298410058853905451808850351998778372592125345728:\
-197255501810134466527763121418063065290290022369219487833295059537429337101189\
-783044175591353593062077175481267129854986283098700760325035876354445070947793\
-058914697030684503632373000359897949087848219409533770124680481080225742545585\
-001264761479203309653301922843981712229172043165392269421568541833342916317000\
-431426769244194972083689522924425943882388425693361949205142118058339661265928\
-420468862287502392063931445553953558252617038417114625507952241035841547410514\
-394005883910781839207458352346014901000953417864549874454663348884848145565578\
-199593520223446654381035611119886686031817474103111527201662428603960618821632\
-937407936357524153023755302046302905773264370856644700208433841509056781555411\
-660188917900123652089716016560204666296352463488770031009697451516218483009641\
-82483010579458536066467424146201741423392734933194874192670766237631
-
-462761815904527247374371237881906779526209862691907173314485351687179809737722\
-931345308257495242463421293615351828538758186207268802798396373957165121523626\
-789875911805919063570708744918346529494870821528785305946867530876763356289183\
-020878512229850175444403397600236269241256121163159010557690004980364349927674\
-266628786610838462595542349210571478560306255425427580426313260244566871980314\
-778994691977986375810088905663917302318268129493934426093096005634357202982303\
-341973578728279937462400151270546916937907448334706322844376022068302207116976\
-975635726333381348311458411382095946880635668862121018217928578604974240727573\
-009938358386555995625898873391116629670531374874957657656053702029266863704529\
-183558279217169922152375055754169192057473646476815170172130362849017361505131\
-025100328311173700259394677245864989602860951689529969421821397767673840247211\
-076616192:\
-462761815905365718090264628943789111251245167780049156594066961600199213190186\
-990761433365703851489931654015525797206435744719053290202394165476834746447123\
-980799553499722965385226051119686309818777182319644972792901186416371226831460\
-036054466590141298536744156561235976224419933838581653186230666476066023843718\
-510489528520292393460554947658083722330550484669593877556727464060520374820215\
-792000273606151349856052385153086687104303800275392179543069519854086704029149\
-984751007903086215801148877951286153987793964765364727813177735845582222311790\
-083581426923417465712185651789393217147435036249858292520250580421675456143276\
-630010116061872750769276564528146875763629566422737982058916516747849759486929\
-983989874250741728811284202984071146582260090610444531549134818517659678264777\
-746542888025358444872665560128783707796803442119327576529884831282832682119403\
-428446207:\
-923715968479137369163724436587585531532138213080945884468747213427978838918940\
-350443957223240941731462470474292071939192179634746320649724244791514007954295\
-343065110737097544949096279769681825486885363942429235166655119118604772287306\
-647445785153266771593435740782510116343093335165900999271694884879992233946961\
-624257130612964862830380758139758424257874601828542900384367674952506989202075\
-688178948485881389532443742775324045494775140444272404692439312706758441142184\
-616717776946954879990106492809409557692412067367188095566519045820448544228694\
-046470185544854422351811987268400889046084021317615584844085537061429328271976\
-018445635181209137796749918224089008044981599793228052594754345467056201455209\
-273180726384107537172994000078965799738920376739886078918750406122677073849494\
-023151324437008173419839375345567084360772328017074342879281699318086591260574\
-330518015:\
-722197356712037968122082195084631955687391974019929557198336858595392352627851\
-624715317903792423347015969361357553554769958766775707129814706258283458363798\
-704380607891443558952153774460345989687269560617738649201538474275570240482879\
-982370319091359653068788782184060550409745861229925602130886505686858151334677\
-234096604770597181498342892806434528893583750409622849168291341326035281721134\
-108938415327271387323731732259327426638516200037624821519501177150284883644116\
-602739470796221235703172941126273090616938727714655644097429880496567136847390\
-134711274970570860530966589057648612414413205563559114850131079235219907285745\
-522873325314623797527364721545570049746034323598484653341278579018734530904263\
-714962407888543184422128317514111812392169545132004684759799167092760035192165\
-143166666115350364206261836159112613633415120657427726513034583501885635242774\
-361676663
-
-852811240930917223716049700526055613310065325119410058273112841436173360389827\
-067600484597223592991489500301544412787608717657243183136933723030960499287961\
-180025805774535487472563698724649758571994979476521995282764349617515507339212\
-390599614045320387124877690667704170677140753880657675339809779909400894718137\
-604565854068470666832821593720551120853788490719824723593486587417222862684339\
-754433092850322556821622697344956887315924441780551414646763476811380389708531\
-753799326501114473171619525026547514448670363066644421017097413651564492593345\
-710519780675010742282886385080136359126471299991442756499680559269443950089997\
-798993542734822643160468572997180443964796467127430280656370432920766639078783\
-383559044567705679554288431235966912349185786572977030673184808055428417987655\
-917781167699794495514613317627762473374773116773977669528857170381839162700473\
-3270732096123644745048129056:\
-126185872261197230408785663078922613161955140827437502882718420027808646238493\
-787908909280295706915391344489678452391660180283082458553427428163567180851284\
-178414018437405329890385103605154102498924000147488288284768256431559436041069\
-145421094694428161753420072068389804255427680272205597683662873202026439502631\
-734404464774307421558224534489546863066233203479241736440781995791474856095838\
-269763759746717486811395066763383870576787904155415267764612635532467529605024\
-113578327813470451874837744405067387480491480674175950848338621132678697997473\
-231117847088919311534747594400514652223311092878351252315701789901426818100639\
-743458465831157999119023434005364674468180708937869307611770319238915718847174\
-443278769013419185628763247874874396573501766307940543298823915933595852178284\
-465051877197401039659156615481644405619173735595577659109290562579711724206886\
-228782624859173378064385:\
-853644878507584787725369781669211068013646036362792638671328081894540983566741\
-315340551128910068548346356307471316689509830314874104502824264923218962086029\
-594246918895715681697925329851367503055795117471451494533345154635216019808056\
-754332930337780097383866110492520542077488588004465726128141641500315486683197\
-075493597127544845509255220792452407533582871024031042223500130390318245548410\
-961386224468250971607581283215625738690213912411090551681753953384716961723633\
-970402516643015557682529478419228790638718769371240885850375637418127904946605\
-668979359702307723940424981607363068171212992098758183458079952429621843459294\
-616351675289095984517856562453241375418956622374813841018827909335236757473533\
-195891180589871263189636855365039600202321493523286253000780709318779395720875\
-725449007860631208557413853152750990804594625081373893725629633059436480731455\
-4720709619653726583942807551:\
-571419833968933968780282928116747017917747733267187012898009681162516457608558\
-529800774770535181263584711491636995016961706591180889255596876575502233274916\
-526701780138152631912358862350749345652961733415414869269691880092743157597094\
-781310891352846390995934685218465489638725549657131114228325051886693698728606\
-582807308857903512489180917892285184120167459998926127628926286674812011523196\
-764826460756220369911422884881080207086599164396548130143663970750660186146145\
-162758410665922759565495800804872879965340041290955113277172106045966354647531\
-447742509540632870301435509427148076652025696773164565347983110644984662895211\
-898510593007836353873250473884275094142598972095152878728883104457950224619531\
-660754936816660726177705116666517604032722323342912680646311072522068638542498\
-602982458767653696638914403227284963287902348793853455664160463486054732892279\
-0437174424639791607643532979
-
-314804515107169253740988787564344743726371959907909986530733863976724456680313\
-996781489506686118596980242139912480973309314021838218548009298502905903798586\
-222682229349642577347490292285852490868370515350185388270830622046913974607961\
-008615109482340511856271142022898165642704974987179359034662759456885366695261\
-984774100970018053496216064206597760917739999870797275773847491336444219253241\
-465784827530729563643315024450014903204787864206742316796836747541109807997308\
-132602220405394657654320488171038695432220218839910434079702926197096278513500\
-717508987229351250252299272953987103763082900862891141630821972740832384617516\
-755802815053267049931210868380823069430645565358287150885227586948004972953278\
-525063339050094956405808328198168324001397720036736569171977198705397054825962\
-628632438635567872328817776845167551772686511034212695170736509715121636698584\
-945275639778914931647999718261952911164177350911:\
-157479297222944249861852791825730868428836544111522964151303023237017930749056\
-463120653861483042305611136447592894272434689747708939043321458827314030644357\
-342985486063752425472815250804610501606778706778886418586106059162683956810468\
-474441855585198366560350065692491813044476114769947511588935311622688326938158\
-980347134639621897235154278272705896829547627482982898566012996979583678894582\
-258214856868080975639461127459000147008501310596305911097723077384088864192838\
-127774607944001723826486861833544537206990960463703031475185136355798749852343\
-311708987822354831505793815190636225699728178417072780700389217551158684995495\
-398728026369441053088536594153149277238840378967494393598061176839628882296503\
-795464957990933163611487278037497137657977556563151170019840024822868265944419\
-592409077738048941857981926128411741213928755885294130222862629407509811640660\
-475615424360750145199809728518380752105765863423:\
-314934566479800090395800630582404683588882769850638147321908183392900499940478\
-711826765070664796051025929484174098344648790954303331399702083310348416189537\
-951271722950873255271484386142156748674606402037193726006995009474573463503846\
-366688495785381924934203123185936197223479061885022038982088821004595778755622\
-272579944109442284961814721978014283787368114529033454365196742612856882267911\
-867329529708527147581875685018067791183873594323619250118494771887245697922755\
-871573431959624219013664847917010441644464090171750723676535531693140158410205\
-250853526107289986726019109193894273884736753829782032523695039159909806471287\
-404948324668932861254789659433949959036844394547090376182188036838546074091483\
-526568813624543721497224251136840963710836493784649855958180292451605871787391\
-635146031158112879553281546410699048715448251524587514809150992040080432214899\
-116055841254393452230243614338291315183919824894:\
-235102202318388747686659165837007820879308762457981192430370983607809347274551\
-061782150140306067420319122473827155441904550381829285177777849856696886284492\
-601978143041094170470029007945125773944540494486009337679403599297936415071858\
-516861784075771605519965707790566093287679794349976469655292864473738885310357\
-259696318828604649024037320228463161532477452061792338452353394168553863483489\
-225130902083463266110007488259260939020481245136895118972793293637553341402461\
-162248103674418941581677139531413062427969665937757913571882705672371243332607\
-456470701445745359847663767598740174838821198442860522142523836965671913699479\
-800190472428927299043323353339916376058248776218929027726139670048776863089773\
-948516022857979492863833562765275733331992836456902089802561070702629083095999\
-605228216486519535202901673989395374979465755494937749558252302610157607052813\
-402194421037533391989263017241560413881096872325
-
-290480299768498935136309295999873544407915464943400600039954272905588149923387\
-510357340485916145562954547158474841314612927265333901443335454794329247863049\
-177079398995327798879263258721537968694018587728829010899440236608024943146179\
-772594813223182898860671803813591651379854471613088661546185488996456120752039\
-639859487361722995647357317646050797538251169600705221381087174308456545232079\
-659190502086294993072010812156295264617373783953828184816455894260978809278843\
-758491284533534557127500537681626354100058943588164530302778157140688561547980\
-992000192006256050932850885871047127232926654761006877967573457228435629672911\
-293503981193083585947803819082083572999460719205767101939543957566569186380678\
-663953550007104394150723443962592816029104595317690792822828902146617944490188\
-893708687919694876126757447720063362745303421781825759257442697203068682892806\
-9375962000311861830922601152391711976682453697434291794619771387903:\
-145242366064604835818125284569375964967810955759865170539800768531314398793100\
-549912225743327677010552329433859758604413008767934359685746071149150491177427\
-541069271191340057823685358925076162020370848491370281180497432744363321899563\
-015258826807960996815486236535271298494296605639157023124476301892743814057341\
-442838059536172476192051816662388015995683188560785951473147101050495279827861\
-827523873641572678008952097298124111441464484359210951847742953415341876758797\
-008454047030540570128756352994472777513633143604516497768973759875201028863495\
-909540694351152599470217432744142291836102335770926775336010279257179140415532\
-635197055309986976958014463229454096481572318522349236115985647969752650797617\
-276979235794539088061329076052674841388578290536254495453521843766832334497236\
-641842867905935528910848500012024334122152654152649482130042100975709083917581\
-0970291401493977632927253885799189849233384239238079553716956954624:\
-435718233472390454471157883156197757738592005846272102449137108457634282063333\
-857709496748758717067221745634531129210951619997028462122131903376244132244486\
-324077021200804554149281407322876300843352730771540348029111182493537804745847\
-105879909902614965210893220753582265918189720475316898045057222835885653331597\
-611874566923321440768627184002286847688939831001005714064321117631852926648654\
-639658191802934549719271531552982603378838974583022685736478350966661549071779\
-017093552474024007896103087746260942963755792078516945395130434726694684679746\
-480284040227982052483373978310378433077947475251874329526031477847236662553422\
-129002848085158696081737229181943101139575392669794858739870569378276314998447\
-688898323822802189258021859549745377666875918132664123403981482359913030931773\
-496427558522984662260837409623920281323467247988487097235987209798850866533603\
-5265014535784677310338175176445581932767497518722031017005200441344:\
-241032897071759339841297482170069216829532398029341334811591631593624780479624\
-895310231870289957958771422704911870256024327331837245189800401483769817458704\
-475330277085503330060479583454783738351187390303843435454487949681256694519544\
-326708135183919797645127705333358221229565748387826255259855966168496698503649\
-518358981396374508873537641472737639014837971951461696809370378137660681638936\
-180758997554595846002220656152614786629370469042283296519989379256600596056409\
-523156759491546078028941853135584142831468881383773793213120717964291067060977\
-560324912830307218201706390719478223124279750279375766614900688671409312308702\
-682578231190872575958147208752080792355405689661801007677234693988842424250514\
-596102236908600103216133921572893445870511571454065749081585224490842823455345\
-709508691281473460372681286654122910836150367289191675109237629112890769339492\
-3865951135347065139483093125111917391451301319509607010747348418561
-
-535845151956824308903875962473938970603880770165624098239831034079687485086726\
-155527002415890160510243417908154624295350102255793276591307691359481831468017\
-162155252181252767931535400063801551100662252851137375206603279982354130288532\
-565367236611175006158624744129460889184585401933934954816702571175226840820100\
-973696848397062764715788613933890842779403559178141020089231319859014200317134\
-562935387633026762519990650466786842093846495979552582856681652606837487800681\
-918890463375363085591091635594953947632180408589315057421756479406442183295542\
-825969881336044153537960992977129781673131586035498793093561740749304461047657\
-668750394188631917800307537367465919828253198483959320999995993819603170763557\
-685615280137426763464534057998617887154756141003787925036713387831297032690683\
-547272969560795684206542395862339262585938257024463571347102307846136756370316\
-243620033744452383708727823522350945403788452698126550770756181562819017176967\
-03627264:\
-535842085846738849817302393134318844432416424639723748060473783547852235181188\
-779114541607043960318877876082749046403808619285885776443374298617682732758486\
-039305462231560781629138737458322628511768820367336788790875307551967526093712\
-905513655081961958538510242100809381179448460073785761354707246737557552636901\
-562266514150391554825719701695419546172371136493043234117977513567764033842305\
-323685656209608389846945827943829182627347016465456385364072604143472072164495\
-292008430946136753917375430403908299622487090158914292768618766526816514797360\
-207285750449187208783552324067827879882719768503322692745713466159056792497037\
-510282894599078058030772244677916040025793009050274490213763022580407550172624\
-082278349335325004184170905593857212329261928358135274976427243742450852297038\
-750136462670173875092969241634489198270065964851364841109738596264017330858608\
-498905123368153324549490350776089339588082927644358808026914941542038748848508\
-36045824:\
-537934577227395072475585414092578420425236294691696410882859450678426713415007\
-623118785630096617855672384345013193698425850064098524117095069024501162187594\
-187411954215605692268550352698559025747683356286200421273157124094223492277718\
-780476115222525206286672294043511737957919706673276860640713028594402109826350\
-942563780147356441387809415746355333538925850899554981296614427261219088823101\
-763746454488553565788877417867803793197480801090708646941914337560044490377548\
-443947393023297120945211971853462621978806090223082601418991524926979861640423\
-495652782406472569733273567283018024956290467843462272145127890463853664911468\
-760164434428388755731374648199145165241965981468743155571250566222740714352598\
-968902004471668552181551699541161869612152558077339068788892446212702544203801\
-051206659519267205982455642111982090558650955706376774629619639552956516085986\
-846273887903711270753530051951176535404208539358050530879381142310931209459651\
-93232383:\
-434615995036145418876996071603109840028298157220070558756101719914392082121110\
-243768028728037754051998675767000433196585131533330653284673203425318072727121\
-807081294860851669567425125888183512740366128591873724137292713040229671896143\
-884361842269716737158468795685452239756524671138726273358881680997422384176375\
-848292260647858426833036681621357457684017612614708004917225052053573516391149\
-318301431692622379411539475201731897231886080919189723789251867346383166473021\
-145899600690198608363985986903753081034679441929618960792537425730781536566062\
-946694837120830881381871753096502084379048619484113258343337616993812330036567\
-808143433953058839350009432428104019400827123688426871664505952774735696967720\
-381153507549248445913784366046509185758189872026275712832326931622494065789908\
-101237062612792315658852693483723790326395754931103455361237224358686796816728\
-224022077855176537190464043947058205052713501004952100160335163199948293965733\
-65183097
-
-196929730754513492008178390902247410630104493232010836746897527504893735260293\
-095151258384814981618522499920387777380436517983780057829824478705425873256077\
-933218674297167149248490663093379662736538278557013712288277184632113840932838\
-766122108698637125879083876028819479967457358845926633356338151866507612899859\
-774821030974666821097730641681518770895322668829072030610880250231215722211654\
-708460175817661939211689633581185755789284817278848733189236737237129615892915\
-216574720152960046304995338208622168688621045029698986691349095020239550375233\
-870321254008972062667942216148084448387435418841304018598658874235847841867222\
-013949775504624916918066318396784660602521304299160610922782783267219191621119\
-617020677517528452907811356182327606741913783755861708068183180143821596432157\
-328919089970449209042138174982864438663908082986283154895164125160322312430206\
-518375153695647741405828907406003794528335287326115514596624385665486989610949\
-9690666148260610767071475712:\
-123556654936410249602049549191499088534083656020240291647845259378211174962321\
-984522563124569495749565894947477543753194755891782370392196103711751556995175\
-031809956819238077083962790454727231990786168380834972245277387723903697209826\
-756814441181233008136458192383122718743160900036652714114280495156362269920249\
-626150513016137320577335254478080238794312061285861330791735163268317548593135\
-983932311524810248852259336161047123492256330659010452079487278323645489109977\
-237116633605762246590757123475180297115284646213168055277478325498278373840041\
-970992880400414698675318432068009711150245528911625026605727429269798649368122\
-333878115582436421783479673383548902261254731291609556378660400400774462493319\
-788437617794138959367959510462313014600803345984745301590931290165978769517594\
-768150405501575952022887097979944691253339527717949550645531700415678162368321\
-227992557930414974792780035237486800590514288868807870443325996919606099419607\
-5428888052657776335727493119:\
-197690647898256050939797027570635363670565608664381877560834129631505436769752\
-681004892256000448647844239974283716630421231527399882946715301822734177527313\
-579496062684344107965100871983067750860051300758022226312246197136463949901512\
-873512942725466496953059752095564894064492811931276262685149270733111838603563\
-555006947437029907829102932104107526234239093101632809134694179801451663197266\
-903338627301826850237586720858398240382479144022284512205267266998241755277260\
-763076435183169004388315148786347001309722521277645503850332663094916197673391\
-718082067677487212592534748916358752345083767279503501703497845811147809701209\
-690204146718682290277864237894328158658735889072006088128915571074857462135289\
-130632532443580462643314540707408547215793145195101986238733023483997640009114\
-904589359227563180865181953196727842454231330597071466222822300160135986356734\
-052630494567290920148679365196799288170540652204729225972969155011488930891525\
-8550583162748055955678691329:\
-194794295808570105812154845832036432928623596915565746417009271119094077259505\
-053528210005969153139881457258901495885683518874037578661071846057912985262593\
-316113905830128468115173665741269223477371577106364664414801251852384402750966\
-879021386134525525067966591755044698898614908919135506972061493269249379721720\
-603373823646928410172942900031035527387622218702588984072144813972316507914537\
-031894445106490654930154141283916335133427010011700632825688998913135987175709\
-451393668479972849543785638779706855557750501438689358753727020672268580218791\
-350503528829958819633394832907134882933021989102364770668056310102959525402808\
-015420988236024745507075693391761784217377916642702134887719735355155217036861\
-646051595316011096807083242430369721376504100797849285627155619265413283404597\
-142768409015462194484398690335257131009014617272350096411657327528415936093868\
-573431960078431497051048296223528169718593307374410294979088070559054899051627\
-8646279735219973189096570037
-
-364674873320417134403673422912483517103680570819380209118217153729167829938514\
-654084973244562743588635837451028559626397875806676713653269696253940764442974\
-270458711885013051451597838047657179644972694391351470528158400417558181453413\
-269502455208700499232678603660580879444746888369470321749113175207116153873335\
-295360998148033762848484698546055445679424156126118347970252621076823425798782\
-453918541706131405831833124128254709803882945681214817959454731628665554054033\
-934545707117436007783752075452934717068789840538545492895770820483855031767239\
-835779790032668213041943750069984200816206468016517447836848581669296852479769\
-274518280917745566326722919334154661075958644803247730469363136372870517648512\
-000748546071317433652171959039886081692716928013639178700071213333429805520082\
-565396388793792518280575440058507986024722316590883229198493430921929282235934\
-049401525438601502565789906474906260231669443333464997680021692739533262463603\
-39798632198371401787129633463200020720875732992:\
-182337439377248143035636297540008057220123763990284826169219347638492844403143\
-666638277023150746509062353431430202052001080618333569438559536026598621741667\
-053358669815063417525556000337190043726278186662731274449183799680597941231728\
-691290666419751108373243757986486056221551827783457504812386137585365628606830\
-636791795071388413560146977478633723351542223490732970694381283132766649714673\
-739519822511180153478231807809148943442660632348898642543106119985173411846342\
-565954204185805614285056503167006919558784569088391512992248949000056485389773\
-124399339770915443555002132303504645717767090741909389178111541685692341422759\
-246210133073088071100405630857773120500986725162880587543499875572206208966862\
-974199917987891092218385244268668199350223535439793378422041027975952335161108\
-241014623455653692353675841875500378951985276522924699450005843510400937479141\
-896627877871507721751293097427863036691707784175310453198244686854623764562192\
-89006450892048345527516143948915177843738279935:\
-364674878754496124123093837417537796455099439028741522551058545273109556022556\
-231048967376149941923244744075844599533402019088705286037700826522670522096023\
-052076765281162924198835054730281989723425104136910803155052097391883179457959\
-486524340277256884828065314213865992999582164555392060592286351529795089513055\
-703086700574423740140469805208883572083879705693948013306736961590314213214775\
-512266773377491233599755045823820144875539416033053002900300209047366377340107\
-765356812051402416584201397114091342066727772039285554536581164374106294216325\
-679770619632812812566957807469978941276229079562207399589161627225202002827155\
-776206266083904819156046461096051102075486434499168971954300603184302086687173\
-742484675473407296629255897053808319429294811070072941125231960468358708960591\
-765727471305918561961773329919846159337942999536250839093468959203091644562262\
-977918032698616283492032173793576338961482001382755876249536987777639912211640\
-83091358892889451602007828595824368344165777159:\
-234275931568662209569785646184582488338584204381712875387163610562872257213031\
-745755563068733540005158674253149464343270071961839232808242778622094941486824\
-719851648165829521776355123615033557237270400097205445510457042496680404618118\
-554317033974213816431705928870141300121134507110546264148055146456260853616775\
-675799618380796973323987500787611552056774731718035702598900192252173820173717\
-904208484948440556834510592164911092621757019345328166701507246534340354231436\
-892405331256250684142214768962770763089510014638093762520123642744997801074754\
-738870362172196795597846524707029183108218828569581724347278597411130695310335\
-666351327919161490002101668894799708108441860422654281936614087970571165704094\
-692759205535654842911739981645056546406021092951768211657569469052947610747867\
-691220487138091720155805263796190880510935930544537377439081509444130206089973\
-243684567943257357666905522482325175926545393345943724611425835968476624907633\
-7919768055264810728665014210582280639544035866
-
-325842170490290705748187269523610715230962413284573236635671173434987387663619\
-234443576263008534616164006858082884291775542385965435808750763661463874179742\
-210396474861456423041358976425492646789927976304091182734783611017743993202516\
-131170018741908051271023784794909337780076007257589528376111645586504408348018\
-339612426269666169458956053971866159625046372280082083728364973332113317999234\
-567170250802756878937142666970169539760142236694794526536571075957313110352410\
-555306101131526052657751368868999897178980981751645911999241386636278067124297\
-580834242446866921016065874491098143338574576533090124772585986300537234846424\
-771988838775175487611053475616274804334041384768158393857556259650057287627312\
-279376068440741840721592593393862006311704720764284318659619191918088817688667\
-697355333567434117576856982712419166229557461584320401433232789459813408836604\
-698254202336424249354175194955597369659701155574857549423694800673978576815566\
-794368398019186147733540918254963175426276854731273060109542096893:\
-336394266665964435093090916568824017327250721673286439742589667885478896720648\
-129645707730771000170829903315785170329559588751383640689871844505371199464382\
-638749662715299957973142863734878534933446573944790663882964066472306886192325\
-093970823234711350886415064015702568744255032614495621463115647333466919971055\
-072096427639300518367897426682705816830582715710594657960907975795468526813766\
-782718503410689905214204005887758743302798798735860523753038356866395610268066\
-969564518223914302099199074635310973020336244165922081798012778983777744053242\
-585928681082884011145627125158831036193515035319106877183308250328467448966482\
-904609102101202473574537194938114039605876694640837252622628585213375649332797\
-893054920989450475112769282759866253385077082475877309928952642707200011531577\
-292325563870801986668661546284568653777453210223867323599299732370199209633977\
-970088233488715105791002340089502196818968601051765180367562642478321162779819\
-872712881942411292656696080142635697497469465010173981795672915968:\
-346864245359158180058741467214421019036103728822169676892848521463662094746372\
-802550254361773414593052492400764699042063436380740707867096468679605152164869\
-799670663738732997016984446485285192031248782094341985075569145236536677563931\
-989385792384304039151939213031322341894595665284523631944405283772900891555679\
-097829316118044068954042759412115729874847497884883657825207707787743770398649\
-254916856186341364088011154403809442610703926030427892488247905484346839703795\
-141192334556209176530207156717860759136275707014836246519274972750982423441100\
-163890520166203552981446445376613449081470405381446884728055784244201127943066\
-422181906688081132221491110875927500319606301722464949170945987499100531748816\
-511290326430761171708452730224428721348288730408789483417799619425089538613151\
-977957031934020332109751598314463826084649537057546895638452585141286598249494\
-888666057364495825449649990598271098186201031993411666416627692107259850678535\
-095233281312443913870067001402541636318648322065095143626337288195:\
-209411333382565638138648783814173782052077835484550279461214316574619294882300\
-106398896344394220282595575798256848119894806756327704337500260469040544408346\
-452975425240871695380472667976160756329929377794786592915321228283714404372290\
-986199569710059922789315815907515450834733325717436824712841221293917479967910\
-565999941239969857755329626565526091801408460975615513369425319829107597870199\
-009590615974480308871586134732678347584209361841418765285548169794044146523984\
-597361937427866471589507542395636465054820659422778992512998174454590527387409\
-959894928541695910177114795274215715011876210510453804786245240115093566842821\
-044702403990475687998199163007705171272373112450593323027472382496066011540526\
-818090971167008407232012009374078459758539911686738860780090117860862044581404\
-857542105962507172036591248504271630930110333712617282048061030103118243599690\
-244353936073940167837188396611513926683769060778405595594189246719493147963771\
-585272425370343059241812465766626263037383448946247774922995538456
-
-302959747450036387459894540235123971636233736081735225560103365199931874441130\
-028687844971235610936970397848406726190769677830014746268012196736101817081349\
-656655601763492235118245233981092827403053301561012707235399947855537227702673\
-115080193923405716924638051038778482672171811407158883251558505892377010455710\
-319990655264520998342215169193426050947066264799022089709463361911581991634132\
-236235181015365022124273668392673391203091206968415123756985139805619819948635\
-585098036367244625761459519500352081848996610385458320129436663789997480901710\
-236533281632351075631018953036605448865067979102609958698373202351739037084198\
-859959854686524052635434932149192814613278677798009981810176896062374905813080\
-695541723785722384752300108530162169759028847317412933357137852658857592530457\
-541194055519184988325702919625987235252373136433648520068960515999479321705266\
-200363737167510020818295330709991856368698071608390681308833732986190885417272\
-969842576509112966985081710151846086847390169261245145086453334691096277419871\
-3345:\
-930693231599434286203873573061837589132316455459049942576072973261411943411181\
-343392380390521702194933051584300041204961744546142818900341148108232245516308\
-352251529459927737087254844034560333288854935795743568330092727805587255201888\
-679616612146267914020856603417469217828373038740861077146231141116009601352411\
-392383630574556790807690450274886610842459205819782083851300701981300331709317\
-475854173928839271465703758308070132786907761074836798043983913773713425253745\
-831976706954608514918108081712101222457655798954574488488341447299796161150137\
-009120407480991579473472415230245163708194377271500338338173999820026824067740\
-589458443634325221026946288354108649966499309246314290378437430114881939751672\
-514482408975119068445770675902404635517404232907370586301639272254322050155034\
-259717291845144523268114851768774843831745033971003885574331760999006663507374\
-770033967116688049432839082145362127141174457535925434598494532740081104764167\
-980472435057459740893157068725871031296412012156643910826639579636068426712180\
-8506881:\
-124062134902771857808534580418343363680096712316389830971487874040892814366277\
-979003337153143912392086073485803429798539434004078813978547334012173367924872\
-380640790556349965429599395678570501617453158786742208890355307136759888856891\
-276775013281906113551864152989666063823091754247334449767837459584647332522056\
-264999522158048467939823289863499037033159285021818732441029276625360357100276\
-053803664807515020472139007624316362009343461498104129832981017728476807612215\
-749657607694537693693938752023498518709797429374937046822644050247374897188793\
-539778884978712969121438101727181570068127537788791830676329944755446141609531\
-351602952636510211504012081264927365652850221141519431920227501974972275913441\
-660006998810278915303002878707039246012431562603740303148913953818214501647835\
-712791799293270357450941115931425860798786834065418704907429618043480548270653\
-442867459973893772042179984852007957940974947913624728030501950890442886790939\
-700346822761779364643106218278137563910934859561945569647393834353388507452552\
-42760191:\
-123962089525803189340645553691212614302363853855543557349822186650150914186432\
-898393999367067391258981075575909795085317380631526665144469607131693030929830\
-698198672763433855712531664463102768536122636195589626097935017768275509340135\
-138183042169404589635378173076017770265901108818437308196015981439821888687063\
-679421203099550198220735030215228133233205046631686214889385173707764646419284\
-879265937898366220730636927592466305242434692837611984520364767068306530155575\
-158746803534424218143943673580671415397803145233350407883132078628854626024625\
-477908883655282397228457326089772811461407412147942464999219833942413592971357\
-125884309738312015793932263047744405054556347177874239251574844093800357087207\
-045232942767703546617290339746005616619589918774766179119453940997942058603251\
-939229300259242641872798089579522348953002024486435329603569577415004050714354\
-102280787634980471338703086794138575328071050747402127449860285197628523669695\
-322561641006873850163837943899691804729439097607350700217610338867039758415350\
-78830362
-
-715344160546506053018067916441327666320749884565742835949429135080819680868007\
-605728851874165212452366804013327483427820566552268708174459045386672325127385\
-114495317950745682014690558839059759173739230320924114125600280099439596182740\
-415242014142137837064439154081376634277409771510843267178838423518517984154190\
-881063240091647479545363212073885459012971441095047397968320460580649550666059\
-837647322789021698711887017141345641123374090118785638881006401453133232644172\
-331172980349339167214619778709101974704518689271343834668314699245981805001489\
-636858718127486497636543614456608192432783080652621388179211975629806897188843\
-160582161919536541771038624146704077717992698607413512365889920967554179985948\
-913643651552422324073994685702863305075510372619806299978928483665712390138333\
-378535576543691534727690279125502997278044169433853749411712054086689855993754\
-194777773047860314479987880718474474208122784477954631198073705465610147706562\
-095075683476756851626930746022774727654675394852191931389475847426238529424530\
-5608567694592767669567485:\
-114455065714095307868118830275460538804108162103324825286996251939970997930952\
-103878379503236654773304063460212208670270996102095127387177178891841374083145\
-953297827166435956731563439707095227091812015877198291086689391005235918740298\
-557195603605444646583416971782465469965868723367600964923100738289374032822806\
-655958600209408352170101048167132066804210673864332444841572835615963803190909\
-701069237665660805927294756101280473851829248608516125059571134662861702896541\
-755725481139053420182841100105390452348024439591484585037533593493875207072432\
-359409146455631006993631948060089956410816334377031252202367078491619235997609\
-986105610843524330296901950536056461804549699993884593477349147261022998107556\
-579691032619966775842806283399706858032715408097094109847451273174384530688939\
-478296142574060797928168697264764376937561621691017425880612556478141476795574\
-722261381068868024840844490319844643333844547089136882140369759743439054489706\
-908265777804792475460491107562894549008209355776227278362567328262376036685902\
-241814686282474880803766279:\
-221756689822712543171568667673546882749997970869614248616369979310471231883369\
-759156518210166759571175979570426036792689132535595660453028079406628305634426\
-126354741732974447360339531606657846253145261260650338297373071090098459122118\
-542632608240189344977407220221943860131985891128494033654440909303354369268667\
-305965102083180890039831992013931068935991884255072260770538043416387896195570\
-068600870572595930073167117327013511431528650148295393679245072014929648399306\
-795217503670344174975930427627877672065933120373240636005619894527577062202858\
-549642035224973710177273699512743741795114791034835700158610227369990114201144\
-409001704727892137735419777288471088055643052134401665961364771254062335338038\
-438173234703407674274617707014247976596407973737363825852507059166273160087575\
-664045232102152438863049287538896170684071513707192263038225480698736391136579\
-627403626067060857856598763146924169128008894394528828908553255609044240978834\
-326971728303024990888455273771655186398230068031724002193942255726097719534016\
-457760585236821881745833983:\
-120170637729858074933418926892577794783235429821821586214132563645839307496789\
-114434874157827241680215392124717410719156662576847855199096204411456086253594\
-434722707883093457514430768668557206993816261932049454466567352105733111069047\
-236048677923186811003172530573492508493398009697646212117299916021082045074521\
-208482243837022521738457522425960731417742382135431762554367137890267792047121\
-878389298552396415116417803631714480857935305097583184237482527669003267218976\
-213643238351359594473477624907275150974211194068006608365559631835472549272961\
-312405607228416118716959085405617409757634996652938367589467464948309165738231\
-708291425589967338687133815869217104739590372931206904646450881014911081659420\
-227337167187510326512760827244218821110337553601099176054840981542057897153496\
-827811811213366033328471297905896179453273099812686556990847949741242434416624\
-519094734821636267383093930883549057375457430594423182636978491553748907389682\
-047367452786712471736707479239712857972135448722148077603424092556314162669344\
-280391246913077866587295271
-
-158348444151469774548335765813521644515894096058831026317698686817873396376095\
-219186421363012902247862586077718495096164183176083638661355997918261465604389\
-164777987022637202915269811304453426529140886232730689357107369326896599546826\
-977879197866744214590813928782160670889333072713213372076914166814031740620222\
-096627966174797593473354188354467797039643805088081798071919426870672233314642\
-953082219125370097281416749121370007682492963462746019874621812683075856737391\
-007920705903971044050916451994891314339534606942005543166165795377741434662375\
-955229893463370206057311773277174926176509846932971298586879031626058990967970\
-505410940293948838884571678563798668093182157173484130828707113750334400398660\
-348235884809950348030411188436611054804982023783245270535153735126550769204667\
-434556945983891538476320011110669400000199540451791655950968071754732102936535\
-168723696208040682785637021766415238686083294832260449204853908570835780283356\
-963282883490691222614607938230023211016130039888113806142750994372202954417658\
-9609273623223472232904601214605349233381875712:\
-263907358103524308016003616240943568139453322722052833994193849431503541525058\
-995713943283395924782065325990023794137618869102264135554299500053436641830640\
-626299955141330592091874820579555896591857601896357815779451275593474551928543\
-804497439728361834065273595291575498635927176336000953278227104376648969789525\
-703208248990409514456586836046883778872764507544922919134165364811094117315511\
-894771593159662310894325440097675771180209977516431394740860477486319776519878\
-360572857547741688700823604288541642477327709995560287138588959518137553112505\
-679827156470494695761747914993997234830953625721012306409348099048606133247946\
-677588656444374878089406686542417592105579952839008606119230077891180195699633\
-851362277534563864366989638511839912058804595173568794241254796521946807992131\
-045318043218350590798105204025504581391864181733676325360766601269392329209315\
-187523661618291818419897568159877549759165996061868730643081008173729815374284\
-190887614668635462817804642909056283439325780981407041335722900189937717909205\
-462776149043535400479799536396435459472957438:\
-211133135824348337682086534294478483410615204298610764964437050600134692350033\
-411025411869480039197870925894560881379899503473755147191112593241776237231654\
-342798838338627674286533275678688560815411566252023050054315170758540942143984\
-008295253707455093419878382769349287304251187793859151157176173840363048243260\
-400483899385031403522809458387053773065030784347450520597797840658117177772403\
-000658673634443660675445999230969003812217525564493573904209997059225356457046\
-643331057306523326152874384039508229960772058482645923512877153986056774090200\
-811742866935514099215146596342819747966459096714001765101279023714626373299927\
-443383895075181545207386833580070794932388467628363739027968376926415952759709\
-397131484397293031273931252655877042079891608804690020094102049268889804085050\
-730129335727701084865660783523558260443144562362348283321635539321258047329763\
-071505828333710841893913354257538227063495876448125763532091931561288559286353\
-017858039298230922470823476011445724256270108727169418659906970562309554685398\
-1050706891848182833973758045880640459723759616:\
-797421018282309300276471146922392374361280725303771976263687044724945058896296\
-451309105463368903681696970153235477683299993604051654023373903149996643473426\
-166434265143380282785745212956236077797941832897001532940624177162025905739667\
-502819441373311769422777386686214623042675710170924642038905382252462485182661\
-524114024567848587159571579423965316485436953070099618710616908871984898104859\
-518520979551476408408878506846489536612480506172925117451120162875411998798910\
-629645301999381431439669279547348179362682729535153979540276434848292210821935\
-564796443872517939077424608576203698347529101270087333501730710945001551555155\
-540251494872452369069373652183820833813858644536695375055396279203484056295384\
-837626040377194020678066253140310026304907208174421305017384101678566613477185\
-572575244017575211126796263341583248723084854182022705297183955357678491491724\
-278510184968749519182312222178407427566490416770984084770910316973078295508562\
-993275346600008986039724266656410117395243871165589356580330661737127514660362\
-456330958501002723618710978858556875800559616
-
-570513291024910857180683250916886630281059424414328988931422545533517561122793\
-631611698890692975369823565021867395616597231593865114054852988652595857222173\
-785886913949317711328526787771799158072614225857979913571626790248887317992360\
-167800299638616884182461004926831944232612168588972544178064099808031631865451\
-995501726940320446490738407683552476544375207587726360228516004525721031635167\
-189313406844483367879499127048185133020654599042180384794966476592498269287333\
-394273459198207137428730076666630101478663430585733673105509077278403044440224\
-515802378796047848113764972155433205375289582554589182264296349226836180582017\
-800829021699268814492289365041654321714838113199714700763684988192837776571621\
-041753135136959735893473906920185465471635513195159451498432346221258748335825\
-692841909451266601967997403894935550036529738793666792238250159177997490056776\
-328670581584491554242700556013301776049152944144145962242210164374109093577609\
-193798653166630449523508889477961157587292159917031040158514486371046850698665\
-403328230477729237209338647241174563848372252354929460284227583:\
-389090064478803238425733972877396658479573008733924311467488310125994876745978\
-265728517639007602019900455338801296015736830952779627163537976401354942031059\
-255968507737945477550546732698999740662321990696927104417850905895751344128036\
-309904986792819113482722824254526081607369602139248301886858284332413485304722\
-151671089791799609280132728020486736447880185660528840776199747817388639563882\
-578272823859464332390249881899219107224037658578163618277971161769958821308883\
-878958345509682643718372287295933347434151190430249861828790495151673867183795\
-799033293596814472790477600948685208383998583347199295232979843412101400520988\
-783820080907740294158571881335843414994333284856510342103216151071744491124911\
-990261465685618399319959135671701636031160052642583395020843964015761785362259\
-328768408878788095431168614078372538772404278191313779200894852629107049320017\
-258846438601547862385140157859503670871838184084510090792574281033587926199019\
-519816410838837378584463300653427089543268733889126702351652132482924347842112\
-35171680646026590945513301759285681091536143715910835768804704256:\
-389850748866830549216713947520052085840618738187290114045390699948062435462301\
-331981356410111029465239490497221784384528004804894050441412571928941114029614\
-401508629838533859866372064119581576407711498274915002737787813507365670922683\
-354834649155758577888929635132714336531213138805441420123523295002802371509329\
-856943111718534867581511939884626219914411129703524819095283076026512769798731\
-261078050989625023322588403020721217239057014905313658246666610834082223523316\
-512019983305841438870861931094976675735251295277422623893808579753950006185298\
-224861622986980508165905767826729986256550490823286773566585051844511095843507\
-855738364937872178905817408519573480546833176486981816284098507721096245857916\
-327537370957663200281352391542177127256013801809513340285155231376241334482035\
-357327124508089525274704732845010389141080369508103690865465831197313500100401\
-233940618536554311839573849160059627854061930449979293910303021516122940029443\
-019743696572446219355717454498535854741983743088553134832455818188606042161341\
-45213173620081314918751450217911557020823291320973945186837069824:\
-385050515979582938058684449317244459454543188847291753951308608752890815619344\
-418067929799272083548279079529764867908297817354566403941852679176504766181588\
-126669026481873939112166336071041441922517506254469620169659402374985953945928\
-677987133408787884226832363218232756849456355231661973760018153141282186541706\
-118749055945769990183527736294041132309358495297336272148994808704990117447881\
-473121375354205848245506374080828354735015786468367324134836307698950731331633\
-392088531033408793317653189104548710125193434962177839902896771413194314949479\
-782653752907021741048831277650278224109058573723776377672962251652182561109326\
-578869913576493811603879212797493914292901745983868798224200059853444221688741\
-981423885963230399822541813324599524535071333455856132404165710049819597890503\
-145434594517971428816214345153227839896738653503172028828267415572305502675384\
-561681061746799964421718827327455113766812720973290252157090591977363344191988\
-954148747606057442566422044297004703507172254103427691963065665454925138337969\
-76550081610997879196925233902454008520815752950469855858908987393
-
-112257175050859411550752248084728681788327833874184396264053673467030037878596\
-969988703843029907736127965374317675974948069611105935122138212351277419722573\
-057011124405399665613653226476640209071786653482772221698300609700311608038648\
-590963921562560930617228290860978048535424272982746566346480687058647938931792\
-494772599734085765312766056205234046028863592507837419129992867085316460877885\
-789539171069649397622138447505558858829602695700582104463802776107914307926273\
-214698138431329653367976833729651926683947234915788607043713802723642663637964\
-025640637436341151017013067623453822445820764645585159304152273047344187434198\
-867025897525687276617237932574144068460864621430701337485740486427047413661483\
-598700092348322437326444026477488764821883728727014645994811437194748569816146\
-637297401701871436627436065564252496196647389702427641868798569366840114174731\
-009139856943870045531278316406330327666097190113056988423950985903950648913437\
-941903061243609720110536173494412493715304181396157897404816630618506774378126\
-656051207121858460635355814516494613320048954756343702670887714967179131994777\
-84576:\
-359223730951507047686474888926681248550952555597868396256182034819810022826661\
-034067274739878182888378066110740820008132913491632027784959679342819222345737\
-027677813259054891249428372903420422893266086909226894769732780025626089723922\
-406789743545011902150262709179337950528530359168404540850497452857903223605298\
-473153621614825810650813680225617009289051037184006086292900759359929112814468\
-972123389591255433994595098151461393996083110907393308647683311137256462223596\
-585259225213975588028764886936735444573431350424192620734174502489730489123221\
-344700889435428469044927072315024239903803264048061000758152155946765210567523\
-888750896289403659049999409689629719161113625114956814607072946438222123000438\
-810228802584203621237260571488035658499878399671492452713464211389474559573354\
-214818325834065832627997963753069853886591400943892997986698486507694378753104\
-273433657764449139981625487096493565718051243605694709201664988577246252840936\
-634080367542310643479799635673030367954737690270337653443034560877995332116573\
-847116980412102515874745598192226325580714248159368956390879934850154260139924\
-258817:\
-718446091617723823743472339783445505851897301395650654672873762721567280990140\
-047430441708659481697917967162683292917863371736949992580995225625799685473915\
-378751531891992346296580913672393129161494601291505877424862966232760119539495\
-026855520043834180400148438707547851619936204538620538566604848869011210681280\
-057458080507476672755098303144023100324642200310394846430112093113226789335462\
-593856427850182934327356269945617017966384726166767161387150750588378432402770\
-054808830616620216659203929959714386281725317569029476199032082945509509924387\
-248010561479556880727474465822543567698020655144612694849338701244417579696748\
-907538202228361418492140400845303299159502212700265159323931083639682418304129\
-255252690914821961200434524681829932197503648654196326743966131402129877271248\
-048776305078912127947091629883756392918045706107561262231739566550992365653607\
-143741986604170567716176934267603930852036052726419418870817131333887879102631\
-861902243094297899649348012869172232508195269963726340116188461821200382409452\
-823400516165136422481585720010982398981692816534425389645158169719299759587995\
-942911:\
-216508910512383622654019475845034476415847966603170291589788162796526699278772\
-190280169944859914998215465884713187196883397693482221933777604979888331827818\
-754472343836245705244148900472024935634984129277279331763529273031989392930335\
-645471788131265936927160886160369220002699883783343149019877323088836044017143\
-308371112376100327561822135526758829869999741446013982332224479585831487709721\
-630434273769419421629572533510046554786460685514577032828144707143473782672568\
-465556097523567950912879933097938161818019916174456153047557708713706315230398\
-277264366238145031097978159354114453606863929301161045270814481870283821986349\
-944645053745537437628565712608955009429036482124886620466443631772225938388759\
-835568942312412285594010078372192399542904340513569238676810665771368148881011\
-506400324035672016652102027333750356020885866464039924552417876836208934121171\
-031957651970606287945036733081616118341676478646035344937556044308952306817828\
-601060230648268515401210151002895147060519501408822305149342147983981551139345\
-702183956987879884819780766298173944149228882734386767851896416786193194714131\
-054615
-
-132012216859757230037775572521506266291648756272586591176540307064815216284870\
-804003610829087044921463026377883996192642548317006159922776348121917260095755\
-503134200051254456758248492833354558969935426070515312351509557589645775009392\
-397810707096681214323988033368472601292127149614606307827332857383610261612880\
-149851800738072908871413867750169880457189422836293886350679863430046835998728\
-503968411374709502048085751758357279983700825511435135236186526528524349684289\
-866134994962853035963655110390488068559802069665057882626270889559694110103339\
-614714653776095707460432988245132622358044545269821640409714299840952736762208\
-678423825132629401993715370700397676439090535612169552217898132208953854961548\
-445665349681578584788319590102108919102047147072307672935028699164699040107819\
-593310650278220532797365455095688425828790267519291101928282274561719641398897\
-396081957317648029219764913746611937568613799412445678975833975300971447407392\
-459222225074004927053914848774907852123372400962227429830440936399869647850408\
-582086669064900153329904310469052934755802091273007485080741188845130751301081\
-28048904757072082585387072:\
-129941436987920745008991085029475121438777397790146567403211337730417712379420\
-810672905442153473828965317777618006675940038964965863501863753205590982758000\
-265985343205524418662054387799411630097716524251724020175535553226342575243102\
-792828854736046571752987875687176011346563044215064549787489930273914241921690\
-360463236956655954422737535567113313191315194737567299162991295856521652124495\
-254774984672580210362737013051904769336409044672998083198233697843820513763972\
-958624209721154415763986439755518609563243788023944791581234447986521345096272\
-984446226201954095697805912140252287415831724063316256194061029456987879279487\
-815830957249824542191293962613581112253131999349791416109393349349987103641545\
-802835092470245671300986876566152902892349087226268026451665896936117674090160\
-049066683964912466791304630955735872647829123099307672022195609348335040961712\
-358400200677845948106950096030843007492260830578849183604190891529531875550283\
-325863741697723661618410401676018089404896857593338554101796520439673783494219\
-440300214355795412525585850807370090159727867442169346197944653791573200710757\
-01509166981998875416525825:\
-133047606796335709112268627100040591998243327020541449553082422558420376208682\
-812484206578052890058795941694338109618131807517933671302919443122667592702678\
-968227517133973416102287506567128757513702279902956887279382455931529594870509\
-852688044848432851023700485235451355437228996320479116483848007252870080510845\
-552745086421846780875656215978127742824216822670050036139948341431498456760724\
-237650595397759071093528617834080926307030510609955891104442032133890173051463\
-793472420924159568637590973450962427086348790170186767766524089991948246349160\
-634941447607784305791894820169457600996189682835541020129838504465879493247100\
-594050162502276948805205568338213706657628486388253854427328536072410195068797\
-427426212555230531354636866127372286724319590459542530462092671607458209249325\
-231980424306796596670248227676437543945310861140304160993898390023766537422865\
-172170515737377517361279547196351431616792343370716486410377440682963654352730\
-062262504199678168036526444463734413258483741267332090969426417567959231863679\
-412410205085661065826423246746808225461753621174816132641031105254519638321541\
-76390562796364757722988543:\
-105130613687748440403511432011229858831972690175287239196829475993126648110400\
-750262533439421883033948180150733912153862305591700482578406948263180378500381\
-942931219795467825916079248469906047619791976986885180126238698257674081425340\
-187660775993577985654007302925895916589319240020972021684492407773144206030363\
-132442904576534511869473443243149793874019977128098791331139901450133819965368\
-234316071115387628104496140270727944750819077283366838327643799272035552251700\
-997531545884799098936139862696183081828300151270958111936893533015523807701302\
-280012251655859259294034717634431318512960859380211136821233191540925445878109\
-397507332797630853907140959471006719810224859482142000829423025569925049562908\
-428223824159491166638242779992937354620015709751676809773402034050102009775238\
-169253094733067091077789818173777065122385266544833416065682783863046016326950\
-633902607826253795147867077970524485908601617467197480710208554088974316649613\
-526490117927498859087490190284954433961157868901343184642190819205582059810497\
-194858496487160771768131880029400765917996988128276903178409122315952875645275\
-57120875929507253119655500
-
-488949073114424331989857685876722644697601567909307207119156901581714458922486\
-197520366859879607964550035472266019650901472140564231295070075267661938549336\
-214739095130688064201210254178935360495766103323466914079277549850343782367165\
-199399551156706108508811131569540958310945961559911997430384872632983942678271\
-786950257384700840421378375689807688340388561619720283921588077501950433728498\
-616933267926716882174455871193412683215831679065172407852480948207101942981269\
-130381798608747400533535334314587863921523124691851558085847535204433322048503\
-544492501124937414992399846945843730930419783978767143647392381520185969513736\
-779137443415628083070836180003896971041282966652257736112342359421183591463096\
-216116107243340725938249561427959451975245383774860948337193997295206300081894\
-287362496290271383807813569883781976263221517101752202223195204013179955491073\
-380520386478832155548761454547836568875282932892731317136207806677815309844967\
-545785245423316464344779496891949695116889772538265179582984223181603301779234\
-234493039924829073877322179810246731866967782733768227520142349831930281194941\
-661283084656272617772312904338128176215506943:\
-488934151580000910273551273897697487644653750290386906745416457435487669400572\
-725015167842867670672320363495809767881356993535702298897577757848734165113091\
-204748029151688116772874879019483344769481497299041363106529080583752384971692\
-385733316678114521160674624371956108020693966402860493002707429115989177034229\
-628830451700707728343723558402728852434304305205267896241245153480508380259851\
-519246618374282298667728579021827360819305802512678832227667367684265007961936\
-748319449553126749205892203894237440842958517692736453869844147101725670888254\
-286293997359910755343549529806959986218437065451755335189343902303889634760666\
-178112203247542649271860671362987590093769540864579723342704323233629966980595\
-764687841035840334263565508118447507008468372635247141084232866472990523277759\
-579664833154630306391041429442958043888427243970823805487362702141697769613441\
-472269897703528416865587682885971103992712525308304403411844118759899727711564\
-645944547056710459139390891071209876487995360106990642740825919354388576521268\
-002236475346636454596001352245339072893736114056480478457630198355420953169919\
-712567823383028203488138604733315617138941951:\
-488949073121538988894643953985216199936024823203052479660203502749608642089638\
-295609471228823042099178808299295349744738873225644092743066960656373905335993\
-226594601021423386483533414143499965607377878255370919800951583762215921081413\
-178407903555239910874390448732145181095513246806670886194538146997695604119376\
-320137875242368153907031000685590768203853402852876962188866862977598879441556\
-746937923129924873312867723376777395682902527532315323218464968046891265803922\
-053445091259182777893870605821407728384214483686254470070998261258884066527425\
-861557185366656552209296984910159347803942427484871690944116736767282346016766\
-481058351623931611379188907104444816802262199432803773786084929928117511157651\
-560581397656796121762663813480037879330540630321311334742826531199827963323669\
-532749752637315112355801911055172776284138788073620374656915281024766882107181\
-697028340651677475325566247000777504448846697756197542339170820790556541789200\
-600239074196576371686317370946522040554247204578281543560411838691415567469924\
-895054150084305830609314327796155704111172955181321008323078497301990011464450\
-173595889401386807929213249376235683512844288:\
-410092040850741063574924314448267881004102909569185969267407508839136321838722\
-356274721146780423216131236149452232593357903453050689350036936858132109701764\
-176101779730272532720708856606560795421686565935598163200165965062174601538841\
-164283910598566893199077869356770126329745425450558301289250155105932429204583\
-900510475118100140064432426133911247203584879326182977470889502548763715620374\
-522351622758123300160219051142796256622252657590471977176037414742245195000339\
-606319546688416505608595725014401929887474344812706013677475706009565780205927\
-550652254709432187167550972375130327086038724827792277736100097234496216514314\
-992302320048801299291660341525213217242775422880584028047440325813749759959217\
-670606269298850195316471355073659231737687136475218967054387588527690043656123\
-882616735732589625869823197943162558694204859648083112026876285155808063060304\
-836177870164739817924670324040456826362170398791089139245928604549040239178325\
-233934107353043832431499717292477080819150756301917891165092117896598141214771\
-399791688514748727275067877283723067830016526019688241327241980707938730875970\
-453740869024411001035373774440383590514540543
-
-138762351133548077743415873038775897676329559314243951028134391495680666126742\
-627318034187764134859143451991071936930648952641452215937583560898153959154212\
-331937446292503726864777568089403384312417201291981829383783933459053277056867\
-225409753882219567017371300560842417076989099209444310098365604624717628375379\
-980263242978656690485301861976573421512028141985948836449854756971767290548143\
-780811385408546699083000033158849327883052792311279379027140265841600803635947\
-440536613329178332625418476961881567444473913255263667920204837119032496842254\
-257874701769514109918551739476539710067144685650042109921696935353572737116331\
-674810302627994073861393023905796175030946147414899094376661678415597630609649\
-262528629908056136891571194817715459291132896292995415180128479030139829508266\
-122458174070238486081523938955700522865254574522668913798774012105047440049501\
-051199056786759978008347417066168967801203517201260585178426017111026017793989\
-389427220441022338169999067681396473395702714890439297080064935807881953245907\
-710418648591510662473342030438159472010166701281033339560643745499156949954805\
-270532411284472302932666918585682103751578546474039247829531600:\
-450975921267528881423655664394522845393144760681247938282886138716671928584487\
-222831784722571610760119796408472342902198794351346589152657054590389950570397\
-314721175514383846293965204256099643265796056995283154257081276647197478059605\
-765138807513641571717612457966253627811200941970620230492627213620382045894110\
-469714276752587178768026064572084351210314417379516375803478174760698119576394\
-787569645258079253648695609812953477740298964523455884378804191966227522764356\
-600534760371312662801696957336463525884203945587877581215431610912768542965213\
-973258775193701787203408162778500052944557185011551045817722710637113277056377\
-194162043167056436178509417085073054187975430946700646733270386867185849869150\
-444005384070488850346635956900040024282426501744312114727700197773208185313100\
-334333362225213224530361991455910413471238325420580530693997147323338852528605\
-198000330647125188683294538737601228675413778550212607904201819916998032050414\
-439983159532958667065493168642852135444972885666712576812493664152681407566007\
-517430132936159704479609263104823065901608783586055277282888612760789387599662\
-0564926323414005158200643160200198546102009764294645825323130880:\
-451192683260656724007957426058175976777092207494624540659324930236360646638381\
-683748354152678238888901081422396458079150319824763681794290803124911000694744\
-763297838595339341499141819712715703674786767683241670748717465070756997395708\
-230692393547042056494054159153649282192389880073295036214731189726993122338948\
-301018342872650826019627056625874376747927301076833848077967667942652566029676\
-700006973352060132083982618776926626894744409791135978994572773976897752724710\
-303176920500272525003225286717607554005509155367978660718062672677973254006291\
-141686416925496737373797847620211281271259929459353267080785600431822231813283\
-592471353056451607042931613125041704639357312712304328184964167095498090385813\
-245760095997698151316187380608878480838863599219402625774932726297002490673164\
-826377543103745873466160903009255870959444275271535698351498781578632176283638\
-339301369350211149155189020294373256873760442935544357552204447270695699693730\
-083652956783457798232234107862502396065843874829680908732247814702012605381641\
-436209355047373130907439514261953948347849205490168976048860487848929733725938\
-7326089475382441229043956958296017272682761283530723746513944560:\
-446184119671208116731905065703522497902043234617238555051056067843092348032891\
-591460924321171723954896988737841199338306791114255994017768369799443038690934\
-265424049645148434961727306575484801689290269903486783418579230865098016255093\
-174236751494762065116066048329793147094902679941001782420197392110666296371200\
-941018896020736329385172405696463143448863196504953197651412551935698489879160\
-581853587848680112767607301573783706850192260390533088906398143691112508630432\
-277728843876711210660327284250005174687993240419497348403091138395489187448438\
-209307144373995629378706203376537236321597224221218277288442465270546278441017\
-225541409833806604016495454896514502340263712904926721551331363653070594807386\
-860257878371074693164282777249794553676951198442131074282182102965574296192184\
-052980354391595239002270080320778089682666871907760754572051286486676178995463\
-851384630214661921228235007156263910432601675547830090179818959335877146323699\
-576805832909173702942007394737072402637185030919997419166896685516861374134897\
-869655965125233463039536329326686291213595507312366477350289024564617433264353\
-5342316784854950139977686415831803521094566978552745702330993120
-
-831903739527981619512103753089137519713228192986178925775408205942180012522099\
-640684388037362799002320370468347104066520003815425691665405614581277200176607\
-782730471661515345192309554304825976546548710150905569065231825305057961656794\
-628039182592626014076367970646950872424030290697646402321825703423878216266652\
-900955805521905350525486061357725256595734651223339435738558399391490470763593\
-681310715114319956074442791035414591596946799515799872319507450922047519589477\
-836698412186337464899087907133509391879292836286349785539115873914709397098939\
-790692677671590426359583805212491988547718022262937978704736854378473126218653\
-216597107456040077128134577866252997621638478612464003506545825774377669622245\
-745117863435804465294709351137777724127819834545786340604064885412707258003472\
-309658903471228448349385729653549870016082649339121245922013524716940636658704\
-212674942253232094351213214914155291107946094530331716541051327682316835411879\
-960299096099942159123936953197028071299831558831268074532195442463722436742569\
-890936257897752214406575649075735374504079239199776231353313624359918324659945\
-837537839666547147362161015234531617411979361287655105218633484776868381951849\
-92256:\
-202903154644970578907066901471915938056103241027759488424976266346896332863996\
-577105222345382037962606044970414356716783878140720208512968992154967225502063\
-922323675353858686876826620497200852136344799891171720965517788611001849284654\
-819500741796727923615629693875400662961011170776943575005431164527113606996080\
-711062160590465520154800894792038172215983419340084929828561135213470190830269\
-810028533933059892135598863968222417113613268532189407487141051892594456413460\
-688753433134023206192160923154909780975586546521913167867158299054587293070409\
-472699006081353421952926601446178434716298310984010856094626873036294998837932\
-594868466717584114424627878695813066142621046524134182187022956305932944533934\
-112717710387560108440132059420032068917439412975622522640553303045874029389131\
-733278167814437396257168751465931175621062360747339592864982851015845676375114\
-687564401603309708108236375635092699423677819866661428223882147016449410708769\
-658969027685099652689359853191529126186394691692087207152945685056755622975671\
-832223670399391216117612881678571153759055985054420471219118489779207272895106\
-948975885455846322239725325865227133863914818873311141361622613595429645885092\
-48:\
-831903937869241835719124297616829171175599908742918156457814337752422676959605\
-567893008909426719860538923594340072599423882544311760127542260964030769674508\
-842175669466121924384624573869853318740990941612483864098293113008040625010431\
-484382367568034052393693572708679479223251660379676404830276387253389984636595\
-692895343262881243190233153137630334638781444541895073087171844547067578659392\
-645923506276242461469928487254317713265779021222866002373675128484010052888651\
-906829718441716620401222485041511586084858055930658977674915126336730849911841\
-508017756659552892438080974545034286817533359824445883015473972784351646282019\
-194761157184563880338089764234828562402118556451831946628274759699497727804780\
-924577663940525344754668083670127421386214903152965367391097466277756658880979\
-897531539564653736654279799647109783110428288736893230963656928636457710894573\
-740293427468108022749947385078359567867236885981495016752691720771084537480965\
-537785980673560224646953134468651574528769665979806376721529894790751017132709\
-355284827842960401963527955520726863776636695129640543316742224518493569755697\
-472934822430039832129660251188806428581613509427605270413171255014790855305283\
-82912:\
-111552875171678263962551551595357030862155883548710162189328121859380919029563\
-118821418527847248892763181107363724739318222757160410309304919044750709814412\
-699080460974974083364488317087514356817135937920417561332975505479370258645451\
-255059905317193440506894965864731680539917517837202787731718828208668046700523\
-579638368181783376854206459085484729009509874758288821472451058240513292339140\
-979172687142929392035671646767291532859056752153944881739945552117794907114258\
-905855293639098060301822758200362102288895285949628353276110020083572870798806\
-300293806314708625763124498028610024531336323454892263168627006796526212246310\
-430657304091316495615210061949055153253675336557290099004864335736003184680025\
-674900043399428599860047189558074363134466146084043942802117902368568094115721\
-538255417283846509722622907924000883355081227703595979001997851658916315505489\
-245000582750666282175144423635325064231811686813031239645634854183032791493243\
-760009207157314672275568474396250965858080984515988037386939278749146977048381\
-312158194379041727213578455743041067318070450508082422602487473371864572969326\
-513401874683477734240756893158727596125291716115451976744874152636669208741847\
-53152
-
-671383797745264147954162281372916111442806253377242386985229782727326243981086\
-323821309626482674886080996177242334682780680556985471177460069832853288250634\
-907524791207432088926638636589481042199341150044308859876708566521421204433205\
-068298279176580833013061752761413540583857334245200181350723654442006810277345\
-649583753448542239352265959172686705777826287269591154653226912333050529413401\
-995405152142824070345050799462112848841713605727995865850511890239377197718129\
-091280151713202872965504668678242943846469314423987590504024074072524339488378\
-146283303707688430536932867267257651653195416169864403817008958526978168819717\
-653124343006247303678380512023815041108257729105443240764477823433212615008987\
-064672383106762999566440312998036181380890542180126271212189637635607197924946\
-875402333140707116940249836987087508629106087027904879345007065309916528197498\
-300853168142189372528498952434111791686169534344549024392666576281878020634508\
-289065836119096800189012527081925861714076969635272249471310781708074914885261\
-134179523901430900069909790834890887868601469687178335269209939796691696661137\
-813549119307508289197071385846953465244264494781652434050677420256175083326887\
-493546434273103600173024:\
-153459153770485659898199569050865484402380182186136884972384478926424074383277\
-654671124991861548435270875109374229931652090464556800329674746312234021403190\
-429792229925383839585953896560505924881804195095997257954593495732996807154842\
-755990630380373494862012691330576377299025840680046754183812394900999604143988\
-078362634277412829667224201192311704682127237421205384463399813793270719146630\
-600283065501510937761776423635857644740111823207367452059426466090898090739968\
-673474256706029204421700070567484024000657098924923640273681209317445462643516\
-772423107152732124611029898718065408316621155018309294887815359404527999666538\
-103701284456786590494409525708675132465042912099098305019476146737697193469373\
-802581182528517155669643276643789312906815657598074404047245818241853573315758\
-958116875534021040320432465453150637530492109806110647547624904979165028086728\
-894961901677543065558613905075473111206698257175436937653855734662695744641398\
-207426879061679917580570173376194087928666453103916659553916725352601812162358\
-866200420877185868032783900401375320536613038300689131956933998793677599429619\
-742649410949604394981993198051791417924928112630628613754058304660613384842029\
-9659496513057491284688880:\
-163050350880992719820577635973310588457645800231736719778060982665398109730958\
-082087604388306259050539757687478796928280993186468770629653636883477213378728\
-191572954821317531849546314310542162021167355696585144994916919719453772537865\
-961098977039013114766950752585090655952967480038027386936264792812622140280772\
-404345933308402322269131462666161026096170200066116152391760916369214898589834\
-754796050084731871141309166332653494039413122271426069673187150345641747829201\
-734097216058569687098769686307539053174471439419630240138902538078828303359081\
-736324513482581535297888829719380529359852407514958936027055865175896620417476\
-476901515713615709724938528864526212917352621110530647419333446067381229916739\
-415071984670613345551434048967214194778591813139822822650402500462770210674053\
-247737759244369540977247493588677012303305674804477875957093214624394454897302\
-447312654627495178566752025428528352194371477125664247816163918032476130897035\
-886801683423073118648650936386096939042145882641489962482021143519486525064260\
-371763914748441421706259194872513694470844838272575801659390459286919049043598\
-869933382555490414353736437876971481088655693480023441306407627813322999582906\
-0603634413892848391815168:\
-530236983316532815121276312462493313302244979845831268793960256836427678056484\
-239985220854510373435027337264429402494258326873558328901536786268005304821087\
-844012020288574034943337321935407987277263777240111820324554794585726440422596\
-505667244731173209767832806138985698287508795927799583696895535456501334071363\
-581769880395356799066234408229879482822572830977608643468237624956027864797423\
-586235857512343461117442624446253661621216730117571820305114802949293924795088\
-469378466450420308215216286716811254753888481724522824054730409319826351299935\
-472946577901462941707645656698846963210227662168227089484816699446623476171244\
-454947834296924098704491582819473124611649626238635033111611477997557974212435\
-417879411603156419602500032413931337781291884534876464557046774484325505645804\
-764973289979379900892852475728595228245644421519707496170231427739950306314986\
-568125306568539309864728756682828343094338384817342706318007503655580943680190\
-566875017929316200782060047581348699824454046197707897115756651557553791763375\
-160968927982687925139526398255278646789996675254054801580636256798657453673692\
-253297044467033402057939150379013860548523792131463034823280691750017926146347\
-801043426893645561724928
-
-122767323014713684557442729020466715341998628979505657684229704353296171367037\
-411913095007864820101872659840219130921806524108172783872770953561653684711973\
-479454179643287645605369250975305419617992099021774731734202032562350315172851\
-051599262846066242243199033423457222590739308232716875092267161669332374842441\
-033709536797052024535253802757116497594313048969994513468569485219924282091766\
-851846329473013959889350563668814777094023803991281324449096344061373189842310\
-871741164084844375029689516357660686194578391021426716624076942361493550508533\
-861399550840205032339721827602828852030988319397856726113467258843800562329430\
-483426147344429825470487171292720412312379846608842662888412711801364929075534\
-818168329263188893027952089413166874643840762633509856840863653983066792940213\
-615981187635685914972961287592408585810539623909712990570635984468050599860960\
-512964905651309756084205884506503676067264808969169777929868316240650077023896\
-894760534528160799876259475786563781048739978005708796388465947006869969100284\
-689080994589678971029788944714946472141702800482259868529720578240597839652038\
-728875955725197176220764696162940982167885743583683249625628077780902824328183\
-74495228282447765019033596:\
-283082173536961452407769367287009588671836460353139711498444702961741370094862\
-011919362480004256368129404666079436619904216918618576358529666421751914667003\
-648686045447747880559647245780193258060552049786949498294078220911769154403482\
-908464450865396980151361401805791636605204655629776473344275525486233868837654\
-501433355682653095016417719035352170849236981962605254681032350889807679228657\
-339208147715806690406387465389002665078364969570247320372545575712536893526096\
-517278830517647359380258024816671232166242001241410481278086926781257898013081\
-623490482712187047669526675639071632566007109964224561499766028796075148090060\
-545618251860746305966499156912240578118516616212427586765263064290914553251991\
-641994270282459721084617998517693605514612275446180927995505725880023127272143\
-601500020407740318153128538776377847303065487726738179793060222351672651663823\
-054718747795788173621305190670281468854814564570116550308527078268490992255929\
-481209653503937949692856923140789522621771444091467248525545206048901545244653\
-262667619527268597563252358886854105990994760797998401581306778593376341791731\
-440285931943901934144256322193361952107800421806522223414379385783308185156165\
-07689033284559929416074758498792929170030587:\
-283082173536961452469153043433279646787353116659594153835464397785237177659818\
-661054026761310410340714410331745089854935296952496434186788622266068517400579\
-240885232507071469837501294647114162007923357439633436620054629105599450527279\
-740389244862630771222680930688120594192414008068149907433840690365210881741743\
-846857755990277235960311971201926886313310952951680318585492339146870269215396\
-759461504081160296394494628641549546205125095528198582109027987454568908496029\
-962070998113081843662098771235215994804696257073308477621318206042458346428193\
-242515478359296470259869258418134143745031961740592781544065338146950565712515\
-326078506819405416707658951407364319478572687317419444755588049792008524391713\
-808772219799431376197529021362461552277579793584731616880678539864682700547933\
-466742802917267807579321999386872847709151127207367069300780092598046326561248\
-832751954534013855151171074388332239953795610143186608819739948460269781922356\
-863938940192628760449958975012128807894786416376349237477603408703788545661925\
-930621204425858917099005358055754940818130644409418247186249031361560712923265\
-544722433144984974271319644039354834499448150252253228585920113524299491272807\
-28623000311992597274812061327491555351592963:\
-104372357383334289986292817667461264194888954369610998823507948238075347582750\
-179881661718016987707637785329022428383715469624249390235187152429241257445235\
-258850953198988783088270577595190769476713205732866219414232072742837598151283\
-694959534314198355342706247445539543907543712705535414466574612728233719806223\
-813367021218729837802571201092950438145079274101691878770387029409773069908631\
-353687210459507570570586259868725186263827647246593910834911892286133474136611\
-542237382010734393804101196386154252527423038171322892872097999881257158611174\
-552310035022692919804579739123438303288739555767831506130647466900968524829438\
-350529108249582563822916466584531927859539821095609026737741099632977425910380\
-198316123276586310320474644339573235030521194348791812442163477336134214348778\
-212715456495354331909810003694433078521910564648710203835419537824437170091199\
-984664525310195383056694530264296910103441849858415643216798372431449897146206\
-540165255219228094920989283566347674683940415543997090494204105714745493013393\
-831895378181212991812371909011012564226988765855789665256408612798883702336477\
-689855438381742653178553273785136999588612901958521591618295172172732140693886\
-65063489343687416257234703396408707511017972
-
-522194442651902137132367021016973283365088710964886919844916237731280543021667\
-184627789987699144139338567518804019610971821764019430214861566469479361570954\
-373409672475865975826378842415779182383216248959219522583089722880566437953112\
-839500348472232142739344332182249839532962818445938123113862320657277226903093\
-327054024702213311597794328166699535158865783070284029112155303379373948117742\
-828750433052851737209792390388480633519127763108295558338163460454489768203949\
-943951986142761975262302207334578953183714354365492217896843414519795439426222\
-415176724294870127926261102538243233479188050889262389947148720154690006855364\
-156893184885514467708408648056103619852000369694323294031698211683273282845497\
-071594974092014156922155510503182678306186829920730336487161543412306431984657\
-522343323864700432556176184326306479522992522798848452612541828159035478186735\
-002693596898288329398889664027260078526565216719535981417164534841725235701031\
-631925309744004975349642218568396837904082718934690998632174389941826329032522\
-845318541469792725911607583280452178015448241183025931414034788831243325222675\
-396377622501556035123385573990237424494777698691436763366319719984800900377608\
-862721071289577116858421571465331047946047109574719845578047735:\
-101226168436990249832548694848521633437550115642738991813824538823515378979380\
-776009977671326701645443679508408552050890177203482181883822195286671585263626\
-084845268227842704623629921986284205514341294695305140730825603389858118415033\
-752399182713762563172288075742509059900299890911812246574035611228558271905248\
-742442147100194189383376568069084662825299315499233358067116658670334358506219\
-743457032738654662884430052884639263380485838159651138424187191765697416940347\
-452406630255665261133825717053590509770635829538804687441037437075189754522162\
-784724787336674917068283426031563390901011888479476080332618327236493351684503\
-570094093695559707776430327639749575128730780321400766975534127996811175711908\
-415377458716559199120810484882104949991740982639433724745622309633844499884701\
-846892554892900056951078640621746793570620217262279074150624229381892264499232\
-936382024355474137164860592629019224803473434211938006964560140372144239390336\
-974895383037829546803831648050410348373675399645097627049099617187123390437078\
-154613346873822277257688055822310172429299546029918681647044524535115679431862\
-521336686492308731734354415381358626822927668303902904423648318134084904509065\
-7697427563009331389461040980100618585268847388009439657449228287:\
-104438888138275678975664887447194279701713133250456660518822063036303422450717\
-933094093612514412421793336656911031056536739709976575096986716142925096154172\
-731805806017138014140133230398292983314505502205363333921547337814072417504221\
-488668985263219598051055173132624020659295385676407612150812492522572206533001\
-597613411407390487831154621600984730366928347514925191320805231875314018711926\
-108958730884607431991741280783658877084447973755533129611375100624549664607173\
-593004207049470166692311969166587519452308135813374412485340221090890373894092\
-547473219588151595817974438987375628117980455733550195635326163317296192091733\
-100632255613046181280276448489948180573483469974079672124146902276801610778660\
-886610601261687360060500328120394530433563029325101891648190581439619845488854\
-111504290823023818955212652041771624268130430972342217181240520628880135289459\
-727980006188945214421936203445014567819291218561438718674734422248294340000415\
-371982105892266044302071649095235053339823035550500783147251005929287324777164\
-498830989860510470393865137584837763438075028678783924768231642584082363258155\
-813646861557899903946629462961785279828997746823645764136794722968155251354538\
-4176355364270472266603290513654522383907518529754691654268223490:\
-934758354278336052364696838461442597967744986277020319834887979333018445832062\
-233986623238265813084552844580209031696784429400823397776870273881045920016346\
-267616112561945505979619905475988813557646379565575402321664246816363914496413\
-159591945732473903060746615296937923339942939160231506877132920668004619887290\
-097875968385600494526254981896171347486681707872148044189587898363930798490120\
-487948420471681027217101015820048148790357192889483843051220809971886629318351\
-683008420023383610964271479146229862470599428607334459129377337041532712134686\
-582961506648182279833738112277658115518336768935218767455723435647654249012998\
-781809105575400181554122940019038174912099395038845548799585508035099650377958\
-572177290022044670517072895740049720526330041448799254506126176394759697363862\
-351020178962460276320485508232548625696854159130325486668112368045217104212832\
-115042860486298021973158447248106503841184738709849961483251847777163668567753\
-680724029515132763905427005238717158628034354872542121828742537525579594955627\
-525627790483249000185291166968052200430258105646065423159234684964457417500990\
-758025816296882099734588259162326941283422448528935372072615562344496110828342\
-614627532773534491086926402957418489766158166431144861740676905
-
-# Format number:is_prime, where is_prime is 0 or 1
-[PrimeTest]
-0:0
-1:0
-2:1
-3:1
-4:0
-255:0
-257:1
-65517:0
-65521:1
-65537:1
-
-# This one passes Miller-Rabin with a base of 2, but not with most others
-4294967297:0
-
-# Random ones
-10416536965533130067:1
-
-62073521899194104903553565787:1
-
-170585900781008069215236465296032411499:1
-
-1443993313735051633697456797423139085424112074517:1
-
-10771372029656662585340604592252023412983364818055143344382694346546\
-2298290643:1
-
-11771372029656662585340604592252023412983364818055143344382694346546\
-2298290643:0
-
-42588518477191145729:0
-
-# The following are of the form p1*p2*p3*...*pn + 1 where px is the x'th prime
-# This is to make sure the number gets past any checks for small prime factors,
-# and tests the Miller-Rabin routines. It would be nice to look up or search
-# for some Carmichael numbers to help this testing some.
-32589158477190044731:0
-
-4014476939333036189094441199026045136645885247731:0
-
-1907826688958019501360189182099275775721983966835701205590751690\
-4309700014933909014729740191:0
-
-4445236185272185438169240794291312557432222642727183809026451438\
-704160103479600800432029464271:0
-
-6107692946593319609927894338899785515035614388823837148866549657\
-4810764573680243467182799164806563626522181311132959748531230211:0
-
-6989612506894284794136067796445539076219364950255126280242854713\
-9923075880112964253713561700013194221462347575861905534037645370\
-21369947456703810795390696338067840821591:0
-
-2577426147548683169379880845613862450845254401055092509543183257\
-2701791887072337189992932234179329410389241899414841054215169960\
-1546741832617953638436279944072980418788682453341495300190580109\
-0622787969540076319408964006231:0
-
-# Carmichael numbers
-232250619601:0
-9746347772161:0
-340561:0
diff --git a/src/tests/data/ocb_long.vec b/src/tests/data/ocb_long.vec
new file mode 100644
index 000000000..046ee3208
--- /dev/null
+++ b/src/tests/data/ocb_long.vec
@@ -0,0 +1,36 @@
+
+Keylen = 128
+Taglen = 128
+Output = 67E944D23256C5E0B6C61FA22FDF1EA2
+
+Keylen = 192
+Taglen = 128
+Output = F673F2C3E7174AAE7BAE986CA9F29E17
+
+Keylen = 256
+Taglen = 128
+Output = D90EB8E9C977C88B79DD793D7FFA161C
+
+Keylen = 128
+Taglen = 96
+Output = 77A3D8E73589158D25D01209
+
+Keylen = 192
+Taglen = 96
+Output = 05D56EAD2752C86BE6932C5E
+
+Keylen = 256
+Taglen = 96
+Output = 5458359AC23B0CBA9E6330DD
+
+Keylen = 128
+Taglen = 64
+Output = 192C9B7BD90BA06A
+
+Keylen = 192
+Taglen = 64
+Output = 0066BC6E0EF34E24
+
+Keylen = 256
+Taglen = 64
+Output = 7D4EA5D445501CBE
diff --git a/src/tests/data/passhash9.vec b/src/tests/data/passhash9.vec
new file mode 100644
index 000000000..908accc25
--- /dev/null
+++ b/src/tests/data/passhash9.vec
@@ -0,0 +1,3 @@
+
+Password = 736563726574
+Passhash = $9$AAAKhiHXTIUhNhbegwBXJvk03XXJdzFMy+i3GFMIBYKtthTTmXZA
diff --git a/src/tests/data/pubkey/dsa.vec b/src/tests/data/pubkey/dsa.vec
index 73b4efe38..a366e5574 100644
--- a/src/tests/data/pubkey/dsa.vec
+++ b/src/tests/data/pubkey/dsa.vec
@@ -1,12 +1,12 @@
# RFC 6979 A.2.1: DSA, 1024 bits
-P = 86F5CA03DCFEB225063FF830A0C769B9DD9D6153AD91D7CE27F787C43278B447E6533B86B18BED6E8A48B784A14C252C5BE0DBF60B86D6385BD2F12FB763ED8873ABFD3F5BA2E0A8C0A59082EAC056935E529DAF7C610467899C77ADEDFC846C881870B7B19B2B58F9BE0521A17002E3BDD6B86685EE90B3D9A1B02B782B1779
+P = 0x86F5CA03DCFEB225063FF830A0C769B9DD9D6153AD91D7CE27F787C43278B447E6533B86B18BED6E8A48B784A14C252C5BE0DBF60B86D6385BD2F12FB763ED8873ABFD3F5BA2E0A8C0A59082EAC056935E529DAF7C610467899C77ADEDFC846C881870B7B19B2B58F9BE0521A17002E3BDD6B86685EE90B3D9A1B02B782B1779
-Q = 996F967F6C8E388D9E28D01E205FBA957A5698B1
+Q = 0x996F967F6C8E388D9E28D01E205FBA957A5698B1
-G = 07B0F92546150B62514BB771E2A0C0CE387F03BDA6C56B505209FF25FD3C133D89BBCD97E904E09114D9A7DEFDEADFC9078EA544D2E401AEECC40BB9FBBF78FD87995A10A1C27CB7789B594BA7EFB5C4326A9FE59A070E136DB77175464ADCA417BE5DCE2F40D10A46A3A3943F26AB7FD9C0398FF8C76EE0A56826A8A88F1DBD
+G = 0x07B0F92546150B62514BB771E2A0C0CE387F03BDA6C56B505209FF25FD3C133D89BBCD97E904E09114D9A7DEFDEADFC9078EA544D2E401AEECC40BB9FBBF78FD87995A10A1C27CB7789B594BA7EFB5C4326A9FE59A070E136DB77175464ADCA417BE5DCE2F40D10A46A3A3943F26AB7FD9C0398FF8C76EE0A56826A8A88F1DBD
-X = 411602CB19A6CCC34494D79D98EF1E7ED5AF25F7
+X = 0x411602CB19A6CCC34494D79D98EF1E7ED5AF25F7
Msg = 73616D706C65
@@ -44,13 +44,13 @@ Signature = 8EA47E475BA8AC6F2D821DA3BD212D11A3DEB9A07C670C7AD72B6C050C109E179000
# RFC 6979 A.2.2: DSA, 2048 bits
-P = 9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44FFE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE235567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA153E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B
+P = 0x9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44FFE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE235567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA153E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B
-Q = F2C3119374CE76C9356990B465374A17F23F9ED35089BD969F61C6DDE9998C1F
+Q = 0xF2C3119374CE76C9356990B465374A17F23F9ED35089BD969F61C6DDE9998C1F
-G = 5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C46A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7
+G = 0x5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C46A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7
-X = 69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC
+X = 0x69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC
Msg = 73616D706C65
diff --git a/src/tests/data/pubkey/elgamal.vec b/src/tests/data/pubkey/elgamal.vec
index bd1324930..5cfbacdee 100644
--- a/src/tests/data/pubkey/elgamal.vec
+++ b/src/tests/data/pubkey/elgamal.vec
@@ -4,67 +4,67 @@ G = 13
X = 1510837665211600837455333225484573368412905214721958306259132011740929687444
Msg = 02AD1D776D591520E4D8BEF8B21CC2F54FB4EB788E52ECEBE13564435DA66284D51A6A6696E615EF599786CE4CBEFAFF066E0A1CD8868454EB5CE0CA99241B29E1D1492CF2712C2C101B3F3779034683AD8271098C2E3FBAA83901A97D9645FA5815AF79F4F638ECBE09020003F434D708914899C668F34830E70F4CAF0803
Nonce = 0A5842A8D0C1B07E5DE6FD3E0C6B1108523D4D35417F
-Ciphertext 5B99F58B48F3D473327075F2FF4EEA3C8C1FEB0B241F042864610D6FC512A81F431A965724195DB71C3B84B6B9F1DFAE0DAE60E7CDA957703D10FCCDA45CDD0EF8C8F76AA4F51F3EDAD8E5085B97D69523A3EAC89D67CDFDDCF0A30491A98BE2FD6C5E69C3A2C95300B9DB4EDF2111E7613EF7B2CA430D0CFFBDECF6A7BE592A853B404B6910C48A0204ED3430691E766FBAF21A428B9F833C5932C053C616EEB59850150A22331A8FB5AF2065B595E4F08881B1DB7CB85A28A33F4449890739679CCAA431A9205210995BEA68759B475BE4183A975C9D042FBBEDF589AB6AF017D7523B2CC90CD63526BC584F1E9EF42ABAAA9238987D7F73B94E323C6AADFD
+Ciphertext = 5B99F58B48F3D473327075F2FF4EEA3C8C1FEB0B241F042864610D6FC512A81F431A965724195DB71C3B84B6B9F1DFAE0DAE60E7CDA957703D10FCCDA45CDD0EF8C8F76AA4F51F3EDAD8E5085B97D69523A3EAC89D67CDFDDCF0A30491A98BE2FD6C5E69C3A2C95300B9DB4EDF2111E7613EF7B2CA430D0CFFBDECF6A7BE592A853B404B6910C48A0204ED3430691E766FBAF21A428B9F833C5932C053C616EEB59850150A22331A8FB5AF2065B595E4F08881B1DB7CB85A28A33F4449890739679CCAA431A9205210995BEA68759B475BE4183A975C9D042FBBEDF589AB6AF017D7523B2CC90CD63526BC584F1E9EF42ABAAA9238987D7F73B94E323C6AADFD
P = 1541287358797997024335652872773425159872421808416662301794871595911973385718041854467851087853175356350298847849929853669980047096240555092681165983790725605204837589691602540741068782404825906414885161661820441988899240406981724303
G = 5
X = 1344717445208905302019700797220481877896877304443340806021921711564
Msg = 02C1ED6A171875F055809F12BC61829961CC740935C6DCC468FA663E8D1A7DE9E0555E3EA99476436743FC5C76D3E041055FAEB7641907F8E2F1F94061B22E72B7CD39EDD7A6367828CCDC000301CEA7D91CB1E8A3E20DC85FAA23EF6D08E6
Nonce = F42F854C10C9DD14A6712594A31326A1FD2CF5
-Ciphertext 9E47FB001BDDB12F2D8E0FA5501A7EAC1B185FDFC7D2FF3E4461B0D75D626F5156DEDD4D25F13C6C1F5F9A1F916058045705F5E82F748E9B6F0DC95D572B8DC2770159092EECA13946F0522FE2A859705009B615818A1B4F98E8DD38CF00DE746ABD5F3852D93F8D9299DE18EB763F11E41A8B9660C5F056538EED431BB8E2199D9012F50C7FBEF5AAD35ECCD7F141CD9AC6553315A2699D6718F50EBDCEAE62A11ACC466E8533EDBAF13C15B5532B323EBF283B108F892DBFCEA21231DFD548
+Ciphertext = 9E47FB001BDDB12F2D8E0FA5501A7EAC1B185FDFC7D2FF3E4461B0D75D626F5156DEDD4D25F13C6C1F5F9A1F916058045705F5E82F748E9B6F0DC95D572B8DC2770159092EECA13946F0522FE2A859705009B615818A1B4F98E8DD38CF00DE746ABD5F3852D93F8D9299DE18EB763F11E41A8B9660C5F056538EED431BB8E2199D9012F50C7FBEF5AAD35ECCD7F141CD9AC6553315A2699D6718F50EBDCEAE62A11ACC466E8533EDBAF13C15B5532B323EBF283B108F892DBFCEA21231DFD548
P = 13232376895198612407547930718267435757728527029623408872245156039757713029036368719146452186041204237350521785240337048752071462798273003935646236777459223
G = 11629401773565540073100961473632977008134185076958364415809981826641612629974728305105606061133984394938666464842000720534465163992699133277631369246002549
X = 175607362627753240470186183617696577774
Msg = 47E586A7E7D98C116A6F553F652E57BF
Nonce = BEF5E7EFAA76C52A8ECEE604EDAFD31B
-Ciphertext CD70DE085B0C586B4E64097EA3AB4CE0B60A71B0F640FE4468F4F940412EDBDD9035EEC602530CFF81B2CDC35805264A866E4689DDBADC3438575B6337118BB23A5AB7710F85F2A4E1E0DBEC5652FEF73C868747ECB7043BA08241A0879A2DC588D3EC14ED552E62B1B111646FF4DFA9050754240A46A840EA5EB1D97712F2BB
+Ciphertext = CD70DE085B0C586B4E64097EA3AB4CE0B60A71B0F640FE4468F4F940412EDBDD9035EEC602530CFF81B2CDC35805264A866E4689DDBADC3438575B6337118BB23A5AB7710F85F2A4E1E0DBEC5652FEF73C868747ECB7043BA08241A0879A2DC588D3EC14ED552E62B1B111646FF4DFA9050754240A46A840EA5EB1D97712F2BB
P = 13232376895198612407547930718267435757728527029623408872245156039757713029036368719146452186041204237350521785240337048752071462798273003935646236777459223
G = 11629401773565540073100961473632977008134185076958364415809981826641612629974728305105606061133984394938666464842000720534465163992699133277631369246002549
X = 226260657342880764984259695048075261500
Msg = 74BC8D009250F4CD2E08BC556EE01449
Nonce = A2951BE393736E39E9D209FE978C7546
-Ciphertext 6D6ED1C6E519C628CACC7981A5BBE487F6E013B26448D711911698CEEAA4F746182A716602183A746FC35B022BD7B27EF079F7164309653D148D0CE91907FF6C4A9001A0CCA2A0A163F3F93200C2E40A957919CB84AC35B928E026F1827E6D4A9B986B592BE39861538414D5EA6980248FD3C3C0CDEE372F392D5AC46DB8EEFB
+Ciphertext = 6D6ED1C6E519C628CACC7981A5BBE487F6E013B26448D711911698CEEAA4F746182A716602183A746FC35B022BD7B27EF079F7164309653D148D0CE91907FF6C4A9001A0CCA2A0A163F3F93200C2E40A957919CB84AC35B928E026F1827E6D4A9B986B592BE39861538414D5EA6980248FD3C3C0CDEE372F392D5AC46DB8EEFB
P = 13232376895198612407547930718267435757728527029623408872245156039757713029036368719146452186041204237350521785240337048752071462798273003935646236777459223
G = 11629401773565540073100961473632977008134185076958364415809981826641612629974728305105606061133984394938666464842000720534465163992699133277631369246002549
X = 190989497955271245954961490592364802400
Msg = 01AFE1A93EDB9CD3E3715523C952478D
Nonce = 9500DDCD404618F64A2063BC19941A6E
-Ciphertext 0636C3F1C63C54CAB4B48B6EF0ECBFF00BA6AB70DF4DB6266D0785351B37279D41D957D16CAB48C64035DCB2A1CD75BAC298C8ECAE8057D87071EADAA5DA6E2B69B5F353B5753F7E24DA81ABAD40059CD73CFA6E78CAB1C7DA418D55E5DBD42FA4F2B876A25B4AF63588C80E0DB11E8BAB1531960E951C08C1A68C8FAE0DA87C
+Ciphertext = 0636C3F1C63C54CAB4B48B6EF0ECBFF00BA6AB70DF4DB6266D0785351B37279D41D957D16CAB48C64035DCB2A1CD75BAC298C8ECAE8057D87071EADAA5DA6E2B69B5F353B5753F7E24DA81ABAD40059CD73CFA6E78CAB1C7DA418D55E5DBD42FA4F2B876A25B4AF63588C80E0DB11E8BAB1531960E951C08C1A68C8FAE0DA87C
P = 1418488780399624169246918906980830188668962659968489177172519612007411971965075884911751185624649475197807409457369163882960326663412481439463507475025544888587052733646843233033458377686354235239579046252542291754237282749312023983
G = 1351977104923085061876231022324913317418268765766371251774974499254352282996737121345129752664271877383194755574993089982460597274051441610498438524702048238124542105329402087161253933648442955133245175046317041420863434958965806440
X = 5693645782587047029911723275175292231768316497
Msg = 58E72BD0F04B11
Nonce = EF07721FF6B28A8A3B4EBC95C16B13A83649B7
-Ciphertext C7B6ACADBBCFD3A34EDA31CE9CA7F7889FBB2DF5C6C25793EB974591BF0EDE93637B6A95E8075BDB2A987039D92487665465C98AAD0C123FA00BB9736170E78069AA32DFBEB07099A0B7D439AA807A2D3D6F9F913EBC673F9F8CD5D3C0E9DD0D988EAC4D8204928C2DA8ECD1FA3A598FCBFFEF5017DB8542D123CF69E8C92EB956F10DC995AE6B6564967D5C12A07BA35607C54CC3F10A36FF3603DD7CC1490664610002977CE8C4A4EFFBD1421C902D4D8DFF81D014E1AB55F239E0F2FD28AB
+Ciphertext = C7B6ACADBBCFD3A34EDA31CE9CA7F7889FBB2DF5C6C25793EB974591BF0EDE93637B6A95E8075BDB2A987039D92487665465C98AAD0C123FA00BB9736170E78069AA32DFBEB07099A0B7D439AA807A2D3D6F9F913EBC673F9F8CD5D3C0E9DD0D988EAC4D8204928C2DA8ECD1FA3A598FCBFFEF5017DB8542D123CF69E8C92EB956F10DC995AE6B6564967D5C12A07BA35607C54CC3F10A36FF3603DD7CC1490664610002977CE8C4A4EFFBD1421C902D4D8DFF81D014E1AB55F239E0F2FD28AB
P = 1418488780399624169246918906980830188668962659968489177172519612007411971965075884911751185624649475197807409457369163882960326663412481439463507475025544888587052733646843233033458377686354235239579046252542291754237282749312023983
G = 1351977104923085061876231022324913317418268765766371251774974499254352282996737121345129752664271877383194755574993089982460597274051441610498438524702048238124542105329402087161253933648442955133245175046317041420863434958965806440
X = 4008521039270359712424267366152273661245582878
Msg = C37AA41207A357DBCCFBE93DC45C5BD91D29FD29CBA29B26AC437A9B560C3BEA
Nonce = A36338E4D7815E6A4B178E951BEF073C6D5A7F
-Ciphertext D824C94623313298600CC20203F8A40006CAFCFC8F883C99AC09DBAE4B95E6DB9FB5737E24D9D7E39B603893076BC81A2BC0C0D608B32B353972B57066535DAAC49E3F7F2A0E243618EEE01C5AB3AFAE1D55E3A1DB33CF713E5187AD51D55144B1A108354ECA651E55F85F253FE73C1C15FA5EDDDA47467BD0425F09E3C4156548E71896659C618B84FD72BA176E2DEEECD8B15F2C05F870697EA464B88273742BD6ECBA5164424F34EBB9E13E31683A16712901818C7E5F502720FBCB075EA1
+Ciphertext = D824C94623313298600CC20203F8A40006CAFCFC8F883C99AC09DBAE4B95E6DB9FB5737E24D9D7E39B603893076BC81A2BC0C0D608B32B353972B57066535DAAC49E3F7F2A0E243618EEE01C5AB3AFAE1D55E3A1DB33CF713E5187AD51D55144B1A108354ECA651E55F85F253FE73C1C15FA5EDDDA47467BD0425F09E3C4156548E71896659C618B84FD72BA176E2DEEECD8B15F2C05F870697EA464B88273742BD6ECBA5164424F34EBB9E13E31683A16712901818C7E5F502720FBCB075EA1
P = 1418488780399624169246918906980830188668962659968489177172519612007411971965075884911751185624649475197807409457369163882960326663412481439463507475025544888587052733646843233033458377686354235239579046252542291754237282749312023983
G = 1351977104923085061876231022324913317418268765766371251774974499254352282996737121345129752664271877383194755574993089982460597274051441610498438524702048238124542105329402087161253933648442955133245175046317041420863434958965806440
X = 5316253934868425065538718034591876558413406625
Msg = 36FDC0501B44AF
Nonce = 832BC01DB63F958D47B6962AEAA74C0831A6AB
-Ciphertext 62E46CDF100BADF4419215256BEC8427DD0388D1B60B5A8675532C0934351BA0036AF58032AB6C4DB829F1A0C8217FBF2CB9C10A5C60FF285919BCAF238E89FBAA4771CAD13D4A69AB2C1FFF0A44D2F9287F1E70D58210AE859074B3969EE800A9D1507BA48582BD1E03CC234B0CB11408BE0932763EDC99CA4BEC6E496A452237F920972C629714EA2F1FF212460C23B66DB56BC73E94743D32D2CD3536A17A136F56D7F7C24E3B8F102F48BBB21633279D3E584E71DC37B436104CA69A6BB3
+Ciphertext = 62E46CDF100BADF4419215256BEC8427DD0388D1B60B5A8675532C0934351BA0036AF58032AB6C4DB829F1A0C8217FBF2CB9C10A5C60FF285919BCAF238E89FBAA4771CAD13D4A69AB2C1FFF0A44D2F9287F1E70D58210AE859074B3969EE800A9D1507BA48582BD1E03CC234B0CB11408BE0932763EDC99CA4BEC6E496A452237F920972C629714EA2F1FF212460C23B66DB56BC73E94743D32D2CD3536A17A136F56D7F7C24E3B8F102F48BBB21633279D3E584E71DC37B436104CA69A6BB3
P = 178011905478542266528237562450159990145232156369120674273274450314442865788737020770612695252123463079567156784778466449970650770920727857050009668388144034129745221171818506047231150039301079959358067395348717066319802262019714966524135060945913707594956514672855690606794135837542707371727429551343320695239
G = 49567166504681114998529684425585849617514862026978329597099192087961538717407709177883083441369264146939535263894140299406849834767828526204179623557679393249247253593623658376992386256295047165071989556654741504656225128772294708626157371448610928885819291350567633953878147205134001752476855481804967677085
X = 3756315909532643155590215634844150624450334340186095
Msg = DF72B687F62AFEA3A51195EE876E4C87708F7ABB8D2D5DD72B68256DAC6D
Nonce = 0B333C9C486C5F3A96F37D00133ADD18113376C9BE76
-Ciphertext 4156CF437A39C415B212AAA34C9AACAFA3F3113F53BB75E0BD3D759089E21754EF89B4BA1A8B37E5EDA13F8A2F87D16F03F3B6FE19A5CF799B17D83F7B5E9A225F324AAD7D46E80A1DAFCA337A3F500930A7831D1F3785763EB9A6994063CED033177E1CA2770B751B3053C1445ADFEAED790E49E4685A05B9563D1EF32BD321971D541B525D648EA7C8741D8FA7E46293D46A0F4345BE73EA4FAF1E4C16BCBE11C53BA0FCBA2975BD37F11FE5ADA8731CAED3C403EA6E43AE47ADAA7E28433404AD3ADE6AA8E12BFC374BADAAFB167F3AAF91DC6F8398003E5F8528E8D4773F800D48C8EDDAEDD72A3870E97679F946CE27FB692BC11677757A28F3899A3DA8
+Ciphertext = 4156CF437A39C415B212AAA34C9AACAFA3F3113F53BB75E0BD3D759089E21754EF89B4BA1A8B37E5EDA13F8A2F87D16F03F3B6FE19A5CF799B17D83F7B5E9A225F324AAD7D46E80A1DAFCA337A3F500930A7831D1F3785763EB9A6994063CED033177E1CA2770B751B3053C1445ADFEAED790E49E4685A05B9563D1EF32BD321971D541B525D648EA7C8741D8FA7E46293D46A0F4345BE73EA4FAF1E4C16BCBE11C53BA0FCBA2975BD37F11FE5ADA8731CAED3C403EA6E43AE47ADAA7E28433404AD3ADE6AA8E12BFC374BADAAFB167F3AAF91DC6F8398003E5F8528E8D4773F800D48C8EDDAEDD72A3870E97679F946CE27FB692BC11677757A28F3899A3DA8
P = 178011905478542266528237562450159990145232156369120674273274450314442865788737020770612695252123463079567156784778466449970650770920727857050009668388144034129745221171818506047231150039301079959358067395348717066319802262019714966524135060945913707594956514672855690606794135837542707371727429551343320695239
G = 49567166504681114998529684425585849617514862026978329597099192087961538717407709177883083441369264146939535263894140299406849834767828526204179623557679393249247253593623658376992386256295047165071989556654741504656225128772294708626157371448610928885819291350567633953878147205134001752476855481804967677085
X = 4304232149632055597449717737864742436448127103739097
Msg = F73BB7E5C8A5619380
Nonce = 0AD9527B09EAD1E59B4A1CAF58C861B69A856AB8AA80
-Ciphertext C9881464A37749949D66D75CD9B7A8ACAD33DD1FAC7561F684E9CB5343D2ED15969D7EDB4135518B50F0FEC9A9559C1D5E44DAB42C14BBDE2D2711EA4D02D7F27D1A9BCFEC9E8B73FA64BA3C54707FDDE7D5BE695E17FB9D259FB576FD4E57D66C8F727DC236E2A6E9FD01709D34B8D09F7DD3890F003EBE616042B4E0A8A00F6C3F34DE7E002FE72A84AF8D014D64E8CD08B9B56CC3A6BBE6F966B92105A92C5ABF4F2BF735670622F6213FE9739FAD65692E1C0EBF708A47E18600A22972A5A3DA0F22D11C581D46F734151A083FF757E961351EB183B467A859FBB9ED1DAC396FA405701FD6E3A62EB126E93648C3C6DFA9C4DBF3C005880F4799F66B310E
+Ciphertext = C9881464A37749949D66D75CD9B7A8ACAD33DD1FAC7561F684E9CB5343D2ED15969D7EDB4135518B50F0FEC9A9559C1D5E44DAB42C14BBDE2D2711EA4D02D7F27D1A9BCFEC9E8B73FA64BA3C54707FDDE7D5BE695E17FB9D259FB576FD4E57D66C8F727DC236E2A6E9FD01709D34B8D09F7DD3890F003EBE616042B4E0A8A00F6C3F34DE7E002FE72A84AF8D014D64E8CD08B9B56CC3A6BBE6F966B92105A92C5ABF4F2BF735670622F6213FE9739FAD65692E1C0EBF708A47E18600A22972A5A3DA0F22D11C581D46F734151A083FF757E961351EB183B467A859FBB9ED1DAC396FA405701FD6E3A62EB126E93648C3C6DFA9C4DBF3C005880F4799F66B310E
diff --git a/src/tests/data/rfc3394.vec b/src/tests/data/rfc3394.vec
new file mode 100644
index 000000000..29192789c
--- /dev/null
+++ b/src/tests/data/rfc3394.vec
@@ -0,0 +1,26 @@
+
+
+Key = 00112233445566778899AABBCCDDEEFF
+KEK = 000102030405060708090A0B0C0D0E0F
+Output = 1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5
+
+Key = 00112233445566778899AABBCCDDEEFF
+KEK = 000102030405060708090A0B0C0D0E0F1011121314151617
+Output = 96778B25AE6CA435F92B5B97C050AED2468AB8A17AD84E5D
+
+Key = 00112233445566778899AABBCCDDEEFF
+KEK = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Output = 64E8C3F9CE0F5BA263E9777905818A2A93C8191E7D6E8AE7
+
+Key = 00112233445566778899AABBCCDDEEFF0001020304050607
+KEK = 000102030405060708090A0B0C0D0E0F1011121314151617
+Output = 031D33264E15D33268F24EC260743EDCE1C6C7DDEE725A936BA814915C6762D2
+
+Key = 00112233445566778899AABBCCDDEEFF0001020304050607
+KEK = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Output = A8F9BC1612C68B3FF6E6F4FBE30E71E4769C8B80A32CB8958CD5D17D6B254DA1
+
+Key = 00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F
+KEK = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Output = 28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21
+
diff --git a/src/tests/data/rfc6979.vec b/src/tests/data/rfc6979.vec
new file mode 100644
index 000000000..a1c54b29b
--- /dev/null
+++ b/src/tests/data/rfc6979.vec
@@ -0,0 +1,14 @@
+
+[SHA-256]
+# From RFC 6979 A.1.1
+Q = 0x4000000000000000000020108A2E0CC0D99F8A5EF
+X = 0x09A4D6792295A7F730FC3F2B49CBC0F62E862272F
+H = 0x01795EDF0D54DB760F156D0DAC04C0322B3A204224
+K = 0x23AF4074C90A02B3FE61D286D5C87F425E6BDD81B
+
+[SHA-1]
+# DSA 1024 bits test #1
+Q = 0x996F967F6C8E388D9E28D01E205FBA957A5698B1
+X = 0x411602CB19A6CCC34494D79D98EF1E7ED5AF25F7
+H = 0x8151325DCDBAE9E0FF95F9F9658432DBEDFDB209
+K = 0x7BDB6B0FF756E1BB5D53583EF979082F9AD5BD5B
diff --git a/src/tests/data/transform.vec b/src/tests/data/transform.vec
deleted file mode 100644
index e69de29bb..000000000
--- a/src/tests/data/transform.vec
+++ /dev/null
diff --git a/src/tests/data/util.vec b/src/tests/data/util.vec
new file mode 100644
index 000000000..a1e857b10
--- /dev/null
+++ b/src/tests/data/util.vec
@@ -0,0 +1,58 @@
+
+[round_up]
+In1 = 1
+In2 = 10
+Out = 10
+
+In1 = 3
+In2 = 10
+Out = 10
+
+In1 = 9
+In2 = 10
+Out = 10
+
+In1 = 10
+In2 = 10
+Out = 10
+
+In1 = 1
+In2 = 4
+Out = 4
+
+In1 = 3
+In2 = 4
+Out = 4
+
+In1 = 4
+In2 = 4
+Out = 4
+
+In1 = 9
+In2 = 4
+Out = 12
+
+In1 = 11
+In2 = 4
+Out = 12
+
+In1 = 0
+In2 = 2
+Out = 0
+
+In1 = 0
+In2 = 10000
+Out = 0
+
+[round_down]
+In1 = 9
+In2 = 10
+Out = 0
+
+In1 = 10
+In2 = 10
+Out = 10
+
+In1 = 11
+In2 = 10
+Out = 10
diff --git a/src/tests/test_aead.cpp b/src/tests/test_aead.cpp
index 5fe4011fb..a9545a736 100644
--- a/src/tests/test_aead.cpp
+++ b/src/tests/test_aead.cpp
@@ -7,147 +7,131 @@
#include "tests.h"
#if defined(BOTAN_HAS_AEAD_MODES)
-
-#include <botan/hex.h>
#include <botan/aead.h>
-#include <iostream>
-#include <fstream>
-#include <memory>
+#endif
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-size_t aead_test(const std::string& algo,
- const std::string& input,
- const std::string& expected,
- const std::string& nonce_hex,
- const std::string& ad_hex,
- const std::string& key_hex)
- {
- const auto nonce = hex_decode_locked(nonce_hex);
- const auto ad = hex_decode_locked(ad_hex);
- const auto key = hex_decode_locked(key_hex);
-
- std::unique_ptr<Cipher_Mode> enc(get_aead(algo, ENCRYPTION));
- std::unique_ptr<Cipher_Mode> dec(get_aead(algo, DECRYPTION));
-
- if(!enc || !dec)
- throw std::runtime_error("Unknown AEAD '" + algo + "'");
-
- enc->set_key(key);
- dec->set_key(key);
-
- if(auto aead_enc = dynamic_cast<AEAD_Mode*>(enc.get()))
- aead_enc->set_associated_data_vec(ad);
- if(auto aead_dec = dynamic_cast<AEAD_Mode*>(dec.get()))
- aead_dec->set_associated_data_vec(ad);
+#if defined(BOTAN_HAS_AEAD_MODES)
- size_t fail = 0;
+class AEAD_Tests : public Text_Based_Test
+ {
+ public:
+ AEAD_Tests() :
+ Text_Based_Test(Test::data_dir("aead"), {"Key", "Nonce", "In", "Out"}, {"AD"})
+ {}
- const auto pt = hex_decode_locked(input);
- const auto expected_ct = hex_decode_locked(expected);
+ Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
+ {
+ const std::vector<uint8_t> key = get_req_bin(vars, "Key");
+ const std::vector<uint8_t> nonce = get_opt_bin(vars, "Nonce");
+ const std::vector<uint8_t> input = get_req_bin(vars, "In");
+ const std::vector<uint8_t> expected = get_req_bin(vars, "Out");
+ const std::vector<uint8_t> ad = get_opt_bin(vars, "AD");
- auto vec = pt;
- enc->start(nonce);
- // should first update if possible
- enc->finish(vec);
+ Test::Result result(algo);
- if(vec != expected_ct)
- {
- std::cout << algo << " got ct " << hex_encode(vec) << " expected " << expected << std::endl;
- ++fail;
- }
+ std::unique_ptr<Botan::AEAD_Mode> enc(Botan::get_aead(algo, Botan::ENCRYPTION));
+ std::unique_ptr<Botan::AEAD_Mode> dec(Botan::get_aead(algo, Botan::DECRYPTION));
- vec = expected_ct;
+ if(!enc || !dec)
+ {
+ result.note_missing(algo);
+ return result;
+ }
- dec->start(nonce);
- dec->finish(vec);
+ enc->set_key(key);
+ enc->set_associated_data_vec(ad);
+ enc->start(nonce);
- if(vec != pt)
- {
- std::cout << algo << " got pt " << hex_encode(vec) << " expected " << input << std::endl;
- ++fail;
- }
+ Botan::secure_vector<uint8_t> buf(input.begin(), input.end());
+ // TODO: should first update if possible
+ enc->finish(buf);
- if(enc->authenticated())
- {
- vec = expected_ct;
- vec[0] ^= 1;
- dec->start(nonce);
- try
- {
- dec->finish(vec);
- std::cout << algo << " accepted message with modified message" << std::endl;
- ++fail;
- }
- catch(...) {}
+ result.test_eq("encrypt", buf, expected);
- if(nonce.size())
- {
- auto bad_nonce = nonce;
- bad_nonce[0] ^= 1;
- vec = expected_ct;
+ buf.assign(expected.begin(), expected.end());
- dec->start(bad_nonce);
+ dec->set_key(key);
+ dec->set_associated_data_vec(ad);
+ dec->start(nonce);
+ dec->finish(buf);
- try
+ if(enc->authenticated())
{
- dec->finish(vec);
- std::cout << algo << " accepted message with modified nonce" << std::endl;
- ++fail;
+ const std::vector<byte> mutated_input = mutate_vec(expected, true);
+ buf.assign(mutated_input.begin(), mutated_input.end());
+
+ dec->start(nonce);
+
+ try
+ {
+ dec->finish(buf);
+ result.test_failure("accepted modified message", mutated_input);
+ }
+ catch(Botan::Integrity_Failure& e)
+ {
+ result.test_note("correctly rejected modified message");
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure("unexpected error while rejecting modified message", e.what());
+ }
}
- catch(...) {}
- }
- if(auto aead_dec = dynamic_cast<AEAD_Mode*>(dec.get()))
- {
- auto bad_ad = ad;
+ if(nonce.size() > 0)
+ {
+ buf.assign(expected.begin(), expected.end());
+ std::vector<byte> bad_nonce = mutate_vec(nonce);
+
+ dec->start(bad_nonce);
+
+ try
+ {
+ dec->finish(buf);
+ result.test_failure("accepted message with modified nonce", bad_nonce);
+ }
+ catch(Botan::Integrity_Failure& e)
+ {
+ result.test_note("correctly rejected modified nonce");
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure("unexpected error while rejecting modified nonce", e.what());
+ }
+ }
- if(ad.size())
- bad_ad[0] ^= 1;
- else
- bad_ad.push_back(0);
+ const std::vector<byte> bad_ad = mutate_vec(ad, true);
- aead_dec->set_associated_data_vec(bad_ad);
+ dec->set_associated_data_vec(bad_ad);
- vec = expected_ct;
dec->start(nonce);
try
{
- dec->finish(vec);
- std::cout << algo << " accepted message with modified AD" << std::endl;
- ++fail;
+ buf.assign(expected.begin(), expected.end());
+ dec->finish(buf);
+ result.test_failure("accepted message with modified ad", bad_ad);
+ }
+ catch(Botan::Integrity_Failure& e)
+ {
+ result.test_note("correctly rejected modified ad");
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure("unexpected error while rejecting modified nonce", e.what());
}
- catch(...) {}
- }
- }
-
- return fail;
- }
-
-}
-
-size_t test_aead()
- {
- auto test = [](const std::string& input)
- {
- std::ifstream vec(input);
- return run_tests_bb(vec, "AEAD", "Out", true,
- [](std::map<std::string, std::string> m)
- {
- return aead_test(m["AEAD"], m["In"], m["Out"],
- m["Nonce"], m["AD"], m["Key"]);
- });
- };
+ return result;
+ }
+ };
- return run_tests_in_dir(TEST_DATA_DIR "/aead", test);
- }
+BOTAN_REGISTER_TEST("aead", AEAD_Tests);
-#else
+#endif
-SKIP_TEST(aead);
+}
-#endif // BOTAN_HAS_AEAD_MODES
+}
diff --git a/src/tests/test_bigint.cpp b/src/tests/test_bigint.cpp
index e6aa4a434..96ec035fe 100644
--- a/src/tests/test_bigint.cpp
+++ b/src/tests/test_bigint.cpp
@@ -1,5 +1,5 @@
/*
-* (C) 2009 Jack Lloyd
+* (C) 2009,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -7,522 +7,291 @@
#include "tests.h"
#if defined(BOTAN_HAS_BIGINT)
-
-#if defined(BOTAN_HAS_NUMBERTHEORY)
-
-#include <vector>
-#include <string>
-#include <fstream>
-#include <iostream>
-#include <cstdlib>
-#include <iterator>
-
-#include <sstream>
-#include <botan/bigint.h>
-#include <botan/exceptn.h>
-#include <botan/numthry.h>
-#include <botan/reducer.h>
-
-#if defined(BOTAN_HAS_EC_CURVE_GFP)
-#include <botan/curve_nistp.h>
+ #include <botan/bigint.h>
+ #include <botan/numthry.h>
+ #include <botan/reducer.h>
#endif
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-BOTAN_TEST_CASE(bigint_to_u32bit, "BigInt to_u32bit", {
- for(size_t i = 0; i != 32; ++i)
- {
- const u32bit in = 1 << i;
- BOTAN_TEST(in, BigInt(in).to_u32bit(), "in range round trips");
- }
- });
+#if defined(BOTAN_HAS_BIGINT)
-BigInt test_integer(RandomNumberGenerator& rng, size_t bits, BigInt max)
+class BigInt_Unit_Tests : public Test
{
- /*
- Produces integers with long runs of ones and zeros, for testing for
- carry handling problems.
- */
- BigInt x = 0;
-
- auto flip_prob = [](size_t i) {
- if(i % 64 == 0)
- return .5;
- if(i % 32 == 0)
- return .4;
- if(i % 8 == 0)
- return .05;
- return .01;
- };
-
- bool active = rng.next_byte() % 2;
- for(size_t i = 0; i != bits; ++i)
- {
- x <<= 1;
- x += static_cast<int>(active);
-
- const double prob = flip_prob(i);
- const double sample = double(rng.next_byte() % 100) / 100.0; // biased
+ public:
+ std::vector<Test::Result> run() override
+ {
+ std::vector<Test::Result> results;
- if(sample < prob)
- active = !active;
- }
+ results.push_back(test_bigint_sizes());
+ results.push_back(test_random_integer());
- if(max > 0)
- {
- while(x >= max)
+ return results;
+ }
+ private:
+ Test::Result test_bigint_sizes()
{
- const size_t b = x.bits() - 1;
- BOTAN_ASSERT(x.get_bit(b) == true, "Set");
- x.clear_bit(b);
+ Test::Result result("BigInt size functions");
+
+ for(size_t bit : { 1, 8, 16, 31, 32, 64, 97, 128, 179, 192, 512, 521 })
+ {
+ BigInt a;
+
+ a.set_bit(bit);
+
+ // Test 2^n and 2^n-1
+ for(size_t i = 0; i != 2; ++i)
+ {
+ const size_t exp_bits = bit + 1 - i;
+ result.test_eq("BigInt::bits", a.bits(), exp_bits);
+ result.test_eq("BigInt::bytes", a.bytes(),
+ (exp_bits % 8 == 0) ? (exp_bits / 8) : (exp_bits + 8 - exp_bits % 8) / 8);
+
+ if(bit == 1 && i == 1)
+ {
+ result.test_is_eq("BigInt::to_u32bit zero", a.to_u32bit(), static_cast<uint32_t>(1));
+ }
+ else if(bit <= 31 || (bit == 32 && i == 1))
+ {
+ result.test_is_eq("BigInt::to_u32bit", a.to_u32bit(), static_cast<uint32_t>((uint64_t(1) << bit) - i));
+ }
+ else
+ {
+ try {
+ a.to_u32bit();
+ result.test_failure("BigInt::to_u32bit roundtripped out of range value");
+ }
+ catch(std::exception& e)
+ {
+ result.test_success("BigInt::to_u32bit rejected out of range");
+ }
+ }
+
+ a--;
+ }
+ }
+
+ return result;
}
- }
-
- return x;
- }
-
-#if defined(BOTAN_HAS_EC_CURVE_GFP)
-
-void nist_redc_test(Test_State& _test,
- const std::string& prime_name,
- const BigInt& p,
- std::function<void (BigInt&, secure_vector<word>&)> redc_fn)
- {
- auto& rng = test_rng();
- const BigInt p2 = p*p;
- const size_t trials = 100;
- const size_t p_bits = p.bits();
-
- Modular_Reducer p_redc(p);
- secure_vector<word> ws;
-
- for(size_t i = 0; i != trials; ++i)
- {
- const BigInt x = test_integer(rng, 2*p_bits, p2);
-
- // TODO: time and report all three approaches
- const BigInt v1 = x % p;
- const BigInt v2 = p_redc.reduce(x);
-
- BigInt v3 = x;
- redc_fn(v3, ws);
-
- BOTAN_TEST(v1, v2, "reference");
- BOTAN_TEST(v2, v3, "specialized");
-
- if(v1 != v2 || v2 != v3)
- std::cout << "Prime " << prime_name << " input " << x << "\n";
- }
- }
-
-#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32)
-
-BOTAN_TEST_CASE(bigint_redc_p192, "P-192 reduction", {
- nist_redc_test(_test, "P-192", prime_p192(), redc_p192);
- });
-
-BOTAN_TEST_CASE(bigint_redc_p224, "P-224 reduction", {
- nist_redc_test(_test, "P-224", prime_p224(), redc_p224);
- });
-
-BOTAN_TEST_CASE(bigint_redc_p256, "P-256 reduction", {
- nist_redc_test(_test, "P-256", prime_p256(), redc_p256);
- });
-
-BOTAN_TEST_CASE(bigint_redc_p384, "P-384 reduction", {
- nist_redc_test(_test, "P-384", prime_p384(), redc_p384);
- });
-
-#endif
-BOTAN_TEST_CASE(bigint_redc_p521, "P-521 reduction", {
- nist_redc_test(_test, "P-521", prime_p521(), redc_p521);
- });
-
-#endif
-
-void strip_comments(std::string& line)
- {
- if(line.find('#') != std::string::npos)
- line = line.erase(line.find('#'), std::string::npos);
- }
-
-/* Strip comments, whitespace, etc */
-void strip(std::string& line)
- {
- strip_comments(line);
-
-#if 0
- while(line.find(' ') != std::string::npos)
- line = line.erase(line.find(' '), 1);
-#endif
-
- while(line.find('\t') != std::string::npos)
- line = line.erase(line.find('\t'), 1);
- }
-
-std::vector<std::string> parse(const std::string& line)
- {
- const char DELIMITER = ':';
- std::vector<std::string> substr;
- std::string::size_type start = 0, end = line.find(DELIMITER);
- while(end != std::string::npos)
- {
- substr.push_back(line.substr(start, end-start));
- start = end+1;
- end = line.find(DELIMITER, start);
- }
- if(line.size() > start)
- substr.push_back(line.substr(start));
- while(substr.size() <= 4) // at least 5 substr, some possibly empty
- substr.push_back("");
- return substr;
- }
-
-// c==expected, d==a op b, e==a op= b
-size_t results(std::string op,
- const BigInt& a, const BigInt& b,
- const BigInt& c, const BigInt& d, const BigInt& e)
- {
- std::string op1 = "operator" + op;
- std::string op2 = op1 + "=";
-
- if(c == d && d == e)
- return 0;
- else
- {
- std::cout << std::endl;
-
- std::cout << "ERROR: " << op1 << std::endl;
-
- std::cout << "a = " << std::hex << a << std::endl;
- std::cout << "b = " << std::hex << b << std::endl;
-
- std::cout << "c = " << std::hex << c << std::endl;
- std::cout << "d = " << std::hex << d << std::endl;
- std::cout << "e = " << std::hex << e << std::endl;
-
- if(d != e)
+ Test::Result test_random_integer()
{
- std::cout << "ERROR: " << op1 << " | " << op2
- << " mismatch" << std::endl;
+ Test::Result result("BigInt::random_integer");
+
+ result.start_timer();
+
+ const size_t ITERATIONS = 5000;
+
+ std::vector<size_t> min_ranges{ 0 };
+ std::vector<size_t> max_ranges{ 10 };
+
+ // This gets slow quickly:
+ if(Test::soak_level() > 10)
+ {
+ min_ranges.push_back(10);
+ max_ranges.push_back(100);
+
+ if(Test::soak_level() > 50)
+ {
+ min_ranges.push_back(79);
+ max_ranges.push_back(293);
+ }
+ }
+
+ for(size_t range_min : min_ranges)
+ {
+ for(size_t range_max : max_ranges)
+ {
+ if(range_min >= range_max)
+ continue;
+
+ std::vector<size_t> counts(range_max - range_min);
+
+ for(size_t i = 0; i != counts.size() * ITERATIONS; ++i)
+ {
+ uint32_t r = BigInt::random_integer(Test::rng(), range_min, range_max).to_u32bit();
+ result.test_gte("random_integer", r, range_min);
+ result.test_lt("random_integer", r, range_max);
+ counts[r - range_min] += 1;
+ }
+
+ for(size_t i = 0; i != counts.size(); ++i)
+ {
+ double ratio = static_cast<double>(counts[i]) / ITERATIONS;
+ double dev = std::min(ratio, std::fabs(1.0 - ratio));
+
+ if(dev < .15)
+ {
+ result.test_success("distribution within expected range");
+ }
+ else
+ {
+ result.test_failure("distribution " + std::to_string(dev) +
+ " outside expected range with count" +
+ std::to_string(counts[i]));
+ }
+ }
+ }
+ }
+
+ result.end_timer();
+
+ return result;
}
- return 1;
- }
- }
-
-size_t check_add(const std::vector<std::string>& args)
- {
- BigInt a(args[0]);
- BigInt b(args[1]);
- BigInt c(args[2]);
-
- BigInt d = a + b;
- BigInt e = a;
- e += b;
-
- if(results("+", a, b, c, d, e))
- return 1;
-
- d = b + a;
- e = b;
- e += a;
-
- return results("+", a, b, c, d, e);
- }
-
-size_t check_sub(const std::vector<std::string>& args)
- {
- BigInt a(args[0]);
- BigInt b(args[1]);
- BigInt c(args[2]);
-
- BigInt d = a - b;
- BigInt e = a;
- e -= b;
-
- return results("-", a, b, c, d, e);
- }
-
-size_t check_mul(const std::vector<std::string>& args)
- {
- BigInt a(args[0]);
- BigInt b(args[1]);
- BigInt c(args[2]);
-
- /*
- std::cout << "a = " << args[0] << "\n"
- << "b = " << args[1] << std::endl;
- */
- /* This makes it more likely the fast multiply algorithms will be usable,
- which is what we really want to test here (the simple n^2 multiply is
- pretty well tested at this point).
- */
- a.grow_to(64);
- b.grow_to(64);
-
- BigInt d = a * b;
- BigInt e = a;
- e *= b;
-
- if(results("*", a, b, c, d, e))
- return 1;
-
- d = b * a;
- e = b;
- e *= a;
-
- return results("*", a, b, c, d, e);
- }
-
-size_t check_sqr(const std::vector<std::string>& args)
- {
- BigInt a(args[0]);
- BigInt b(args[1]);
-
- a.grow_to(64);
- b.grow_to(64);
-
- BigInt c = square(a);
- BigInt d = a * a;
-
- return results("sqr", a, a, b, c, d);
- }
-
-size_t check_div(const std::vector<std::string>& args)
- {
- BigInt a(args[0]);
- BigInt b(args[1]);
- BigInt c(args[2]);
-
- BigInt d = a / b;
- BigInt e = a;
- e /= b;
-
- return results("/", a, b, c, d, e);
- }
-
-size_t check_mod(const std::vector<std::string>& args,
- Botan::RandomNumberGenerator& rng)
- {
- BigInt a(args[0]);
- BigInt b(args[1]);
- BigInt c(args[2]);
-
- BigInt d = a % b;
- BigInt e = a;
- e %= b;
-
- size_t got = results("%", a, b, c, d, e);
-
- if(got) return got;
-
- word b_word = b.word_at(0);
-
- /* Won't work for us, just pick one at random */
- while(b_word == 0)
- for(size_t j = 0; j != 2*sizeof(word); j++)
- b_word = (b_word << 4) ^ rng.next_byte();
-
- b = b_word;
-
- c = a % b; /* we declare the BigInt % BigInt version to be correct here */
-
- word d2 = a % b_word;
- e = a;
- e %= b_word;
-
- return results("%(word)", a, b, c, d2, e);
- }
-
-size_t check_shl(const std::vector<std::string>& args)
- {
- BigInt a(args[0]);
- size_t b = std::atoi(args[1].c_str());
- BigInt c(args[2]);
-
- BigInt d = a << b;
- BigInt e = a;
- e <<= b;
-
- return results("<<", a, b, c, d, e);
- }
-
-size_t check_shr(const std::vector<std::string>& args)
- {
- BigInt a(args[0]);
- size_t b = std::atoi(args[1].c_str());
- BigInt c(args[2]);
-
- BigInt d = a >> b;
- BigInt e = a;
- e >>= b;
-
- return results(">>", a, b, c, d, e);
- }
-
-/* Make sure that (a^b)%m == r */
-size_t check_powmod(const std::vector<std::string>& args)
- {
- BigInt a(args[0]);
- BigInt b(args[1]);
- BigInt m(args[2]);
- BigInt c(args[3]);
-
- BigInt r = power_mod(a, b, m);
-
- if(c != r)
- {
- std::cout << "ERROR: power_mod" << std::endl;
- std::cout << "a = " << std::hex << a << std::endl;
- std::cout << "b = " << std::hex << b << std::endl;
- std::cout << "m = " << std::hex << m << std::endl;
- std::cout << "c = " << std::hex << c << std::endl;
- std::cout << "r = " << std::hex << r << std::endl;
- return 1;
- }
- return 0;
- }
-
-/* Make sure that n is prime or not prime, according to should_be_prime */
-size_t is_primetest(const std::vector<std::string>& args,
- Botan::RandomNumberGenerator& rng)
- {
- BigInt n(args[0]);
- bool should_be_prime = (args[1] == "1");
-
- bool is_prime = Botan::is_prime(n, rng);
-
- if(is_prime != should_be_prime)
- {
- std::cout << "ERROR: is_prime" << std::endl;
- std::cout << "n = " << n << std::endl;
- std::cout << is_prime << " != " << should_be_prime << std::endl;
- }
- return 0;
- }
+ };
-}
+BOTAN_REGISTER_TEST("bigint_unit", BigInt_Unit_Tests);
-size_t test_bigint()
+class BigInt_KAT_Tests : public Text_Based_Test
{
- const std::string filename = TEST_DATA_DIR "/mp_valid.dat";
- std::ifstream test_data(filename);
-
- 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;
-
- auto& rng = test_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);
+ public:
+ BigInt_KAT_Tests() : Text_Based_Test(Test::data_file("bigint.vec"),
+ std::vector<std::string>{"Output"},
+ {"In1","In2","Input","Shift","Modulus","Value","Base","Exponent","IsPrime"})
+ {}
- strip(line);
- if(line.size() == 0) continue;
-
- // Do line continuation
- while(line[line.size()-1] == '\\' && !test_data.eof())
+ Test::Result run_one_test(const std::string& algo, const VarMap& vars)
{
- line.replace(line.size()-1, 1, "");
- std::string nextline;
- std::getline(test_data, nextline);
- strip(nextline);
- if(nextline.size() == 0) continue;
- line += nextline;
+ Test::Result result("BigInt " + algo);
+
+ using Botan::BigInt;
+
+ if(algo == "Addition")
+ {
+ const BigInt a = get_req_bn(vars, "In1");
+ const BigInt b = get_req_bn(vars, "In2");
+ const BigInt c = get_req_bn(vars, "Output");
+ BigInt d = a + b;
+
+ result.test_eq("a + b", a + b, c);
+ result.test_eq("b + a", b + a, c);
+
+ BigInt e = a;
+ e += b;
+ result.test_eq("a += b", e, c);
+
+ e = b;
+ e += a;
+ result.test_eq("b += a", e, c);
+ }
+ else if(algo == "Subtraction")
+ {
+ const BigInt a = get_req_bn(vars, "In1");
+ const BigInt b = get_req_bn(vars, "In2");
+ const BigInt c = get_req_bn(vars, "Output");
+ BigInt d = a - b;
+
+ result.test_eq("a - b", a - b, c);
+
+ BigInt e = a;
+ e -= b;
+ result.test_eq("a -= b", e, c);
+ }
+ else if(algo == "Multiplication")
+ {
+ const BigInt a = get_req_bn(vars, "In1");
+ const BigInt b = get_req_bn(vars, "In2");
+ const BigInt c = get_req_bn(vars, "Output");
+
+ result.test_eq("a * b", a * b, c);
+ result.test_eq("b * a", b * a, c);
+
+ BigInt e = a;
+ e *= b;
+ result.test_eq("a *= b", e, c);
+
+ e = b;
+ e *= a;
+ result.test_eq("b *= a", e, c);
+ }
+ else if(algo == "Square")
+ {
+ const BigInt a = get_req_bn(vars, "Input");
+ const BigInt c = get_req_bn(vars, "Output");
+
+ result.test_eq("a * a", a * a, c);
+ result.test_eq("sqr(a)", square(a), c);
+ }
+ else if(algo == "Division")
+ {
+ const BigInt a = get_req_bn(vars, "In1");
+ const BigInt b = get_req_bn(vars, "In2");
+ const BigInt c = get_req_bn(vars, "Output");
+
+ result.test_eq("a / b", a / b, c);
+
+ BigInt e = a;
+ e /= b;
+ result.test_eq("a /= b", e, c);
+ }
+ else if(algo == "Modulo")
+ {
+ const BigInt a = get_req_bn(vars, "In1");
+ const BigInt b = get_req_bn(vars, "In2");
+ const BigInt c = get_req_bn(vars, "Output");
+
+ result.test_eq("a % b", a % b, c);
+
+ BigInt e = a;
+ e %= b;
+ result.test_eq("a %= b", e, c);
+ }
+ else if(algo == "LeftShift")
+ {
+ const BigInt value = get_req_bn(vars, "Value");
+ const size_t shift = get_req_bn(vars, "Shift").to_u32bit();
+ const BigInt output = get_req_bn(vars, "Output");
+
+ result.test_eq("a << s", value << shift, output);
+
+ BigInt e = value;
+ e <<= shift;
+ result.test_eq("a <<= s", e, output);
+ }
+ else if(algo == "RightShift")
+ {
+ const BigInt value = get_req_bn(vars, "Value");
+ const size_t shift = get_req_bn(vars, "Shift").to_u32bit();
+ const BigInt output = get_req_bn(vars, "Output");
+
+ result.test_eq("a >> s", value >> shift, output);
+
+ BigInt e = value;
+ e >>= shift;
+ result.test_eq("a >>= s", e, output);
+ }
+ else if(algo == "ModExp")
+ {
+ const BigInt value = get_req_bn(vars, "Base");
+ const BigInt exponent = get_req_bn(vars, "Exponent");
+ const BigInt modulus = get_req_bn(vars, "Modulus");
+ const BigInt output = get_req_bn(vars, "Output");
+
+ result.test_eq("power_mod", Botan::power_mod(value, exponent, modulus), output);
+ }
+ else if(algo == "PrimeTest")
+ {
+ const BigInt value = get_req_bn(vars, "Value");
+ const bool v_is_prime = get_req_sz(vars, "IsPrime") > 0;
+
+ result.test_eq("value", Botan::is_prime(value, Test::rng()), v_is_prime);
+ }
+ else
+ {
+ result.test_failure("Unknown BigInt algorithm " + algo);
+ }
+
+ return result;
}
- 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;
- }
+BOTAN_REGISTER_TEST("bigint_kat", BigInt_KAT_Tests);
- std::vector<std::string> substr = parse(line);
-
- // std::cout << "Testing: " << algorithm << std::endl;
-
- 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 = is_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_bigint_to_u32bit();
-
-#if defined(BOTAN_HAS_EC_CURVE_GFP)
-
-#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32)
- total_errors += test_bigint_redc_p192();
- total_errors += test_bigint_redc_p224();
- total_errors += test_bigint_redc_p256();
- total_errors += test_bigint_redc_p384();
- #endif
-
- total_errors += test_bigint_redc_p521();
#endif
- return total_errors;
- }
-
-#else
-
-UNTESTED_WARNING(bigint);
-
-#endif // BOTAN_HAS_NUMBERTHEORY
-
-#else
-
-SKIP_TEST(bigint);
+}
-#endif // BOTAN_HAS_BIGINT
+}
diff --git a/src/tests/test_block.cpp b/src/tests/test_block.cpp
index b688ec84e..224735e22 100644
--- a/src/tests/test_block.cpp
+++ b/src/tests/test_block.cpp
@@ -5,83 +5,65 @@
*/
#include "tests.h"
-
#include <botan/block_cipher.h>
-#include <botan/hex.h>
-#include <iostream>
-#include <fstream>
-
-using namespace Botan;
-namespace {
+namespace Botan_Tests {
-size_t block_test(const std::string& algo,
- const std::string& key_hex,
- const std::string& in_hex,
- const std::string& out_hex)
+class Block_Cipher_Tests : public Text_Based_Test
{
- const secure_vector<byte> key = hex_decode_locked(key_hex);
- const secure_vector<byte> pt = hex_decode_locked(in_hex);
- const secure_vector<byte> ct = hex_decode_locked(out_hex);
+ public:
+ Block_Cipher_Tests() : Text_Based_Test(Test::data_dir("block"), {"Key", "In", "Out"}) {}
- const std::vector<std::string> providers = BlockCipher::providers(algo);
- size_t fails = 0;
+ Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
+ {
+ const std::vector<uint8_t> key = get_req_bin(vars, "Key");
+ const std::vector<uint8_t> input = get_req_bin(vars, "In");
+ const std::vector<uint8_t> expected = get_req_bin(vars, "Out");
- if(providers.empty())
- {
- std::cout << "Unknown block cipher " + algo + " skipping test\n";
- return 0;
- }
+ Test::Result result(algo);
- for(auto provider: providers)
- {
- std::unique_ptr<BlockCipher> cipher(BlockCipher::create(algo, provider));
+ const std::vector<std::string> providers = Botan::BlockCipher::providers(algo);
- if(!cipher)
- {
- std::cout << "Unable to get " << algo << " from " << provider << std::endl;
- ++fails;
- continue;
- }
+ if(providers.empty())
+ {
+ result.note_missing("block cipher " + algo);
+ return result;
+ }
- cipher->set_key(key);
- secure_vector<byte> buf = pt;
+ for(auto&& provider: providers)
+ {
+ std::unique_ptr<Botan::BlockCipher> cipher(Botan::BlockCipher::create(algo, provider));
- cipher->encrypt(buf);
+ if(!cipher)
+ {
+ result.note_missing(algo + " from " + provider);
+ continue;
+ }
- if(buf != ct)
- {
- std::cout << algo << " " << provider << " enc " << hex_encode(buf) << " != " << out_hex << std::endl;
- ++fails;
- buf = ct;
- }
+ result.test_eq(provider.c_str(), cipher->name(), algo);
+ result.test_gte(provider.c_str(), cipher->parallelism(), 1);
+ result.test_gte(provider.c_str(), cipher->block_size(), 8);
+ result.test_gte(provider.c_str(), cipher->parallel_bytes(), cipher->block_size() * cipher->parallelism());
- cipher->decrypt(buf);
+ cipher->set_key(key);
+ std::vector<uint8_t> buf = input;
- if(buf != pt)
- {
- std::cout << algo << " " << provider << " dec " << hex_encode(buf) << " != " << out_hex << std::endl;
- ++fails;
+ cipher->encrypt(buf);
+
+ result.test_eq(provider, "encrypt", buf, expected);
+
+ // always decrypt expected ciphertext vs what we produced above
+ buf = expected;
+ cipher->decrypt(buf);
+
+ result.test_eq(provider, "decrypt", buf, input);
+ }
+
+ return result;
}
- }
- return fails;
- }
+ };
-}
+BOTAN_REGISTER_TEST("block", Block_Cipher_Tests);
-size_t test_block()
- {
- auto test_bc = [](const std::string& input)
- {
- std::ifstream vec(input);
-
- return run_tests_bb(vec, "BlockCipher", "Out", true,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return block_test(m["BlockCipher"], m["Key"], m["In"], m["Out"]);
- });
- };
-
- return run_tests_in_dir(TEST_DATA_DIR "/block", test_bc);
- }
+}
diff --git a/src/tests/test_c25519.cpp b/src/tests/test_c25519.cpp
index 5531289a2..db2a94e37 100644
--- a/src/tests/test_c25519.cpp
+++ b/src/tests/test_c25519.cpp
@@ -7,118 +7,118 @@
#include "tests.h"
#if defined(BOTAN_HAS_CURVE_25519)
+ #include "test_pubkey.h"
+ #include <botan/curve25519.h>
+ #include <botan/pkcs8.h>
+#endif
-#include "test_pubkey.h"
+namespace Botan_Tests {
-#include <botan/curve25519.h>
-#include <botan/pkcs8.h>
-#include <botan/hex.h>
-#include <iostream>
-#include <fstream>
-
-using namespace Botan;
-
-namespace {
+#if defined(BOTAN_HAS_CURVE_25519)
-size_t curve25519_scalar_kat(const std::string& secret_h,
- const std::string& basepoint_h,
- const std::string& out_h)
+class Curve25519_Sclarmult_Tests : public Text_Based_Test
{
- const std::vector<byte> secret = hex_decode(secret_h);
- const std::vector<byte> basepoint = hex_decode(basepoint_h);
- const std::vector<byte> out = hex_decode(out_h);
-
- std::vector<byte> got(32);
- curve25519_donna(got.data(), secret.data(), basepoint.data());
-
- if(got != out)
- {
- std::cout << "Got " << hex_encode(got) << " exp " << hex_encode(out) << std::endl;
- return 1;
- }
-
- return 0;
- }
-
-size_t c25519_roundtrip()
+ public:
+ Curve25519_Sclarmult_Tests() : Text_Based_Test(
+ Test::data_file("pubkey/c25519_scalar.vec"),
+ {"Secret","Basepoint","Out"})
+ {}
+
+ Test::Result run_one_test(const std::string&, const VarMap& vars) override
+ {
+ const std::vector<uint8_t> secret = get_req_bin(vars, "Secret");
+ const std::vector<uint8_t> basepoint = get_req_bin(vars, "Basepoint");
+ const std::vector<uint8_t> expected = get_req_bin(vars, "Out");
+
+ std::vector<byte> got(32);
+ Botan::curve25519_donna(got.data(), secret.data(), basepoint.data());
+
+ Test::Result result("Curve25519 scalarmult");
+ result.test_eq("basemult", got, expected);
+ return result;
+ }
+ };
+
+class Curve25519_Roundtrip_Test : public Test
{
- auto& rng = test_rng();
+ public:
+ std::vector<Test::Result> run()
+ {
+ std::vector<Test::Result> results;
- try
- {
- // First create keys
- Curve25519_PrivateKey a_priv_gen(rng);
- Curve25519_PrivateKey b_priv_gen(rng);
+ for(size_t i = 0; i <= Test::soak_level(); ++i)
+ {
+ Test::Result result("Curve25519 roundtrip");
- const std::string a_pass = "alice pass";
- const std::string b_pass = "bob pass";
+ Botan::Curve25519_PrivateKey a_priv_gen(Test::rng());
+ Botan::Curve25519_PrivateKey b_priv_gen(Test::rng());
- // Then serialize to encrypted storage
- const auto pbe_time = std::chrono::milliseconds(10);
- const std::string a_priv_pem = PKCS8::PEM_encode(a_priv_gen, rng, a_pass, pbe_time);
- const std::string b_priv_pem = PKCS8::PEM_encode(b_priv_gen, rng, b_pass, pbe_time);
+ const std::string a_pass = "alice pass";
+ const std::string b_pass = "bob pass";
- // Reload back into memory
- DataSource_Memory a_priv_ds(a_priv_pem);
- DataSource_Memory b_priv_ds(b_priv_pem);
+ // Then serialize to encrypted storage
+ const auto pbe_time = std::chrono::milliseconds(10);
+ const std::string a_priv_pem = Botan::PKCS8::PEM_encode(a_priv_gen, Test::rng(), a_pass, pbe_time);
+ const std::string b_priv_pem = Botan::PKCS8::PEM_encode(b_priv_gen, Test::rng(), b_pass, pbe_time);
- std::unique_ptr<Private_Key> a_priv(PKCS8::load_key(a_priv_ds, rng, [a_pass]() { return a_pass; }));
- std::unique_ptr<Private_Key> b_priv(PKCS8::load_key(b_priv_ds, rng, b_pass));
+ // Reload back into memory
+ Botan::DataSource_Memory a_priv_ds(a_priv_pem);
+ Botan::DataSource_Memory b_priv_ds(b_priv_pem);
- // Export public keys as PEM
- const std::string a_pub_pem = X509::PEM_encode(*a_priv);
- const std::string b_pub_pem = X509::PEM_encode(*b_priv);
+ std::unique_ptr<Botan::Private_Key> a_priv(Botan::PKCS8::load_key(a_priv_ds, Test::rng(), [a_pass]() { return a_pass; }));
+ std::unique_ptr<Botan::Private_Key> b_priv(Botan::PKCS8::load_key(b_priv_ds, Test::rng(), b_pass));
- DataSource_Memory a_pub_ds(a_pub_pem);
- DataSource_Memory b_pub_ds(b_pub_pem);
+ // Export public keys as PEM
+ const std::string a_pub_pem = Botan::X509::PEM_encode(*a_priv);
+ const std::string b_pub_pem = Botan::X509::PEM_encode(*b_priv);
- std::unique_ptr<Public_Key> a_pub(X509::load_key(a_pub_ds));
- std::unique_ptr<Public_Key> b_pub(X509::load_key(b_pub_ds));
+ Botan::DataSource_Memory a_pub_ds(a_pub_pem);
+ Botan::DataSource_Memory b_pub_ds(b_pub_pem);
- Curve25519_PublicKey* a_pub_key = dynamic_cast<Curve25519_PublicKey*>(a_pub.get());
- Curve25519_PublicKey* b_pub_key = dynamic_cast<Curve25519_PublicKey*>(b_pub.get());
+ std::unique_ptr<Botan::Public_Key> a_pub(Botan::X509::load_key(a_pub_ds));
+ std::unique_ptr<Botan::Public_Key> b_pub(Botan::X509::load_key(b_pub_ds));
- PK_Key_Agreement a_ka(*a_priv, "KDF2(SHA-256)");
- PK_Key_Agreement b_ka(*b_priv, "KDF2(SHA-256)");
+ Botan::Curve25519_PublicKey* a_pub_key = dynamic_cast<Botan::Curve25519_PublicKey*>(a_pub.get());
+ Botan::Curve25519_PublicKey* b_pub_key = dynamic_cast<Botan::Curve25519_PublicKey*>(b_pub.get());
- const std::string context = "shared context value";
- SymmetricKey a_key = a_ka.derive_key(32, b_pub_key->public_value(), context);
- SymmetricKey b_key = b_ka.derive_key(32, a_pub_key->public_value(), context);
+ Botan::PK_Key_Agreement a_ka(*a_priv, "KDF2(SHA-256)");
+ Botan::PK_Key_Agreement b_ka(*b_priv, "KDF2(SHA-256)");
- if(a_key != b_key)
- return 1;
- }
- catch(std::exception& e)
- {
- std::cout << "C25519 rt fail: " << e.what() << std::endl;
- return 1;
- }
+ const std::string context = "shared context value";
+ Botan::SymmetricKey a_key = a_ka.derive_key(32, b_pub_key->public_value(), context);
+ Botan::SymmetricKey b_key = b_ka.derive_key(32, a_pub_key->public_value(), context);
- return 0;
- }
+ if(!result.test_eq("key agreement", a_key.bits_of(), b_key.bits_of()))
+ {
+ result.test_note(a_priv_pem);
+ result.test_note(b_priv_pem);
+ }
+ results.push_back(result);
+ }
-}
+ return results;
+ }
+ };
-size_t test_curve25519()
+class Curve25519_Keygen_Tests : public PK_Key_Generation_Test
{
- test_report("Curve25519", 1, c25519_roundtrip());
-
- size_t fails = 0;
+ public:
+ std::vector<std::string> keygen_params() const override { return { "" }; }
- std::ifstream c25519_scalar(TEST_DATA_DIR_PK "/c25519_scalar.vec");
+ std::unique_ptr<Botan::Private_Key> make_key(Botan::RandomNumberGenerator& rng,
+ const std::string&) const override
+ {
+ std::unique_ptr<Botan::Private_Key> key(new Botan::Curve25519_PrivateKey(rng));
+ return key;
+ }
- fails += run_tests_bb(c25519_scalar, "Curve25519 ScalarMult", "Out", true,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return curve25519_scalar_kat(m["Secret"], m["Basepoint"], m["Out"]);
- });
+ };
- return fails;
- }
+BOTAN_REGISTER_TEST("curve25519_scalar", Curve25519_Sclarmult_Tests);
+BOTAN_REGISTER_TEST("curve25519_rt", Curve25519_Roundtrip_Test);
+BOTAN_REGISTER_TEST("curve25519_keygen", Curve25519_Keygen_Tests);
-#else
+#endif
-SKIP_TEST(curve25519);
-
-#endif // BOTAN_HAS_CURVE_25519
+}
diff --git a/src/tests/test_compression.cpp b/src/tests/test_compression.cpp
index 902455fc7..affc6040d 100644
--- a/src/tests/test_compression.cpp
+++ b/src/tests/test_compression.cpp
@@ -1,141 +1,148 @@
+/*
+* (C) 2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
#include "tests.h"
#if defined(BOTAN_HAS_COMPRESSION)
+ #include <botan/compression.h>
+#endif
-#include <botan/compression.h>
-#include <botan/hex.h>
-#include <iostream>
+namespace Botan_Tests {
namespace {
-using namespace Botan;
+const char* text_str =
+ "'Twas brillig, and the slithy toves"
+ "Did gyre and gimble in the wabe:"
+ "All mimsy were the borogoves,"
+ "And the mome raths outgrabe."
+
+ "'Beware the Jabberwock, my son!"
+ "The jaws that bite, the claws that catch!"
+ "Beware the Jubjub bird, and shun"
+ "The frumious Bandersnatch!'"
+
+ "He took his vorpal sword in hand;"
+ "Long time the manxome foe he sought—"
+ "So rested he by the Tumtum tree"
+ "And stood awhile in thought."
+
+ "And, as in uffish thought he stood,"
+ "The Jabberwock, with eyes of flame,"
+ "Came whiffling through the tulgey wood,"
+ "And burbled as it came!"
+
+ "One, two! One, two! And through and through"
+ "The vorpal blade went snicker-snack!"
+ "He left it dead, and with its head"
+ "He went galumphing back."
+
+ "'And hast thou slain the Jabberwock?"
+ "Come to my arms, my beamish boy!"
+ "O frabjous day! Callooh! Callay!'"
+ "He chortled in his joy."
+
+ "’Twas brillig, and the slithy toves"
+ "Did gyre and gimble in the wabe:"
+ "All mimsy were the borogoves,"
+ "And the mome raths outgrabe.";
-// Returns # of bytes of compressed message
-size_t run_compression(Compressor_Transform& c, Transform& d,
- const secure_vector<byte>& msg)
- {
- secure_vector<byte> compressed = msg;
+#if defined(BOTAN_HAS_COMPRESSION)
- c.start();
- c.finish(compressed);
+class Compression_Tests : public Test
+ {
+ public:
+ std::vector<Test::Result> run() override
+ {
+ std::vector<Test::Result> results;
+
+ for(std::string algo : { "zlib", "deflate", "gzip", "bz2", "lzma" })
+ {
+ try
+ {
+ Test::Result result(algo + " compression");
+
+ std::unique_ptr<Botan::Compressor_Transform> c1(Botan::make_compressor(algo, 1));
+ std::unique_ptr<Botan::Compressor_Transform> c9(Botan::make_compressor(algo, 9));
+ std::unique_ptr<Botan::Compressor_Transform> d(Botan::make_decompressor(algo));
+
+ if(!c1 || !c9 || !d)
+ {
+ result.note_missing(algo);
+ continue;
+ }
+
+ const size_t text_len = strlen(text_str);
+
+ const Botan::secure_vector<uint8_t> empty;
+ const Botan::secure_vector<uint8_t> all_zeros(text_len, 0);
+ const Botan::secure_vector<uint8_t> random_binary = Test::rng().random_vec(text_len);
+
+ const uint8_t* textb = reinterpret_cast<const uint8_t*>(text_str);
+ const Botan::secure_vector<uint8_t> text(textb, textb + text_len);
+
+ const size_t c1_e = run_compression(result, *c1, *d, empty);
+ const size_t c9_e = run_compression(result, *c9, *d, empty);
+ const size_t c1_z = run_compression(result, *c1, *d, all_zeros);
+ const size_t c9_z = run_compression(result, *c9, *d, all_zeros);
+ const size_t c1_r = run_compression(result, *c1, *d, random_binary);
+ const size_t c9_r = run_compression(result, *c9, *d, random_binary);
+ const size_t c1_t = run_compression(result, *c1, *d, text);
+ const size_t c9_t = run_compression(result, *c9, *d, text);
+
+ result.test_gte("Empty input L1 compresses to non-empty output", c1_e, 1);
+ result.test_gte("Empty input L9 compresses to non-empty output", c9_e, 1);
+
+ result.test_gte("Level 9 compresses empty at least as well as level 1", c1_e, c9_e);
+ result.test_gte("Level 9 compresses zeros at least as well as level 1", c1_z, c9_z);
+ result.test_gte("Level 9 compresses random at least as well as level 1", c1_r, c9_r);
+ result.test_gte("Level 9 compresses text at least as well as level 1", c1_t, c9_t);
+
+ result.test_lt("Zeros compresses much better than text", c1_z / 8, c1_t);
+ result.test_lt("Text compresses much better than random", c1_t / 2, c1_r);
+
+ results.push_back(result);
+ }
+ catch(std::exception& e)
+ {
+ results.push_back(Test::Result::Failure("testing " + algo, e.what()));
+ }
+ }
+
+ return results;
+ }
- const size_t c_size = compressed.size();
+ private:
- secure_vector<byte> decompressed = compressed;
- d.start();
- d.finish(decompressed);
+ // Returns # of bytes of compressed message
+ size_t run_compression(Test::Result& result,
+ Botan::Compressor_Transform& c,
+ Botan::Transform& d,
+ const Botan::secure_vector<uint8_t>& msg)
+ {
+ Botan::secure_vector<uint8_t> compressed = msg;
- if(msg != decompressed)
- {
- std::cout << hex_encode(msg) << " compressed to " << hex_encode(compressed)
- << " but did not roundtrip - " << hex_encode(decompressed) << std::endl;
- }
+ c.start();
+ c.finish(compressed);
- return c_size;
- }
+ const size_t c_size = compressed.size();
-}
+ Botan::secure_vector<uint8_t> decompressed = compressed;
+ d.start();
+ d.finish(decompressed);
-size_t test_compression()
- {
- using namespace Botan;
-
- size_t fails = 0, tests = 0;
-
- for(auto&& algo : { "zlib", "deflate", "gzip", "bz2", "lzma" })
- {
- try
- {
- std::unique_ptr<Compressor_Transform> c1(make_compressor(algo, 1));
- std::unique_ptr<Compressor_Transform> c9(make_compressor(algo, 9));
- std::unique_ptr<Compressor_Transform> d(make_decompressor(algo));
-
- if(!c1 || !c9 || !d)
- continue;
-
- ++tests;
-
- const char* text_str =
- "'Twas brillig, and the slithy toves"
- "Did gyre and gimble in the wabe:"
- "All mimsy were the borogoves,"
- "And the mome raths outgrabe."
-
- "'Beware the Jabberwock, my son!"
- "The jaws that bite, the claws that catch!"
- "Beware the Jubjub bird, and shun"
- "The frumious Bandersnatch!'"
-
- "He took his vorpal sword in hand;"
- "Long time the manxome foe he sought—"
- "So rested he by the Tumtum tree"
- "And stood awhile in thought."
-
- "And, as in uffish thought he stood,"
- "The Jabberwock, with eyes of flame,"
- "Came whiffling through the tulgey wood,"
- "And burbled as it came!"
-
- "One, two! One, two! And through and through"
- "The vorpal blade went snicker-snack!"
- "He left it dead, and with its head"
- "He went galumphing back."
-
- "'And hast thou slain the Jabberwock?"
- "Come to my arms, my beamish boy!"
- "O frabjous day! Callooh! Callay!'"
- "He chortled in his joy."
-
- "’Twas brillig, and the slithy toves"
- "Did gyre and gimble in the wabe:"
- "All mimsy were the borogoves,"
- "And the mome raths outgrabe.";
-
- const size_t text_len = strlen(text_str);
-
- const secure_vector<byte> empty;
- const secure_vector<byte> all_zeros(text_len, 0);
- const secure_vector<byte> random_binary = test_rng().random_vec(text_len);
-
- const byte* textb = reinterpret_cast<const byte*>(text_str);
- const secure_vector<byte> text(textb, textb + text_len);
-
- const size_t c1_e = run_compression(*c1, *d, empty);
- const size_t c9_e = run_compression(*c9, *d, empty);
- const size_t c1_z = run_compression(*c1, *d, all_zeros);
- const size_t c9_z = run_compression(*c9, *d, all_zeros);
- const size_t c1_r = run_compression(*c1, *d, random_binary);
- const size_t c9_r = run_compression(*c9, *d, random_binary);
- const size_t c1_t = run_compression(*c1, *d, text);
- const size_t c9_t = run_compression(*c9, *d, text);
-
-#define BOTAN_TEST_GTE(x, y, msg) if(x < y) { ++fails; std::cout << "FAIL: " << x << " " << y << " " << msg << std::endl; }
-
- BOTAN_TEST_GTE(c1_e, 1, "Empty input compresses to non-empty output");
- BOTAN_TEST_GTE(c9_e, 1, "Empty input compresses to non-empty output");
-
- BOTAN_TEST_GTE(c1_e, c9_e, "Level 9 compresses at least as well as level 1");
- BOTAN_TEST_GTE(c1_z, c9_z, "Level 9 compresses at least as well as level 1");
- BOTAN_TEST_GTE(c1_t, c9_t, "Level 9 compresses at least as well as level 1");
- BOTAN_TEST_GTE(c1_r, c9_r, "Level 9 compresses at least as well as level 1");
-
- BOTAN_TEST_GTE(c1_t, c1_z/8, "Zeros compress much better than text");
- BOTAN_TEST_GTE(c1_r, c1_t/2, "Text compress better than random");
- }
- catch(std::exception& e)
- {
- std::cout << "Failure testing " << algo << " - " << e.what() << std::endl;
- ++fails;
+ result.test_eq("compression round tripped", msg, decompressed);
+ return c_size;
}
- }
-
- test_report("Compression", tests, fails);
+ };
- return fails;
- }
+BOTAN_REGISTER_TEST("compression", Compression_Tests);
-#else
+#endif
-SKIP_TEST(compression);
+}
-#endif // BOTAN_HAS_COMPRESSION
+}
diff --git a/src/tests/test_cryptobox.cpp b/src/tests/test_cryptobox.cpp
index 773360952..4eb9cdcdb 100644
--- a/src/tests/test_cryptobox.cpp
+++ b/src/tests/test_cryptobox.cpp
@@ -6,45 +6,56 @@
#include "tests.h"
-#include <iostream>
-
#if defined(BOTAN_HAS_CRYPTO_BOX)
#include <botan/cryptobox.h>
+ #include <botan/hex.h>
#endif
-using namespace Botan;
+namespace Botan_Tests {
-size_t test_cryptobox()
- {
- size_t fails = 0;
+namespace {
#if defined(BOTAN_HAS_CRYPTO_BOX)
- auto& rng = test_rng();
-
- const byte msg[] = { 0xAA, 0xBB, 0xCC };
- std::string ciphertext = CryptoBox::encrypt(msg, sizeof(msg),
- "secret password",
- rng);
-
- try
- {
- std::string plaintext = CryptoBox::decrypt(ciphertext,
- "secret password");
-
- if(plaintext.size() != sizeof(msg) ||
- !same_mem(reinterpret_cast<const byte*>(plaintext.data()), msg, sizeof(msg)))
- ++fails;
-
- }
- catch(std::exception& e)
- {
- std::cout << "Error during Cryptobox test " << e.what() << std::endl;
- ++fails;
- }
-
- test_report("Cryptobox", 1, fails);
+
+class Cryptobox_Tests : public Test
+ {
+ public:
+ std::vector<Test::Result> run() override
+ {
+ std::vector<Test::Result> results;
+ Test::Result result("cryptobox");
+
+ const std::vector<byte> msg = Botan::hex_decode("AABBCC");
+ const std::string password = "secret";
+
+ std::string ciphertext = Botan::CryptoBox::encrypt(msg.data(), msg.size(),
+ password,
+ Test::rng());
+
+ try
+ {
+ std::string plaintext = Botan::CryptoBox::decrypt(ciphertext, password);
+
+ const byte* pt_b = reinterpret_cast<const byte*>(plaintext.data());
+
+ std::vector<byte> pt_vec(pt_b, pt_b + plaintext.size());
+
+ result.test_eq("decrypt", pt_vec, msg);
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure("cryptobox decrypt", e.what());
+ }
+
+ results.push_back(result);
+ return results;
+ }
+ };
+
+BOTAN_REGISTER_TEST("cryptobox", Cryptobox_Tests);
+
#endif
- return fails;
- }
+}
+}
diff --git a/src/tests/test_cvc.cpp b/src/tests/test_cvc.cpp
index f25775852..dc4b50ebd 100644
--- a/src/tests/test_cvc.cpp
+++ b/src/tests/test_cvc.cpp
@@ -2,7 +2,7 @@
* CVC EAC1.1 tests
*
* (C) 2008 Falko Strenzke ([email protected])
-* 2008 Jack Lloyd
+* 2008,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -11,20 +11,7 @@
#if defined(BOTAN_HAS_CARD_VERIFIABLE_CERTIFICATES)
-#if defined(BOTAN_HAS_ECDSA) && defined(BOTAN_HAS_RSA)
-
-#include <iosfwd>
-#include <iostream>
-#include <iterator>
-#include <algorithm>
-#include <fstream>
-#include <vector>
-#include <memory>
-
-
#include <botan/ecdsa.h>
-#include <botan/rsa.h>
-
#include <botan/x509cert.h>
#include <botan/x509self.h>
#include <botan/oids.h>
@@ -32,17 +19,18 @@
#include <botan/cvc_cert.h>
#include <botan/cvc_ado.h>
-#define CVC_TEST_DATA_DIR TEST_DATA_DIR "/ecc"
-
-using namespace Botan;
+#endif
-#define CHECK_MESSAGE(expr, print) try { if(!(expr)) std::cout << print << std::endl; } catch(std::exception& e) { std::cout << __FUNCTION__ << ": " << e.what() << std::endl; }
-#define CHECK(expr) try { if(!(expr)) std::cout << #expr << std::endl; } catch(std::exception& e) { std::cout << __FUNCTION__ << ": " << e.what() << std::endl; }
+namespace Botan_Tests {
namespace {
+#if defined(BOTAN_HAS_CARD_VERIFIABLE_CERTIFICATES)
+
+using namespace Botan;
+
// helper functions
-void helper_write_file(EAC_Signed_Object const& to_write, std::string const& file_path)
+void helper_write_file(EAC_Signed_Object const& to_write, const std::string& file_path)
{
std::vector<byte> sv = to_write.BER_encode();
std::ofstream cert_file(file_path, std::ios::binary);
@@ -50,7 +38,7 @@ void helper_write_file(EAC_Signed_Object const& to_write, std::string const& fil
cert_file.close();
}
-bool helper_files_equal(std::string const& file_path1, std::string const& file_path2)
+bool helper_files_equal(const std::string& file_path1, const std::string& file_path2)
{
std::ifstream cert_1_in(file_path1);
std::ifstream cert_2_in(file_path2);
@@ -79,8 +67,44 @@ bool helper_files_equal(std::string const& file_path1, std::string const& file_p
return sv1 == sv2;
}
-void test_enc_gen_selfsigned(RandomNumberGenerator& rng)
+Test::Result test_cvc_times()
+ {
+ Test::Result result("CVC");
+
+ auto time1 = Botan::EAC_Time("2008-02-01");
+ auto time2 = Botan::EAC_Time("2008/02/28");
+ auto time3 = Botan::EAC_Time("2004-06-14");
+
+ result.confirm("time1 set", time1.time_is_set());
+ result.confirm("time2 set", time2.time_is_set());
+ result.confirm("time3 set", time3.time_is_set());
+
+ result.test_eq("time1 readable_string", time1.readable_string(), "2008/02/01");
+ result.test_eq("time2 readable_string", time2.readable_string(), "2008/02/28");
+ result.test_eq("time3 readable_string", time3.readable_string(), "2004/06/14");
+
+ result.test_eq("not set", Botan::EAC_Time("").time_is_set(), false);
+
+ const std::vector<std::string> invalid = {
+ " ",
+ "2008`02-01",
+ "9999-02-01",
+ "2000-02-01 17",
+ "999921"
+ };
+
+ for(auto&& v : invalid)
+ {
+ result.test_throws("invalid time " + v, [v]() { Botan::EAC_Time w(v); });
+ }
+
+ return result;
+ }
+
+Test::Result test_enc_gen_selfsigned()
{
+ Test::Result result("CVC");
+
EAC1_1_CVC_Options opts;
//opts.cpi = 0;
opts.chr = ASN1_Chr("my_opt_chr"); // not used
@@ -92,37 +116,37 @@ void test_enc_gen_selfsigned(RandomNumberGenerator& rng)
// creating a non sense selfsigned cert w/o dom pars
EC_Group dom_pars(OID("1.3.36.3.3.2.8.1.1.11"));
- ECDSA_PrivateKey key(rng, dom_pars);
+ ECDSA_PrivateKey key(Test::rng(), dom_pars);
key.set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA);
- EAC1_1_CVC cert = CVC_EAC::create_self_signed_cert(key, opts, rng);
+ EAC1_1_CVC cert = CVC_EAC::create_self_signed_cert(key, opts, Test::rng());
std::vector<byte> der(cert.BER_encode());
std::ofstream cert_file;
- cert_file.open(CVC_TEST_DATA_DIR "/my_cv_cert.ber", std::ios::binary);
- //cert_file << der; // this is bad !!!
+ cert_file.open(Test::data_file("ecc/my_cv_cert.ber"), std::ios::binary);
cert_file.write((char*)der.data(), der.size());
cert_file.close();
- EAC1_1_CVC cert_in(CVC_TEST_DATA_DIR "/my_cv_cert.ber");
- CHECK(cert == cert_in);
+ EAC1_1_CVC cert_in(Test::data_file("ecc/my_cv_cert.ber"));
+ result.confirm("reloaded cert matches", cert_in == cert);
+
// encoding it again while it has no dp
std::vector<byte> der2(cert_in.BER_encode());
- std::ofstream cert_file2(CVC_TEST_DATA_DIR "/my_cv_cert2.ber", std::ios::binary);
+ std::ofstream cert_file2(Test::data_file("ecc/my_cv_cert2.ber"), std::ios::binary);
cert_file2.write((char*)der2.data(), der2.size());
cert_file2.close();
+
// read both and compare them
- std::ifstream cert_1_in(CVC_TEST_DATA_DIR "/my_cv_cert.ber");
- std::ifstream cert_2_in(CVC_TEST_DATA_DIR "/my_cv_cert2.ber");
+ std::ifstream cert_1_in(Test::data_file("ecc/my_cv_cert.ber"));
+ std::ifstream cert_2_in(Test::data_file("ecc/my_cv_cert2.ber"));
std::vector<byte> sv1;
std::vector<byte> sv2;
- if (!cert_1_in || !cert_2_in)
+ if (!cert_1_in || cert_2_in)
{
- CHECK_MESSAGE(false, "could not read certificate files");
+ result.test_failure("Unable to reread cert files");
}
while (!cert_1_in.eof())
{
char now;
-
cert_1_in.read(&now, 1);
sv1.push_back(now);
}
@@ -132,66 +156,61 @@ void test_enc_gen_selfsigned(RandomNumberGenerator& rng)
cert_2_in.read(&now, 1);
sv2.push_back(now);
}
- CHECK(sv1.size() > 10);
- CHECK_MESSAGE(sv1 == sv2, "reencoded file of cert without domain parameters is different from original");
- //cout << "reading cert again" << std::endl;
- CHECK(cert_in.get_car().value() == "my_opt_car");
- CHECK(cert_in.get_chr().value() == "my_opt_car");
- CHECK(cert_in.get_ced().as_string() == "20100727");
- CHECK(cert_in.get_ced().readable_string() == "2010/07/27 ");
+ result.test_gte("size", sv1.size(), 10);
+ result.test_ne("reencoded file of cert without domain parameters is different from original", sv1, sv2);
+
+ result.test_eq("car", cert_in.get_car().value(), "my_opt_car");
+ result.test_eq("chr", cert_in.get_chr().value(), "my_opt_car");
+ result.test_eq("ced", cert_in.get_ced().as_string(), "20100727");
+ result.test_eq("ced", cert_in.get_ced().readable_string(), "2010/07/27");
- bool ill_date_exc = false;
try
{
- ASN1_Ced("1999 01 01");
- }
- catch (...)
- {
- ill_date_exc = true;
+ ASN1_Ced invalid("1999 01 01");
+ result.test_failure("Allowed creation of invalid 1999 ASN1_Ced");
}
- CHECK(ill_date_exc);
+ catch(...) {}
- bool ill_date_exc2 = false;
try
{
ASN1_Ced("2100 01 01");
+ result.test_failure("Allowed creation of invalid 2100 ASN1_Ced");
}
- catch (...)
- {
- ill_date_exc2 = true;
- }
- CHECK(ill_date_exc2);
- //cout << "readable = '" << cert_in.get_ced().readable_string() << "'" << std::endl;
+ catch(...) {}
+
std::unique_ptr<Public_Key> p_pk(cert_in.subject_public_key());
ECDSA_PublicKey* p_ecdsa_pk = dynamic_cast<ECDSA_PublicKey*>(p_pk.get());
- // let´s see if encoding is truely implicitca, because this is what the key should have
+ // let's see if encoding is truely implicitca, because this is what the key should have
// been set to when decoding (see above)(because it has no domain params):
- CHECK(p_ecdsa_pk->domain_format() == EC_DOMPAR_ENC_IMPLICITCA);
- bool exc = false;
+ result.confirm("implicit CA", p_ecdsa_pk->domain_format() == EC_DOMPAR_ENC_IMPLICITCA);
+
try
{
- std::cout << "order = " << p_ecdsa_pk->domain().get_order() << std::endl;
+ const BigInt order = p_ecdsa_pk->domain().get_order();
+ result.test_failure("Expected accessing domain to fail");
}
- catch (Invalid_State)
+ catch (Invalid_State) {}
{
- exc = true;
}
- CHECK(exc);
+
// set them and try again
//cert_in.set_domain_parameters(dom_pars);
std::unique_ptr<Public_Key> p_pk2(cert_in.subject_public_key());
ECDSA_PublicKey* p_ecdsa_pk2 = dynamic_cast<ECDSA_PublicKey*>(p_pk2.get());
//p_ecdsa_pk2->set_domain_parameters(dom_pars);
- CHECK(p_ecdsa_pk2->domain().get_order() == dom_pars.get_order());
- bool ver_ec = cert_in.check_signature(*p_pk2);
- CHECK_MESSAGE(ver_ec, "could not positively verify correct selfsigned cvc certificate");
+ result.test_eq("order", p_ecdsa_pk2->domain().get_order(), dom_pars.get_order());
+ result.confirm("verified signature", cert_in.check_signature(*p_pk2));
+
+ return result;
}
-void test_enc_gen_req(RandomNumberGenerator& rng)
+Test::Result test_enc_gen_req()
{
+ Test::Result result("CVC");
+
EAC1_1_CVC_Options opts;
//opts.cpi = 0;
@@ -200,48 +219,44 @@ void test_enc_gen_req(RandomNumberGenerator& rng)
// creating a non sense selfsigned cert w/o dom pars
EC_Group dom_pars(OID("1.3.132.0.8"));
- ECDSA_PrivateKey key(rng, dom_pars);
+ ECDSA_PrivateKey key(Test::rng(), dom_pars);
key.set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA);
- EAC1_1_Req req = CVC_EAC::create_cvc_req(key, opts.chr, opts.hash_alg, rng);
+ EAC1_1_Req req = CVC_EAC::create_cvc_req(key, opts.chr, opts.hash_alg, Test::rng());
std::vector<byte> der(req.BER_encode());
- std::ofstream req_file(CVC_TEST_DATA_DIR "/my_cv_req.ber", std::ios::binary);
+ std::ofstream req_file(Test::data_file("ecc/my_cv_req.ber"), std::ios::binary);
req_file.write((char*)der.data(), der.size());
req_file.close();
// read and check signature...
- EAC1_1_Req req_in(CVC_TEST_DATA_DIR "/my_cv_req.ber");
+ EAC1_1_Req req_in(Test::data_file("ecc/my_cv_req.ber"));
//req_in.set_domain_parameters(dom_pars);
std::unique_ptr<Public_Key> p_pk(req_in.subject_public_key());
ECDSA_PublicKey* p_ecdsa_pk = dynamic_cast<ECDSA_PublicKey*>(p_pk.get());
//p_ecdsa_pk->set_domain_parameters(dom_pars);
- CHECK(p_ecdsa_pk->domain().get_order() == dom_pars.get_order());
- bool ver_ec = req_in.check_signature(*p_pk);
- CHECK_MESSAGE(ver_ec, "could not positively verify correct selfsigned (created by myself) cvc request");
+ result.test_eq("order", p_ecdsa_pk->domain().get_order(), dom_pars.get_order());
+ result.confirm("signature valid on CVC request", req_in.check_signature(*p_pk));
+
+ return result;
}
-void test_cvc_req_ext(RandomNumberGenerator&)
+Test::Result test_cvc_req_ext()
{
- EAC1_1_Req req_in(CVC_TEST_DATA_DIR "/DE1_flen_chars_cvcRequest_ECDSA.der");
+ EAC1_1_Req req_in(Test::data_file("ecc/DE1_flen_chars_cvcRequest_ECDSA.der"));
EC_Group dom_pars(OID("1.3.36.3.3.2.8.1.1.5")); // "german curve"
//req_in.set_domain_parameters(dom_pars);
std::unique_ptr<Public_Key> p_pk(req_in.subject_public_key());
ECDSA_PublicKey* p_ecdsa_pk = dynamic_cast<ECDSA_PublicKey*>(p_pk.get());
- //p_ecdsa_pk->set_domain_parameters(dom_pars);
- CHECK(p_ecdsa_pk->domain().get_order() == dom_pars.get_order());
- bool ver_ec = req_in.check_signature(*p_pk);
- CHECK_MESSAGE(ver_ec, "could not positively verify correct selfsigned (external testdata) cvc request");
- }
-void test_cvc_ado_ext(RandomNumberGenerator&)
- {
- EAC1_1_ADO req_in(CVC_TEST_DATA_DIR "/ado.cvcreq");
- EC_Group dom_pars(OID("1.3.36.3.3.2.8.1.1.5")); // "german curve"
- //cout << "car = " << req_in.get_car().value() << std::endl;
- //req_in.set_domain_parameters(dom_pars);
+ Test::Result result("CVC");
+ result.test_eq("order", p_ecdsa_pk->domain().get_order(), dom_pars.get_order());
+ result.confirm("signature valid on CVC request", req_in.check_signature(*p_pk));
+ return result;
}
-void test_cvc_ado_creation(RandomNumberGenerator& rng)
+Test::Result test_cvc_ado_creation()
{
+ Test::Result result("CVC");
+
EAC1_1_CVC_Options opts;
//opts.cpi = 0;
opts.chr = ASN1_Chr("my_opt_chr");
@@ -249,41 +264,42 @@ void test_cvc_ado_creation(RandomNumberGenerator& rng)
// creating a non sense selfsigned cert w/o dom pars
EC_Group dom_pars(OID("1.3.36.3.3.2.8.1.1.11"));
- //cout << "mod = " << hex << dom_pars.get_curve().get_p() << std::endl;
- ECDSA_PrivateKey req_key(rng, dom_pars);
+ ECDSA_PrivateKey req_key(Test::rng(), dom_pars);
req_key.set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA);
//EAC1_1_Req req = CVC_EAC::create_cvc_req(req_key, opts);
- EAC1_1_Req req = CVC_EAC::create_cvc_req(req_key, opts.chr, opts.hash_alg, rng);
+ EAC1_1_Req req = CVC_EAC::create_cvc_req(req_key, opts.chr, opts.hash_alg, Test::rng());
std::vector<byte> der(req.BER_encode());
- std::ofstream req_file(CVC_TEST_DATA_DIR "/my_cv_req.ber", std::ios::binary);
+ std::ofstream req_file(Test::data_file("ecc/my_cv_req.ber"), std::ios::binary);
req_file.write((char*)der.data(), der.size());
req_file.close();
// create an ado with that req
- ECDSA_PrivateKey ado_key(rng, dom_pars);
+ ECDSA_PrivateKey ado_key(Test::rng(), dom_pars);
EAC1_1_CVC_Options ado_opts;
ado_opts.car = ASN1_Car("my_ado_car");
- ado_opts.hash_alg = "SHA-256"; // must be equal to req´s hash alg, because ado takes his sig_algo from it´s request
+ ado_opts.hash_alg = "SHA-256"; // must be equal to req's hash alg, because ado takes his sig_algo from it's request
//EAC1_1_ADO ado = CVC_EAC::create_ado_req(ado_key, req, ado_opts);
- EAC1_1_ADO ado = CVC_EAC::create_ado_req(ado_key, req, ado_opts.car, rng);
- CHECK_MESSAGE(ado.check_signature(ado_key), "failure of ado verification after creation");
+ EAC1_1_ADO ado = CVC_EAC::create_ado_req(ado_key, req, ado_opts.car, Test::rng());
+ result.confirm("ADO signature verifies", ado.check_signature(ado_key));
- std::ofstream ado_file(CVC_TEST_DATA_DIR "/ado", std::ios::binary);
+ std::ofstream ado_file(Test::data_file("ecc/ado"), std::ios::binary);
std::vector<byte> ado_der(ado.BER_encode());
ado_file.write((char*)ado_der.data(), ado_der.size());
ado_file.close();
// read it again and check the signature
- EAC1_1_ADO ado2(CVC_TEST_DATA_DIR "/ado");
- CHECK(ado == ado2);
- //ECDSA_PublicKey* p_ado_pk = dynamic_cast<ECDSA_PublicKey*>(&ado_key);
- //bool ver = ado2.check_signature(*p_ado_pk);
- bool ver = ado2.check_signature(ado_key);
- CHECK_MESSAGE(ver, "failure of ado verification after reloading");
+ EAC1_1_ADO ado2(Test::data_file("ecc/ado"));
+ result.confirm("ADOs match", ado == ado2);
+
+ result.confirm("ADO signature valid", ado2.check_signature(ado_key));
+
+ return result;
}
-void test_cvc_ado_comparison(RandomNumberGenerator& rng)
+Test::Result test_cvc_ado_comparison()
{
+ Test::Result result("CVC");
+
EAC1_1_CVC_Options opts;
//opts.cpi = 0;
opts.chr = ASN1_Chr("my_opt_chr");
@@ -291,229 +307,226 @@ void test_cvc_ado_comparison(RandomNumberGenerator& rng)
// creating a non sense selfsigned cert w/o dom pars
EC_Group dom_pars(OID("1.3.36.3.3.2.8.1.1.11"));
- ECDSA_PrivateKey req_key(rng, dom_pars);
+ ECDSA_PrivateKey req_key(Test::rng(), dom_pars);
req_key.set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA);
//EAC1_1_Req req = CVC_EAC::create_cvc_req(req_key, opts);
- EAC1_1_Req req = CVC_EAC::create_cvc_req(req_key, opts.chr, opts.hash_alg, rng);
+ EAC1_1_Req req = CVC_EAC::create_cvc_req(req_key, opts.chr, opts.hash_alg, Test::rng());
// create an ado with that req
- ECDSA_PrivateKey ado_key(rng, dom_pars);
+ ECDSA_PrivateKey ado_key(Test::rng(), dom_pars);
EAC1_1_CVC_Options ado_opts;
ado_opts.car = ASN1_Car("my_ado_car1");
ado_opts.hash_alg = "SHA-224"; // must be equal to req's hash alg, because ado takes his sig_algo from it's request
//EAC1_1_ADO ado = CVC_EAC::create_ado_req(ado_key, req, ado_opts);
- EAC1_1_ADO ado = CVC_EAC::create_ado_req(ado_key, req, ado_opts.car, rng);
- CHECK_MESSAGE(ado.check_signature(ado_key), "failure of ado verification after creation");
+ EAC1_1_ADO ado = CVC_EAC::create_ado_req(ado_key, req, ado_opts.car, Test::rng());
+ result.confirm("ADO signature valid", ado.check_signature(ado_key));
// make a second one for comparison
EAC1_1_CVC_Options opts2;
//opts2.cpi = 0;
opts2.chr = ASN1_Chr("my_opt_chr");
opts2.hash_alg = "SHA-160"; // this is the only difference
- ECDSA_PrivateKey req_key2(rng, dom_pars);
+ ECDSA_PrivateKey req_key2(Test::rng(), dom_pars);
req_key.set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA);
- //EAC1_1_Req req2 = CVC_EAC::create_cvc_req(req_key2, opts2, rng);
- EAC1_1_Req req2 = CVC_EAC::create_cvc_req(req_key2, opts2.chr, opts2.hash_alg, rng);
- ECDSA_PrivateKey ado_key2(rng, dom_pars);
+ //EAC1_1_Req req2 = CVC_EAC::create_cvc_req(req_key2, opts2, Test::rng());
+ EAC1_1_Req req2 = CVC_EAC::create_cvc_req(req_key2, opts2.chr, opts2.hash_alg, Test::rng());
+ ECDSA_PrivateKey ado_key2(Test::rng(), dom_pars);
EAC1_1_CVC_Options ado_opts2;
ado_opts2.car = ASN1_Car("my_ado_car1");
ado_opts2.hash_alg = "SHA-160"; // must be equal to req's hash alg, because ado takes his sig_algo from it's request
- EAC1_1_ADO ado2 = CVC_EAC::create_ado_req(ado_key2, req2, ado_opts2.car, rng);
- CHECK_MESSAGE(ado2.check_signature(ado_key2), "failure of ado verification after creation");
+ EAC1_1_ADO ado2 = CVC_EAC::create_ado_req(ado_key2, req2, ado_opts2.car, Test::rng());
+ result.confirm("ADO signature after creation", ado2.check_signature(ado_key2));
- CHECK_MESSAGE(ado != ado2, "ado's found to be equal where they are not");
- // std::ofstream ado_file(CVC_TEST_DATA_DIR "/ado");
+ result.confirm("ADOs should not be equal", ado != ado2);
+ // std::ofstream ado_file(Test::data_file("ecc/ado"));
// std::vector<byte> ado_der(ado.BER_encode());
// ado_file.write((char*)ado_der.data(), ado_der.size());
// ado_file.close();
// read it again and check the signature
- // EAC1_1_ADO ado2(CVC_TEST_DATA_DIR "/ado");
+ // EAC1_1_ADO ado2(Test::data_file("ecc/ado"));
// ECDSA_PublicKey* p_ado_pk = dynamic_cast<ECDSA_PublicKey*>(&ado_key);
// //bool ver = ado2.check_signature(*p_ado_pk);
// bool ver = ado2.check_signature(ado_key);
// CHECK_MESSAGE(ver, "failure of ado verification after reloading");
+
+ return result;
}
-void test_eac_time(RandomNumberGenerator&)
+void confirm_cex_time(Test::Result& result,
+ const ASN1_Cex& cex,
+ size_t exp_year,
+ size_t exp_month)
{
- EAC_Time time(std::chrono::system_clock::now());
- // std::cout << "time as std::string = " << time.as_string() << std::endl;
+ result.test_eq("year", cex.get_year(), exp_year);
+ result.test_eq("month", cex.get_month(), exp_month);
+ }
+
+Test::Result test_eac_time()
+ {
+ Test::Result result("CVC");
+
EAC_Time sooner("", ASN1_Tag(99));
- //X509_Time sooner("", ASN1_Tag(99));
sooner.set_to("2007 12 12");
- // std::cout << "sooner as std::string = " << sooner.as_string() << std::endl;
EAC_Time later("2007 12 13");
- //X509_Time later("2007 12 13");
- // std::cout << "later as std::string = " << later.as_string() << std::endl;
- CHECK(sooner <= later);
- CHECK(sooner == sooner);
+
+ result.confirm("sooner < later", sooner < later);
+ result.confirm("self-equal", sooner == sooner);
ASN1_Cex my_cex("2007 08 01");
my_cex.add_months(12);
- CHECK(my_cex.get_year() == 2008);
- CHECK_MESSAGE(my_cex.get_month() == 8, "shoult be 8, was " << my_cex.get_month());
+ confirm_cex_time(result, my_cex, 2008, 8);
my_cex.add_months(4);
- CHECK(my_cex.get_year() == 2008);
- CHECK(my_cex.get_month() == 12);
+ confirm_cex_time(result, my_cex, 2008, 12);
my_cex.add_months(4);
- CHECK(my_cex.get_year() == 2009);
- CHECK(my_cex.get_month() == 4);
+ confirm_cex_time(result, my_cex, 2009, 4);
my_cex.add_months(41);
- CHECK(my_cex.get_year() == 2012);
- CHECK(my_cex.get_month() == 9);
-
-
+ confirm_cex_time(result, my_cex, 2012, 9);
+ return result;
}
-void test_ver_cvca(RandomNumberGenerator&)
+Test::Result test_ver_cvca()
{
- EAC1_1_CVC req_in(CVC_TEST_DATA_DIR "/cvca01.cv.crt");
+ Test::Result result("CVC");
- bool exc = false;
+ EAC1_1_CVC cvc(Test::data_file("ecc/cvca01.cv.crt"));
- std::unique_ptr<Public_Key> p_pk2(req_in.subject_public_key());
- ECDSA_PublicKey* p_ecdsa_pk2 = dynamic_cast<ECDSA_PublicKey*>(p_pk2.get());
- bool ver_ec = req_in.check_signature(*p_pk2);
- CHECK_MESSAGE(ver_ec, "could not positively verify correct selfsigned cvca certificate");
+ std::unique_ptr<Public_Key> p_pk2(cvc.subject_public_key());
+ result.confirm("verified CVCA cert", cvc.check_signature(*p_pk2));
try
{
+ ECDSA_PublicKey* p_ecdsa_pk2 = dynamic_cast<ECDSA_PublicKey*>(p_pk2.get());
p_ecdsa_pk2->domain().get_order();
+ result.test_failure("Expected failure");
}
- catch (Invalid_State)
+ catch(Invalid_State)
{
- exc = true;
+ result.test_note("Accessing order failed");
}
- CHECK(!exc);
+
+ return result;
}
-void test_copy_and_assignment(RandomNumberGenerator&)
+Test::Result test_copy_and_assignment()
{
- EAC1_1_CVC cert_in(CVC_TEST_DATA_DIR "/cvca01.cv.crt");
+ Test::Result result("CVC");
+
+ EAC1_1_CVC cert_in(Test::data_file("ecc/cvca01.cv.crt"));
EAC1_1_CVC cert_cp(cert_in);
EAC1_1_CVC cert_ass = cert_in;
- CHECK(cert_in == cert_cp);
- CHECK(cert_in == cert_ass);
- EAC1_1_ADO ado_in(CVC_TEST_DATA_DIR "/ado.cvcreq");
- //EC_Group dom_pars(OID("1.3.36.3.3.2.8.1.1.5")); // "german curve"
+ result.confirm("same cert", cert_in == cert_cp);
+ result.confirm("same cert", cert_in == cert_ass);
+
+ EAC1_1_ADO ado_in(Test::data_file("ecc/ado.cvcreq"));
EAC1_1_ADO ado_cp(ado_in);
EAC1_1_ADO ado_ass = ado_in;
- CHECK(ado_in == ado_cp);
- CHECK(ado_in == ado_ass);
+ result.confirm("same", ado_in == ado_cp);
+ result.confirm("same", ado_in == ado_ass);
- EAC1_1_Req req_in(CVC_TEST_DATA_DIR "/DE1_flen_chars_cvcRequest_ECDSA.der");
- //EC_Group dom_pars(OID("1.3.36.3.3.2.8.1.1.5")); // "german curve"
+ EAC1_1_Req req_in(Test::data_file("ecc/DE1_flen_chars_cvcRequest_ECDSA.der"));
EAC1_1_Req req_cp(req_in);
EAC1_1_Req req_ass = req_in;
- CHECK(req_in == req_cp);
- CHECK(req_in == req_ass);
+ result.confirm("same", req_in == req_cp);
+ result.confirm("same", req_in == req_ass);
+
+ return result;
}
-void test_eac_str_illegal_values(RandomNumberGenerator&)
+Test::Result test_eac_str_illegal_values()
{
- bool exc = false;
- try
- {
- EAC1_1_CVC(CVC_TEST_DATA_DIR "/cvca_illegal_chars.cv.crt");
+ Test::Result result("CVC");
- }
- catch (Decoding_Error)
+ try
{
- exc = true;
+ EAC1_1_CVC(Test::data_file("ecc/cvca_illegal_chars.cv.crt"));
+ result.test_failure("Accepted invalid EAC 1.1 CVC");
}
- CHECK(exc);
+ catch (Decoding_Error) {}
- bool exc2 = false;
try
{
- EAC1_1_CVC(CVC_TEST_DATA_DIR "/cvca_illegal_chars2.cv.crt");
-
+ EAC1_1_CVC(Test::data_file("ecc/cvca_illegal_chars2.cv.crt"));
+ result.test_failure("Accepted invalid EAC 1.1 CVC #2");
}
- catch (Decoding_Error)
- {
- exc2 = true;
- }
- CHECK(exc2);
+ catch (Decoding_Error) {}
+
+ return result;
}
-void test_tmp_eac_str_enc(RandomNumberGenerator&)
+Test::Result test_tmp_eac_str_enc()
{
- bool exc = false;
+ Test::Result result("CVC");
try
{
ASN1_Car("abc!+-µ\n");
+ result.test_failure("Accepted invalid EAC string");
}
- catch (Invalid_Argument)
- {
- exc = true;
- }
- CHECK(exc);
- // std::string val = car.iso_8859();
- // std::cout << "car 8859 = " << val << std::endl;
- // std::cout << hex <<(unsigned char)val[1] << std::endl;
-
+ catch(Invalid_Argument) {}
+ return result;
}
-void test_cvc_chain(RandomNumberGenerator& rng)
+Test::Result test_cvc_chain()
{
+ Test::Result result("CVC");
+
EC_Group dom_pars(OID("1.3.36.3.3.2.8.1.1.5")); // "german curve"
- ECDSA_PrivateKey cvca_privk(rng, dom_pars);
+ ECDSA_PrivateKey cvca_privk(Test::rng(), dom_pars);
std::string hash("SHA-224");
ASN1_Car car("DECVCA00001");
- EAC1_1_CVC cvca_cert = DE_EAC::create_cvca(cvca_privk, hash, car, true, true, 12, rng);
- std::ofstream cvca_file(CVC_TEST_DATA_DIR "/cvc_chain_cvca.cer", std::ios::binary);
+ EAC1_1_CVC cvca_cert = DE_EAC::create_cvca(cvca_privk, hash, car, true, true, 12, Test::rng());
+ std::ofstream cvca_file(Test::data_file("ecc/cvc_chain_cvca.cer"), std::ios::binary);
std::vector<byte> cvca_sv = cvca_cert.BER_encode();
cvca_file.write((char*)cvca_sv.data(), cvca_sv.size());
cvca_file.close();
- ECDSA_PrivateKey cvca_privk2(rng, dom_pars);
+ ECDSA_PrivateKey cvca_privk2(Test::rng(), dom_pars);
ASN1_Car car2("DECVCA00002");
- EAC1_1_CVC cvca_cert2 = DE_EAC::create_cvca(cvca_privk2, hash, car2, true, true, 12, rng);
- EAC1_1_CVC link12 = DE_EAC::link_cvca(cvca_cert, cvca_privk, cvca_cert2, rng);
+ EAC1_1_CVC cvca_cert2 = DE_EAC::create_cvca(cvca_privk2, hash, car2, true, true, 12, Test::rng());
+ EAC1_1_CVC link12 = DE_EAC::link_cvca(cvca_cert, cvca_privk, cvca_cert2, Test::rng());
std::vector<byte> link12_sv = link12.BER_encode();
- std::ofstream link12_file(CVC_TEST_DATA_DIR "/cvc_chain_link12.cer", std::ios::binary);
+ std::ofstream link12_file(Test::data_file("ecc/cvc_chain_link12.cer"), std::ios::binary);
link12_file.write((char*)link12_sv.data(), link12_sv.size());
link12_file.close();
// verify the link
- CHECK(link12.check_signature(cvca_privk));
- EAC1_1_CVC link12_reloaded(CVC_TEST_DATA_DIR "/cvc_chain_link12.cer");
- EAC1_1_CVC cvca1_reloaded(CVC_TEST_DATA_DIR "/cvc_chain_cvca.cer");
+ result.confirm("signature valid", link12.check_signature(cvca_privk));
+ EAC1_1_CVC link12_reloaded(Test::data_file("ecc/cvc_chain_link12.cer"));
+ EAC1_1_CVC cvca1_reloaded(Test::data_file("ecc/cvc_chain_cvca.cer"));
std::unique_ptr<Public_Key> cvca1_rel_pk(cvca1_reloaded.subject_public_key());
- CHECK(link12_reloaded.check_signature(*cvca1_rel_pk));
+ result.confirm("signature valid", link12_reloaded.check_signature(*cvca1_rel_pk));
// create first round dvca-req
- ECDSA_PrivateKey dvca_priv_key(rng, dom_pars);
- EAC1_1_Req dvca_req = DE_EAC::create_cvc_req(dvca_priv_key, ASN1_Chr("DEDVCAEPASS"), hash, rng);
- std::ofstream dvca_file(CVC_TEST_DATA_DIR "/cvc_chain_dvca_req.cer", std::ios::binary);
+ ECDSA_PrivateKey dvca_priv_key(Test::rng(), dom_pars);
+ EAC1_1_Req dvca_req = DE_EAC::create_cvc_req(dvca_priv_key, ASN1_Chr("DEDVCAEPASS"), hash, Test::rng());
+ std::ofstream dvca_file(Test::data_file("ecc/cvc_chain_dvca_req.cer"), std::ios::binary);
std::vector<byte> dvca_sv = dvca_req.BER_encode();
dvca_file.write((char*)dvca_sv.data(), dvca_sv.size());
dvca_file.close();
// sign the dvca_request
- EAC1_1_CVC dvca_cert1 = DE_EAC::sign_request(cvca_cert, cvca_privk, dvca_req, 1, 5, true, 3, 1, rng);
- CHECK(dvca_cert1.get_car().iso_8859() == "DECVCA00001");
- CHECK(dvca_cert1.get_chr().iso_8859() == "DEDVCAEPASS00001");
- helper_write_file(dvca_cert1, CVC_TEST_DATA_DIR "/cvc_chain_dvca_cert1.cer");
+ EAC1_1_CVC dvca_cert1 = DE_EAC::sign_request(cvca_cert, cvca_privk, dvca_req, 1, 5, true, 3, 1, Test::rng());
+ result.test_eq("DVCA car", dvca_cert1.get_car().iso_8859(), "DECVCA00001");
+ result.test_eq("DVCA chr", dvca_cert1.get_chr().iso_8859(), "DEDVCAEPASS00001");
+ helper_write_file(dvca_cert1, Test::data_file("ecc/cvc_chain_dvca_cert1.cer"));
// make a second round dvca ado request
- ECDSA_PrivateKey dvca_priv_key2(rng, dom_pars);
- EAC1_1_Req dvca_req2 = DE_EAC::create_cvc_req(dvca_priv_key2, ASN1_Chr("DEDVCAEPASS"), hash, rng);
- std::ofstream dvca_file2(CVC_TEST_DATA_DIR "/cvc_chain_dvca_req2.cer", std::ios::binary);
+ ECDSA_PrivateKey dvca_priv_key2(Test::rng(), dom_pars);
+ EAC1_1_Req dvca_req2 = DE_EAC::create_cvc_req(dvca_priv_key2, ASN1_Chr("DEDVCAEPASS"), hash, Test::rng());
+ std::ofstream dvca_file2(Test::data_file("ecc/cvc_chain_dvca_req2.cer"), std::ios::binary);
std::vector<byte> dvca_sv2 = dvca_req2.BER_encode();
dvca_file2.write((char*)dvca_sv2.data(), dvca_sv2.size());
dvca_file2.close();
EAC1_1_ADO dvca_ado2 = CVC_EAC::create_ado_req(dvca_priv_key, dvca_req2,
- ASN1_Car(dvca_cert1.get_chr().iso_8859()), rng);
- helper_write_file(dvca_ado2, CVC_TEST_DATA_DIR "/cvc_chain_dvca_ado2.cer");
+ ASN1_Car(dvca_cert1.get_chr().iso_8859()), Test::rng());
+ helper_write_file(dvca_ado2, Test::data_file("ecc/cvc_chain_dvca_ado2.cer"));
// verify the ado and sign the request too
@@ -521,66 +534,78 @@ void test_cvc_chain(RandomNumberGenerator& rng)
ECDSA_PublicKey* cert_pk = dynamic_cast<ECDSA_PublicKey*>(ap_pk.get());
//cert_pk->set_domain_parameters(dom_pars);
- //std::cout << "dvca_cert.public_point.size() = " << ec::EC2OSP(cert_pk->get_public_point(), ec::PointGFp::COMPRESSED).size() << std::endl;
- EAC1_1_CVC dvca_cert1_reread(CVC_TEST_DATA_DIR "/cvc_chain_cvca.cer");
- CHECK(dvca_ado2.check_signature(*cert_pk));
-
- CHECK(dvca_ado2.check_signature(dvca_priv_key)); // must also work
+ EAC1_1_CVC dvca_cert1_reread(Test::data_file("ecc/cvc_chain_cvca.cer"));
+ result.confirm("signature valid", dvca_ado2.check_signature(*cert_pk));
+ result.confirm("signature valid", dvca_ado2.check_signature(dvca_priv_key)); // must also work
EAC1_1_Req dvca_req2b = dvca_ado2.get_request();
- helper_write_file(dvca_req2b, CVC_TEST_DATA_DIR "/cvc_chain_dvca_req2b.cer");
- CHECK(helper_files_equal(CVC_TEST_DATA_DIR "/cvc_chain_dvca_req2b.cer", CVC_TEST_DATA_DIR "/cvc_chain_dvca_req2.cer"));
- EAC1_1_CVC dvca_cert2 = DE_EAC::sign_request(cvca_cert, cvca_privk, dvca_req2b, 2, 5, true, 3, 1, rng);
- CHECK(dvca_cert2.get_car().iso_8859() == "DECVCA00001");
- CHECK_MESSAGE(dvca_cert2.get_chr().iso_8859() == "DEDVCAEPASS00002",
- "chr = " << dvca_cert2.get_chr().iso_8859());
+ helper_write_file(dvca_req2b, Test::data_file("ecc/cvc_chain_dvca_req2b.cer"));
+ result.confirm("files match", helper_files_equal(Test::data_file("ecc/cvc_chain_dvca_req2b.cer"), Test::data_file("ecc/cvc_chain_dvca_req2.cer")));
+ EAC1_1_CVC dvca_cert2 = DE_EAC::sign_request(cvca_cert, cvca_privk, dvca_req2b, 2, 5, true, 3, 1, Test::rng());
+ result.test_eq("DVCA car", dvca_cert2.get_car().iso_8859(), "DECVCA00001");
+ result.test_eq("DVCA chr", dvca_cert2.get_chr().iso_8859(), "DEDVCAEPASS00002");
// make a first round IS request
- ECDSA_PrivateKey is_priv_key(rng, dom_pars);
- EAC1_1_Req is_req = DE_EAC::create_cvc_req(is_priv_key, ASN1_Chr("DEIS"), hash, rng);
- helper_write_file(is_req, CVC_TEST_DATA_DIR "/cvc_chain_is_req.cer");
+ ECDSA_PrivateKey is_priv_key(Test::rng(), dom_pars);
+ EAC1_1_Req is_req = DE_EAC::create_cvc_req(is_priv_key, ASN1_Chr("DEIS"), hash, Test::rng());
+ helper_write_file(is_req, Test::data_file("ecc/cvc_chain_is_req.cer"));
// sign the IS request
//dvca_cert1.set_domain_parameters(dom_pars);
- EAC1_1_CVC is_cert1 = DE_EAC::sign_request(dvca_cert1, dvca_priv_key, is_req, 1, 5, true, 3, 1, rng);
- CHECK_MESSAGE(is_cert1.get_car().iso_8859() == "DEDVCAEPASS00001", "car = " << is_cert1.get_car().iso_8859());
- CHECK(is_cert1.get_chr().iso_8859() == "DEIS00001");
- helper_write_file(is_cert1, CVC_TEST_DATA_DIR "/cvc_chain_is_cert.cer");
+ EAC1_1_CVC is_cert1 = DE_EAC::sign_request(dvca_cert1, dvca_priv_key, is_req, 1, 5, true, 3, 1, Test::rng());
+ result.test_eq("EAC 1.1 CVC car", is_cert1.get_car().iso_8859(), "DEDVCAEPASS00001");
+ result.test_eq("EAC 1.1 CVC chr", is_cert1.get_chr().iso_8859(), "DEIS00001");
+ helper_write_file(is_cert1, Test::data_file("ecc/cvc_chain_is_cert.cer"));
// verify the signature of the certificate
- CHECK(is_cert1.check_signature(dvca_priv_key));
- }
-
-}
+ result.confirm("valid signature", is_cert1.check_signature(dvca_priv_key));
-size_t test_cvc()
- {
- auto& rng = test_rng();
-
- test_enc_gen_selfsigned(rng);
- test_enc_gen_req(rng);
- test_cvc_req_ext(rng);
- test_cvc_ado_ext(rng);
- test_cvc_ado_creation(rng);
- test_cvc_ado_comparison(rng);
- test_eac_time(rng);
- test_ver_cvca(rng);
- test_copy_and_assignment(rng);
- test_eac_str_illegal_values(rng);
- test_tmp_eac_str_enc(rng);
- test_cvc_chain(rng);
-
- return 0;
+ return result;
}
-#else
-
-UNTESTED_WARNING(cvc);
-
-#endif // BOTAN_HAS_ECDSA && BOTAN_HAS_RSA
-
-#else
+class CVC_Unit_Tests : public Test
+ {
+ public:
+ std::vector<Test::Result> run() override
+ {
+ std::vector<Test::Result> results;
+
+ std::vector<std::function<Test::Result()>> fns = {
+ test_cvc_times,
+ test_enc_gen_selfsigned,
+ test_enc_gen_req,
+ test_cvc_req_ext,
+ test_cvc_ado_creation,
+ test_cvc_ado_comparison,
+ test_eac_time,
+ test_ver_cvca,
+ test_copy_and_assignment,
+ test_eac_str_illegal_values,
+ test_tmp_eac_str_enc,
+ test_cvc_chain
+ };
+
+ for(size_t i = 0; i != fns.size(); ++i)
+ {
+ try
+ {
+ results.push_back(fns[i]());
+ }
+ catch(std::exception& e)
+ {
+ results.push_back(Test::Result::Failure("CVC test " + std::to_string(i), e.what()));
+ }
+ }
+
+ return results;
+ }
+
+ };
+
+BOTAN_REGISTER_TEST("cvc", CVC_Unit_Tests);
+
+#endif
-SKIP_TEST(cvc);
+}
-#endif // BOTAN_HAS_CARD_VERIFIABLE_CERTIFICATES
+}
diff --git a/src/tests/test_dh.cpp b/src/tests/test_dh.cpp
index e48d41154..362ffcf24 100644
--- a/src/tests/test_dh.cpp
+++ b/src/tests/test_dh.cpp
@@ -7,67 +7,73 @@
#include "tests.h"
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
+ #include "test_pubkey.h"
+ #include <botan/pubkey.h>
+ #include <botan/dh.h>
+#endif
-#include "test_pubkey.h"
-
-#include <botan/pubkey.h>
-#include <botan/dh.h>
-#include <botan/hex.h>
-#include <iostream>
-#include <fstream>
-
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-size_t dh_sig_kat(const std::string& p,
- const std::string& g,
- const std::string& x,
- const std::string& y,
- std::string kdf,
- const std::string& outlen,
- const std::string& key)
- {
- auto& rng = test_rng();
-
- BigInt p_bn(p), g_bn(g), x_bn(x), y_bn(y);
-
- DL_Group domain(p_bn, g_bn);
-
- DH_PrivateKey mykey(rng, domain, x_bn);
- DH_PublicKey otherkey(domain, y_bn);
-
- if(kdf == "")
- kdf = "Raw";
-
- size_t keylen = 0;
- if(outlen != "")
- keylen = to_u32bit(outlen);
-
- PK_Key_Agreement kas(mykey, kdf);
-
- return validate_kas(kas, "DH/" + kdf, otherkey.public_value(), key, keylen);
- }
-
-}
+#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
-size_t test_dh()
+class Diffie_Hellman_KAT_Tests : public PK_Key_Agreement_Test
+ {
+ public:
+ Diffie_Hellman_KAT_Tests() : PK_Key_Agreement_Test(
+ "Diffie-Hellman",
+ Test::data_file("pubkey/dh.vec"),
+ {"P", "G", "X", "Y", "Msg", "OutLen", "K"},
+ {"KDF"})
+ {}
+
+ std::string default_kdf(const VarMap&) { return "Raw"; }
+
+ std::unique_ptr<Botan::Private_Key> load_our_key(const VarMap& vars) override
+ {
+ const Botan::BigInt p = get_req_bn(vars, "P");
+ const Botan::BigInt g = get_req_bn(vars, "G");
+ const Botan::BigInt x = get_req_bn(vars, "X");
+
+ const Botan::DL_Group grp(p, g);
+
+ std::unique_ptr<Botan::Private_Key> key(new Botan::DH_PrivateKey(Test::rng(), grp, x));
+ return key;
+ }
+
+ std::vector<uint8_t> load_their_key(const VarMap& vars) override
+ {
+ const Botan::BigInt p = get_req_bn(vars, "P");
+ const Botan::BigInt g = get_req_bn(vars, "G");
+ const Botan::BigInt y = get_req_bn(vars, "Y");
+ const Botan::DL_Group grp(p, g);
+
+ Botan::DH_PublicKey key(grp, y);
+ return key.public_value();
+ }
+ };
+
+class Diffie_Hellman_Keygen_Tests : public PK_Key_Generation_Test
{
- size_t fails = 0;
+ public:
+ std::vector<std::string> keygen_params() const override { return { "modp/ietf/1024", "modp/ietf/2048" }; }
- std::ifstream dh_sig(TEST_DATA_DIR_PK "/dh.vec");
+ std::unique_ptr<Botan::Private_Key> make_key(Botan::RandomNumberGenerator& rng,
+ const std::string& param) const override
+ {
+ Botan::DL_Group group(param);
+ std::unique_ptr<Botan::Private_Key> key(new Botan::DH_PrivateKey(rng, group));
+ return key;
+ }
+ };
- fails += run_tests_bb(dh_sig, "DH Kex", "K", true,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return dh_sig_kat(m["P"], m["G"], m["X"], m["Y"], m["KDF"], m["OutLen"], m["K"]);
- });
- return fails;
- }
+BOTAN_REGISTER_TEST("dh_kat", Diffie_Hellman_KAT_Tests);
+BOTAN_REGISTER_TEST("dh_keygen", Diffie_Hellman_Keygen_Tests);
-#else
+#endif
-SKIP_TEST(dh);
+}
-#endif // BOTAN_HAS_DIFFIE_HELLMAN
+}
diff --git a/src/tests/test_dlies.cpp b/src/tests/test_dlies.cpp
index bf367efb8..78b34d21b 100644
--- a/src/tests/test_dlies.cpp
+++ b/src/tests/test_dlies.cpp
@@ -6,93 +6,73 @@
#include "tests.h"
-#if defined(BOTAN_HAS_DLIES)
+#if defined(BOTAN_HAS_DLIES) && defined(BOTAN_HAS_DIFFIE_HELLMAN)
+ #include "test_pubkey.h"
+ #include <botan/dlies.h>
+ #include <botan/dh.h>
+ #include <botan/pubkey.h>
+#endif
-#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
-
-#include "test_pubkey.h"
-
-#include <iostream>
-#include <fstream>
-
-#include <botan/dlies.h>
-#include <botan/dh.h>
-#include <botan/hex.h>
-#include <botan/pubkey.h>
-
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-size_t dlies_kat(const std::string& p,
- const std::string& g,
- const std::string& x1,
- const std::string& x2,
- const std::string& msg,
- const std::string& ciphertext)
- {
- auto& rng = test_rng();
-
- BigInt p_bn(p);
- BigInt g_bn(g);
- BigInt x1_bn(x1);
- BigInt x2_bn(x2);
-
- DL_Group domain(p_bn, g_bn);
-
- DH_PrivateKey from(rng, domain, x1_bn);
- DH_PrivateKey to(rng, domain, x2_bn);
+#if defined(BOTAN_HAS_DLIES) && defined(BOTAN_HAS_DIFFIE_HELLMAN)
- const std::string opt_str = "KDF2(SHA-1)/HMAC(SHA-1)/16";
-
- std::vector<std::string> options = split_on(opt_str, '/');
+class DLIES_KAT_Tests : public Text_Based_Test
+ {
+ public:
+ DLIES_KAT_Tests() : Text_Based_Test(
+ Test::data_file("pubkey/dlies.vec"),
+ {"P", "G", "X1", "X2", "Msg", "Ciphertext"})
+ {}
- if(options.size() != 3)
- throw std::runtime_error("DLIES needs three options: " + opt_str);
+ Test::Result run_one_test(const std::string&, const VarMap& vars) override
+ {
+ const Botan::BigInt p = get_req_bn(vars, "P");
+ const Botan::BigInt g = get_req_bn(vars, "G");
+ const Botan::BigInt x1 = get_req_bn(vars, "X1");
+ const Botan::BigInt x2 = get_req_bn(vars, "X2");
- const size_t mac_key_len = to_u32bit(options[2]);
+ const std::vector<uint8_t> input = get_req_bin(vars, "Msg");
+ const std::vector<uint8_t> expected = get_req_bin(vars, "Ciphertext");
- DLIES_Encryptor e(from,
- KDF::create(options[0]).release(),
- MessageAuthenticationCode::create(options[1]).release(),
- mac_key_len);
+ Botan::DL_Group domain(p, g);
- DLIES_Decryptor d(to,
- KDF::create(options[0]).release(),
- MessageAuthenticationCode::create(options[1]).release(),
- mac_key_len);
+ Botan::DH_PrivateKey from(Test::rng(), domain, x1);
+ Botan::DH_PrivateKey to(Test::rng(), domain, x2);
- e.set_other_key(to.public_value());
+ const std::string kdf = "KDF2(SHA-1)";
+ const std::string mac = "HMAC(SHA-1)";
+ const size_t mac_key_len = 16;
- const std::string empty = "";
- return validate_encryption(e, d, "DLIES", msg, empty, ciphertext);
- }
+ Test::Result result("DLIES");
-}
+ Botan::DLIES_Encryptor encryptor(from,
+ Botan::KDF::create(kdf).release(),
+ Botan::MessageAuthenticationCode::create(mac).release(),
+ mac_key_len);
-size_t test_dlies()
- {
- size_t fails = 0;
+ Botan::DLIES_Decryptor decryptor(to,
+ Botan::KDF::create(kdf).release(),
+ Botan::MessageAuthenticationCode::create(mac).release(),
+ mac_key_len);
- std::ifstream dlies(TEST_DATA_DIR_PK "/dlies.vec");
+ encryptor.set_other_key(to.public_value());
- fails += run_tests_bb(dlies, "DLIES Encryption", "Ciphertext", true,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return dlies_kat(m["P"], m["G"], m["X1"], m["X2"], m["Msg"], m["Ciphertext"]);
- });
+ result.test_eq("encryption", encryptor.encrypt(input, Test::rng()), expected);
+ result.test_eq("decryption", decryptor.decrypt(expected), input);
- return fails;
- }
+ check_invalid_ciphertexts(result, decryptor, input, expected);
-#else
+ return result;
+ }
+ };
-UNTESTED_WARNING(dlies);
+BOTAN_REGISTER_TEST("dlies", DLIES_KAT_Tests);
-#endif // BOTAN_HAS_DIFFIE_HELLMAN
+#endif
-#else
-
-SKIP_TEST(dlies);
+}
-#endif // BOTAN_HAS_DLIES
+}
diff --git a/src/tests/test_dsa.cpp b/src/tests/test_dsa.cpp
index 37b2851af..71d581474 100644
--- a/src/tests/test_dsa.cpp
+++ b/src/tests/test_dsa.cpp
@@ -7,64 +7,65 @@
#include "tests.h"
#if defined(BOTAN_HAS_DSA)
+ #include <botan/dsa.h>
+ #include "test_pubkey.h"
+#endif
-#include "test_pubkey.h"
-
-#include <botan/pubkey.h>
-#include <botan/dsa.h>
-#include <botan/hex.h>
-#include <iostream>
-#include <fstream>
-
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-size_t dsa_sig_kat(const std::string& p,
- const std::string& q,
- const std::string& g,
- const std::string& x,
- const std::string& hash,
- const std::string& msg,
- const std::string& nonce,
- const std::string& signature)
- {
- auto& rng = test_rng();
-
- BigInt p_bn("0x" + p), q_bn("0x" + q), g_bn("0x" + g), x_bn("0x" + x);
-
- DL_Group group(p_bn, q_bn, g_bn);
- DSA_PrivateKey privkey(rng, group, x_bn);
-
- DSA_PublicKey pubkey = privkey;
-
- const std::string padding = "EMSA1(" + hash + ")";
-
- PK_Verifier verify(pubkey, padding);
- PK_Signer sign(privkey, padding);
-
- return validate_signature(verify, sign, "DSA/" + hash, msg, rng, nonce, signature);
- }
-
-}
+#if defined(BOTAN_HAS_DSA)
-size_t test_dsa()
+class DSA_KAT_Tests : public PK_Signature_Generation_Test
{
- size_t fails = 0;
-
- std::ifstream dsa_sig(TEST_DATA_DIR_PK "/dsa.vec");
+ public:
+ DSA_KAT_Tests() : PK_Signature_Generation_Test(
+ "DSA",
+ Test::data_file("pubkey/dsa.vec"),
+ {"P", "Q", "G", "X", "Hash", "Msg", "Signature"})
+ {}
+
+ bool clear_between_callbacks() const override { return false; }
+
+ std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override
+ {
+ const Botan::BigInt p = get_req_bn(vars, "P");
+ const Botan::BigInt q = get_req_bn(vars, "Q");
+ const Botan::BigInt g = get_req_bn(vars, "G");
+ const Botan::BigInt x = get_req_bn(vars, "X");
+
+ const Botan::DL_Group grp(p, q, g);
+
+ std::unique_ptr<Botan::Private_Key> key(new Botan::DSA_PrivateKey(Test::rng(), grp, x));
+ return key;
+ }
+
+ std::string default_padding(const VarMap& vars) const override
+ {
+ return "EMSA1(" + get_req_str(vars, "Hash") + ")";
+ }
+ };
+
+class DSA_Keygen_Tests : public PK_Key_Generation_Test
+ {
+ public:
+ std::vector<std::string> keygen_params() const override { return { "dsa/jce/1024", "dsa/botan/2048" }; }
- fails += run_tests_bb(dsa_sig, "DSA Signature", "Signature", false,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return dsa_sig_kat(m["P"], m["Q"], m["G"], m["X"], m["Hash"], m["Msg"], m["Nonce"], m["Signature"]);
- });
+ std::unique_ptr<Botan::Private_Key> make_key(Botan::RandomNumberGenerator& rng,
+ const std::string& param) const override
+ {
+ Botan::DL_Group group(param);
+ std::unique_ptr<Botan::Private_Key> key(new Botan::DSA_PrivateKey(rng, group));
+ return key;
+ }
+ };
- return fails;
- }
+BOTAN_REGISTER_TEST("dsa_kat", DSA_KAT_Tests);
+BOTAN_REGISTER_TEST("dsa_keygen", DSA_Keygen_Tests);
-#else
+#endif
-SKIP_TEST(dsa);
+}
-#endif // BOTAN_HAS_DSA
+}
diff --git a/src/tests/test_ecc_pointmul.cpp b/src/tests/test_ecc_pointmul.cpp
index b8537ec64..818fc4460 100644
--- a/src/tests/test_ecc_pointmul.cpp
+++ b/src/tests/test_ecc_pointmul.cpp
@@ -6,78 +6,52 @@
#include "tests.h"
-#if defined(BOTAN_HAS_ECC_GROUP)
-
#if defined(BOTAN_HAS_ECDSA)
+ #include "test_pubkey.h"
+ #include <botan/pubkey.h>
+ #include <botan/ecdsa.h>
+ #include <botan/oids.h>
+#endif
-#include "test_pubkey.h"
-
-#include <botan/pubkey.h>
-#include <botan/ecdsa.h>
-#include <botan/oids.h>
-#include <botan/hex.h>
-#include <iostream>
-#include <fstream>
-
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-size_t ecc_point_mul(const std::string& group_id,
- const std::string& m_s,
- const std::string& X_s,
- const std::string& Y_s)
+#if defined(BOTAN_HAS_ECDSA)
+class ECC_Pointmult_Tests : public Text_Based_Test
{
- EC_Group group(OIDS::lookup(group_id));
-
- const BigInt m(m_s);
- const BigInt X(X_s);
- const BigInt Y(Y_s);
-
- PointGFp p = group.get_base_point() * m;
-
- size_t fails = 0;
+ public:
+ ECC_Pointmult_Tests() : Text_Based_Test(
+ Test::data_file("pubkey/ecc.vec"),
+ {"Group", "m", "X", "Y"})
+ {}
- if(p.get_affine_x() != X)
- {
- std::cout << p.get_affine_x() << " != " << X << std::endl;
- ++fails;
- }
+ bool clear_between_callbacks() const override { return false; }
- if(p.get_affine_y() != Y)
- {
- std::cout << p.get_affine_y() << " != " << Y << std::endl;
- ++fails;
- }
+ Test::Result run_one_test(const std::string&, const VarMap& vars) override
+ {
+ const std::string group_id = get_req_str(vars, "Group");
- return fails;
- }
+ const Botan::BigInt m = get_req_bn(vars, "m");
+ const Botan::BigInt X = get_req_bn(vars, "X");
+ const Botan::BigInt Y = get_req_bn(vars, "Y");
-}
-
-size_t test_ecc_pointmul()
- {
- size_t fails = 0;
-
- std::ifstream ecc_mul(TEST_DATA_DIR_PK "/ecc.vec");
+ Botan::EC_Group group(Botan::OIDS::lookup(group_id));
- fails += run_tests_bb(ecc_mul, "ECC Point Mult", "Y", false,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return ecc_point_mul(m["Group"], m["m"], m["X"], m["Y"]);
- });
+ const Botan::PointGFp p = group.get_base_point() * m;
- return fails;
- }
+ Test::Result result("ECC Scalarmult");
+ result.test_eq("affine X", p.get_affine_x(), X);
+ result.test_eq("affine Y", p.get_affine_y(), Y);
-#else
+ return result;
+ }
+ };
-UNTESTED_WARNING(ecc_pointmul);
+BOTAN_REGISTER_TEST("ecc_pointmul", ECC_Pointmult_Tests);
-#endif // BOTAN_HAS_ECDSA
+#endif
-#else
-
-SKIP_TEST(ecc_pointmul);
+}
-#endif // BOTAN_HAS_ECC_GROUP
+}
diff --git a/src/tests/test_ecdsa.cpp b/src/tests/test_ecdsa.cpp
index 1e8dcb7d7..e18038676 100644
--- a/src/tests/test_ecdsa.cpp
+++ b/src/tests/test_ecdsa.cpp
@@ -7,59 +7,63 @@
#include "tests.h"
#if defined(BOTAN_HAS_ECDSA)
+ #include "test_pubkey.h"
+ #include <botan/ecdsa.h>
+ #include <botan/oids.h>
+#endif
-#include "test_pubkey.h"
-
-#include <botan/pubkey.h>
-#include <botan/ecdsa.h>
-#include <botan/oids.h>
-#include <botan/hex.h>
-#include <iostream>
-#include <fstream>
-
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-size_t ecdsa_sig_kat(const std::string& group_id,
- const std::string& x,
- const std::string& hash,
- const std::string& msg,
- const std::string& signature)
- {
- auto& rng = test_rng();
-
- EC_Group group(OIDS::lookup(group_id));
- ECDSA_PrivateKey ecdsa(rng, group, BigInt(x));
-
- const std::string padding = "EMSA1(" + hash + ")";
-
- PK_Verifier verify(ecdsa, padding, IEEE_1363, "base");
- PK_Signer sign(ecdsa, padding, IEEE_1363, "base");
-
- return validate_signature(verify, sign, "ECDSA/" + group_id + "/" + hash,
- msg, rng, signature);
- }
-
-}
+#if defined(BOTAN_HAS_ECDSA)
-size_t test_ecdsa()
+class ECDSA_Signature_KAT_Tests : public PK_Signature_Generation_Test
{
- size_t fails = 0;
-
- std::ifstream ecdsa_sig(TEST_DATA_DIR_PK "/ecdsa.vec");
+ public:
+ ECDSA_Signature_KAT_Tests() : PK_Signature_Generation_Test(
+ "ECDSA",
+ Test::data_file("pubkey/ecdsa.vec"),
+ {"Group", "X", "Hash", "Msg", "Signature"})
+ {}
+
+ bool clear_between_callbacks() const override { return false; }
+
+ std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override
+ {
+ const std::string group_id = get_req_str(vars, "Group");
+ const BigInt x = get_req_bn(vars, "X");
+ Botan::EC_Group group(Botan::OIDS::lookup(group_id));
+
+ std::unique_ptr<Botan::Private_Key> key(new Botan::ECDSA_PrivateKey(Test::rng(), group, x));
+ return key;
+ }
+
+ std::string default_padding(const VarMap& vars) const override
+ {
+ return "EMSA1(" + get_req_str(vars, "Hash") + ")";
+ }
+ };
+
+class ECDSA_Keygen_Tests : public PK_Key_Generation_Test
+ {
+ public:
+ std::vector<std::string> keygen_params() const override { return { "secp256r1", "secp384r1", "secp521r1" }; }
- fails += run_tests_bb(ecdsa_sig, "ECDSA Signature", "Signature", false,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return ecdsa_sig_kat(m["Group"], m["X"], m["Hash"], m["Msg"], m["Signature"]);
- });
+ std::unique_ptr<Botan::Private_Key> make_key(Botan::RandomNumberGenerator& rng,
+ const std::string& param) const override
+ {
+ Botan::EC_Group group(param);
+ std::unique_ptr<Botan::Private_Key> key(new Botan::ECDSA_PrivateKey(rng, group));
+ return key;
+ }
+ };
- return fails;
- }
+BOTAN_REGISTER_TEST("ecdsa", ECDSA_Signature_KAT_Tests);
+BOTAN_REGISTER_TEST("ecdsa_keygen", ECDSA_Keygen_Tests);
-#else
+#endif
-SKIP_TEST(ecdsa);
+}
-#endif // BOTAN_HAS_ECDSA
+}
diff --git a/src/tests/test_elg.cpp b/src/tests/test_elg.cpp
index 7bfb02e46..1dfbdf92f 100644
--- a/src/tests/test_elg.cpp
+++ b/src/tests/test_elg.cpp
@@ -7,68 +7,59 @@
#include "tests.h"
#if defined(BOTAN_HAS_ELGAMAL)
+ #include <botan/elgamal.h>
+ #include "test_pubkey.h"
+#endif
-#include "test_pubkey.h"
-
-#include <botan/hex.h>
-#include <botan/elgamal.h>
-#include <botan/pubkey.h>
-#include <botan/dl_group.h>
-#include <iostream>
-#include <fstream>
-
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-size_t elgamal_kat(const std::string& p,
- const std::string& g,
- const std::string& x,
- const std::string& msg,
- std::string padding,
- const std::string& nonce,
- const std::string& ciphertext)
- {
- auto& rng = test_rng();
-
- const BigInt p_bn = BigInt(p);
- const BigInt g_bn = BigInt(g);
- const BigInt x_bn = BigInt(x);
-
- DL_Group group(p_bn, g_bn);
- ElGamal_PrivateKey privkey(rng, group, x_bn);
-
- ElGamal_PublicKey pubkey = privkey;
-
- if(padding == "")
- padding = "Raw";
-
- PK_Encryptor_EME enc(pubkey, padding);
- PK_Decryptor_EME dec(privkey, padding);
-
- return validate_encryption(enc, dec, "ElGamal/" + padding, msg, nonce, ciphertext);
- }
-
-}
+#if defined(BOTAN_HAS_ELGAMAL)
-size_t test_elgamal()
+class ElGamal_KAT_Tests : public PK_Encryption_Decryption_Test
{
- size_t fails = 0;
+ public:
+ ElGamal_KAT_Tests() : PK_Encryption_Decryption_Test(
+ "ElGamal",
+ Test::data_file("pubkey/elgamal.vec"),
+ {"P", "G", "X", "Msg", "Nonce", "Ciphertext"},
+ {"Padding"})
+ {}
+
+ std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override
+ {
+ const Botan::BigInt p = get_req_bn(vars, "P");
+ const Botan::BigInt g = get_req_bn(vars, "G");
+ const Botan::BigInt x = get_req_bn(vars, "X");
+
+ const Botan::DL_Group grp(p, g);
+
+ std::unique_ptr<Botan::Private_Key> key(new Botan::ElGamal_PrivateKey(Test::rng(), grp, x));
+ return key;
+ }
+ };
+
+class ElGamal_Keygen_Tests : public PK_Key_Generation_Test
+ {
+ public:
+ std::vector<std::string> keygen_params() const override { return { "modp/ietf/1024", "modp/ietf/2048" }; }
- std::ifstream elgamal_enc(TEST_DATA_DIR_PK "/elgamal.vec");
+ std::unique_ptr<Botan::Private_Key> make_key(Botan::RandomNumberGenerator& rng,
+ const std::string& param) const override
+ {
+ Botan::DL_Group group(param);
+ std::unique_ptr<Botan::Private_Key> key(new Botan::ElGamal_PrivateKey(rng, group));
+ return key;
+ }
- fails += run_tests_bb(elgamal_enc, "ElGamal Encryption", "Ciphertext", true,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return elgamal_kat(m["P"], m["G"], m["X"], m["Msg"],
- m["Padding"], m["Nonce"], m["Ciphertext"]);
- });
+ };
- return fails;
- }
+BOTAN_REGISTER_TEST("elgamal_kat", ElGamal_KAT_Tests);
+BOTAN_REGISTER_TEST("elgamal_keygen", ElGamal_Keygen_Tests);
-#else
+#endif
-SKIP_TEST(elgamal);
+}
-#endif // BOTAN_HAS_ELGAMAL
+}
diff --git a/src/tests/test_ffi.cpp b/src/tests/test_ffi.cpp
index ecaa4a27c..c848729a6 100644
--- a/src/tests/test_ffi.cpp
+++ b/src/tests/test_ffi.cpp
@@ -4,393 +4,398 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
-#include "catchy/catchy_tests.h"
-
-#if defined(BOTAN_HAS_FFI)
-
+#include "tests.h"
#include <botan/version.h>
+#if defined(BOTAN_HAS_FFI)
#include <botan/hex.h>
#include <botan/ffi.h>
+#endif
-using Botan::hex_encode;
-using Botan::hex_decode;
+namespace Botan_Tests {
-TEST_CASE("FFI versioning", "[ffi]")
- {
- CHECK_THAT(botan_ffi_api_version(), Equals(BOTAN_HAS_FFI));
- CHECK_THAT(botan_version_major(), Equals(Botan::version_major()));
- CHECK_THAT(botan_version_minor(), Equals(Botan::version_minor()));
- CHECK_THAT(botan_version_patch(), Equals(Botan::version_patch()));
- }
+namespace {
-TEST_CASE("FFI hex", "[ffi]")
- {
- const std::vector<uint8_t> bin = { 0xAA, 0xDE, 0x01 };
- std::string out;
- out.resize(2*bin.size());
+#if defined(BOTAN_HAS_FFI)
- CHECK_THAT(botan_hex_encode(bin.data(), bin.size(), &out[0], 0), Equals(0));
- CHECK_THAT(out, Equals("AADE01"));
+#define TEST_FFI_OK(func, args) result.test_rc_ok(#func, func args)
+#define TEST_FFI_FAIL(msg, func, args) result.test_rc_fail(#func, msg, func args)
- CHECK_THAT(botan_hex_encode(bin.data(), bin.size(), &out[0], BOTAN_FFI_HEX_LOWER_CASE), Equals(0));
- CHECK_THAT(out, Equals("aade01"));
+#define REQUIRE_FFI_OK(func, args) \
+ if(!TEST_FFI_OK(func, args)) { \
+ result.test_note("Exiting test early due to failure"); \
+ return result; \
}
-TEST_CASE("FFI RNG", "[ffi]")
+class FFI_Unit_Tests : public Test
{
- botan_rng_t rng;
- unsigned char buf[512];
+ public:
+ std::vector<Test::Result> run() override
+ {
+ Test::Result result("FFI");
+
+ result.test_is_eq("FFI API version", botan_ffi_api_version(), uint32_t(BOTAN_HAS_FFI));
+ result.test_is_eq("Major version", botan_version_major(), Botan::version_major());
+ result.test_is_eq("Minor version", botan_version_minor(), Botan::version_minor());
+ result.test_is_eq("Patch version", botan_version_patch(), Botan::version_patch());
- CHECK(botan_rng_init(&rng, "bad_type") < 0);
+ const std::vector<uint8_t> bin = { 0xAA, 0xDE, 0x01 };
+ const char* input_str = "ABC";
- const std::vector<std::string> types = { "system", "user" };
+ std::string outstr;
+ std::vector<uint8_t> outbuf;
+ //char namebuf[32];
- for(const auto type : types)
- {
- REQUIRE_THAT(botan_rng_init(&rng, type.c_str()), Equals(0));
- CHECK_THAT(botan_rng_get(rng, buf, sizeof(buf)), Equals(0));
- CHECK_THAT(botan_rng_reseed(rng, 256), Equals(0));
+ outstr.resize(2*bin.size());
+ TEST_FFI_OK(botan_hex_encode, (bin.data(), bin.size(), &outstr[0], 0));
+ result.test_eq("uppercase hex", outstr, "AADE01");
- int ret = botan_rng_destroy(rng); // Catch evalues expresstion multiple times
- CHECK_THAT(ret, Equals(0));
- }
- }
+ TEST_FFI_OK(botan_hex_encode, (bin.data(), bin.size(), &outstr[0], BOTAN_FFI_HEX_LOWER_CASE));
+ result.test_eq("lowercase hex", outstr, "aade01");
-TEST_CASE("FFI hash", "[ffi]")
- {
- botan_hash_t hash;
- CHECK(botan_hash_init(&hash, "SHA-256", 1) < 0);
- REQUIRE_THAT(botan_hash_init(&hash, "SHA-256", 0), Equals(0));
+ // RNG test and initialization
+ botan_rng_t rng;
- /*
- char namebuf[32];
- CHECK(botan_hash_name(hash, namebuf, 5) < 0);
- CHECK_THAT(botan_hash_name(hash, namebuf, 31));
- CHECK(std::string(namebuf) == "SHA-256");
- */
+ TEST_FFI_FAIL("invalid rng type", botan_rng_init, (&rng, "invalid_type"));
- size_t ol;
- CHECK_THAT(botan_hash_output_length(hash, &ol), Equals(0));
- CHECK_THAT(ol, Equals(32));
+ outbuf.resize(512);
- const char* s = "ABC";
+ if(TEST_FFI_OK(botan_rng_init, (&rng, "system")))
+ {
+ TEST_FFI_OK(botan_rng_get, (rng, outbuf.data(), outbuf.size()));
+ TEST_FFI_OK(botan_rng_reseed, (rng, 256));
+ TEST_FFI_OK(botan_rng_destroy, (rng));
+ }
- std::vector<uint8_t> outbuf(ol);
+ TEST_FFI_OK(botan_rng_init, (&rng, "user"));
+ TEST_FFI_OK(botan_rng_get, (rng, outbuf.data(), outbuf.size()));
+ TEST_FFI_OK(botan_rng_reseed, (rng, 256));
+ // used for the rest of this function and destroyed at the end
+
+ // hashing test
+ botan_hash_t hash;
+ TEST_FFI_FAIL("invalid hash name", botan_hash_init, (&hash, "SHA-255", 0));
+ TEST_FFI_FAIL("invalid flags", botan_hash_init, (&hash, "SHA-256", 1));
+
+ if(TEST_FFI_OK(botan_hash_init, (&hash, "SHA-256", 0)))
+ {
+ /*
+ TEST_FFI_FAIL("output buffer too short", botan_hash_name, (hash, namebuf, 5));
+
+ if(TEST_FFI_OK(botan_hash_name, (hash, namebuf, sizeof(namebuf))))
+ {
+ result.test_eq("hash name", std::string(namebuf), "SHA-256");
+ }
+ */
+
+ size_t output_len;
+ if(TEST_FFI_OK(botan_hash_output_length, (hash, &output_len)))
+ {
+ result.test_eq("hash output length", output_len, 32);
+
+ outbuf.resize(output_len);
+
+ // Test that after clear or final the object can be reused
+ for(size_t r = 0; r != 2; ++r)
+ {
+ TEST_FFI_OK(botan_hash_update, (hash, reinterpret_cast<const uint8_t*>(input_str), 1));
+ TEST_FFI_OK(botan_hash_clear, (hash));
+
+ TEST_FFI_OK(botan_hash_update, (hash, reinterpret_cast<const uint8_t*>(input_str), std::strlen(input_str)));
+ TEST_FFI_OK(botan_hash_final, (hash, outbuf.data()));
+
+ result.test_eq("SHA-256 output", outbuf, "B5D4045C3F466FA91FE2CC6ABE79232A1A57CDF104F7A26E716E0A1E2789DF78");
+ }
+
+ TEST_FFI_OK(botan_hash_destroy, (hash));
+ }
+ }
+
+ // MAC test
+ botan_mac_t mac;
+ TEST_FFI_FAIL("bad flag", botan_mac_init, (&mac, "HMAC(SHA-256)", 1));
+ TEST_FFI_FAIL("bad name", botan_mac_init, (&mac, "HMAC(SHA-259)", 0));
+
+ if(TEST_FFI_OK(botan_mac_init, (&mac, "HMAC(SHA-256)", 0)))
+ {
+ /*
+ TEST_FFI_FAIL("output buffer too short", botan_mac_name, (mac, namebuf, 5));
+
+ if(TEST_FFI_OK(botan_mac_name, (mac, namebuf, 20)))
+ {
+ result.test_eq("mac name", std::string(namebuf), "HMAC(SHA-256)");
+ }
+ */
+
+ size_t output_len;
+ if(TEST_FFI_OK(botan_mac_output_length, (mac, &output_len)))
+ {
+ result.test_eq("MAC output length", output_len, 32);
+
+ const byte mac_key[] = { 0xAA, 0xBB, 0xCC, 0xDD };
+ TEST_FFI_OK(botan_mac_set_key, (mac, mac_key, sizeof(mac_key)));
+
+ outbuf.resize(output_len);
+
+ TEST_FFI_OK(botan_mac_update, (mac, reinterpret_cast<const uint8_t*>(input_str), std::strlen(input_str)));
+
+ TEST_FFI_OK(botan_mac_final, (mac, outbuf.data()));
+
+ result.test_eq("HMAC output", outbuf, "1A82EEA984BC4A7285617CC0D05F1FE1D6C96675924A81BC965EE8FF7B0697A7");
+
+ TEST_FFI_OK(botan_mac_destroy, (mac));
+ }
+ }
+
+ const std::vector<uint8_t> pbkdf_salt = Botan::hex_decode("ED1F39A0A7F3889AAF7E60743B3BC1CC2C738E60");
+ const std::string passphrase = "ltexmfeyylmlbrsyikaw";
+ const size_t pbkdf_out_len = 10;
+ const size_t pbkdf_iterations = 1000;
+
+ outbuf.resize(pbkdf_out_len);
+
+ if(TEST_FFI_OK(botan_pbkdf, ("PBKDF2(SHA-1)",
+ outbuf.data(), outbuf.size(),
+ passphrase.c_str(),
+ pbkdf_salt.data(), pbkdf_salt.size(),
+ pbkdf_iterations)))
+ {
+ result.test_eq("PBKDF output", outbuf, "027AFADD48F4BE8DCC4F");
+ }
+
+ size_t iters_10ms, iters_100ms;
+
+ TEST_FFI_OK(botan_pbkdf_timed, ("PBKDF2(SHA-1)", outbuf.data(), outbuf.size(),
+ passphrase.c_str(),
+ pbkdf_salt.data(), pbkdf_salt.size(),
+ 10, &iters_10ms));
+ TEST_FFI_OK(botan_pbkdf_timed, ("PBKDF2(SHA-1)", outbuf.data(), outbuf.size(),
+ passphrase.c_str(),
+ pbkdf_salt.data(), pbkdf_salt.size(),
+ 100, &iters_100ms));
+
+ result.test_note("PBKDF timed 10 ms " + std::to_string(iters_10ms) + " iterations " +
+ "100 ms " + std::to_string(iters_100ms) + " iterations");
+
+ const std::vector<uint8_t> kdf_secret = Botan::hex_decode("92167440112E");
+ const std::vector<uint8_t> kdf_salt = Botan::hex_decode("45A9BEDED69163123D0348F5185F61ABFB1BF18D6AEA454F");
+ const size_t kdf_out_len = 18;
+ outbuf.resize(kdf_out_len);
+
+ if(TEST_FFI_OK(botan_kdf, ("KDF2(SHA-1)", outbuf.data(), outbuf.size(),
+ kdf_secret.data(),
+ kdf_secret.size(),
+ kdf_salt.data(),
+ kdf_salt.size())))
+ {
+ result.test_eq("KDF output", outbuf, "3A5DC9AA1C872B4744515AC2702D6396FC2A");
+ }
+
+ size_t out_len = 64;
+ outstr.resize(out_len);
+ TEST_FFI_OK(botan_bcrypt_generate, (reinterpret_cast<uint8_t*>(&outstr[0]), &out_len, passphrase.c_str(), rng, 3, 0));
+ result.test_eq("bcrypt output size", out_len, 61);
+
+ TEST_FFI_OK(botan_bcrypt_is_valid, (passphrase.c_str(), outstr.data()));
+ TEST_FFI_FAIL("bad password", botan_bcrypt_is_valid, ("nope", outstr.data()));
+
+ std::vector<Test::Result> results;
+ results.push_back(ffi_test_rsa(rng));
+ results.push_back(ffi_test_ecdsa(rng));
+
+ TEST_FFI_OK(botan_rng_destroy, (rng));
+
+ results.push_back(result);
+ return results;
+ }
+
+ private:
+ Test::Result ffi_test_rsa(botan_rng_t rng)
+ {
+ Test::Result result("FFI");
+
+ botan_privkey_t priv;
+ if(TEST_FFI_OK(botan_privkey_create_rsa, (&priv, rng, 1024)))
+ {
+ botan_pubkey_t pub;
+ TEST_FFI_OK(botan_privkey_export_pubkey, (&pub, priv));
+
+ char namebuf[32] = { 0 };
+ size_t name_len = sizeof(namebuf);
+ if(TEST_FFI_OK(botan_pubkey_algo_name, (pub, namebuf, &name_len)))
+ {
+ result.test_eq("algo name", std::string(namebuf), "RSA");
+ }
- int retUpdate = botan_hash_update(hash, reinterpret_cast<const uint8_t*>(s), 3);
- CHECK_THAT(retUpdate, Equals(0));
+ botan_pk_op_encrypt_t encrypt;
+
+ if(TEST_FFI_OK(botan_pk_op_encrypt_create, (&encrypt, pub, "OAEP(SHA-256)", 0)))
+ {
+ std::vector<uint8_t> plaintext(32);
+ TEST_FFI_OK(botan_rng_get, (rng, plaintext.data(), plaintext.size()));
- int retFinal = botan_hash_final(hash, outbuf.data());
- CHECK_THAT(retFinal, Equals(0));
+ std::vector<uint8_t> ciphertext(256); // TODO: no way to know this size from API
+ size_t ctext_len = ciphertext.size();
- //CHECK_ARRAY(outbuf, "B5D4045C3F466FA91FE2CC6ABE79232A1A57CDF104F7A26E716E0A1E2789DF78");
- CHECK_THAT(hex_encode(outbuf), Equals("B5D4045C3F466FA91FE2CC6ABE79232A1A57CDF104F7A26E716E0A1E2789DF78"));
+ if(TEST_FFI_OK(botan_pk_op_encrypt, (encrypt, rng,
+ ciphertext.data(), &ctext_len,
+ plaintext.data(), plaintext.size())))
+ {
+ ciphertext.resize(ctext_len);
+
+ TEST_FFI_OK(botan_pk_op_encrypt_destroy, (encrypt));
+
+ botan_pk_op_decrypt_t decrypt;
+ if(TEST_FFI_OK(botan_pk_op_decrypt_create, (&decrypt, priv, "OAEP(SHA-256)", 0)))
+ {
+ std::vector<uint8_t> decrypted(256); // TODO as with above
+ size_t decrypted_len = decrypted.size();
+ TEST_FFI_OK(botan_pk_op_decrypt, (decrypt, decrypted.data(), &decrypted_len,
+ ciphertext.data(), ciphertext.size()));
+ decrypted.resize(decrypted_len);
+
+ result.test_eq("RSA plaintext", decrypted, plaintext);
+
+ TEST_FFI_OK(botan_pk_op_decrypt_destroy, (decrypt));
+ }
+ }
+ }
+
+ TEST_FFI_OK(botan_pubkey_destroy, (pub));
+ TEST_FFI_OK(botan_privkey_destroy, (priv));
+ }
+
+ return result;
+ }
+
+ Test::Result ffi_test_ecdsa(botan_rng_t rng)
+ {
+ Test::Result result("FFI");
- CHECK_THAT(botan_hash_clear(hash), Equals(0));
- int ret = botan_hash_destroy(hash);
- CHECK_THAT(ret, Equals(0));
- }
+ botan_privkey_t priv;
-TEST_CASE("FFI mac", "[ffi]")
- {
- botan_mac_t mac;
- CHECK_THAT(botan_mac_init(&mac, "HMAC(SHA-256)", 1), Equals(-1)); // bad flag
- CHECK_THAT(botan_mac_init(&mac, "HMAC(SHA-259)", 0), Equals(-2)); // bad name
- CHECK_THAT(botan_mac_init(&mac, "HMAC(SHA-256)", 0), Equals(0));
+ if(TEST_FFI_OK(botan_privkey_create_ecdsa, (&priv, rng, "secp384r1")))
+ {
+ botan_pubkey_t pub;
+ TEST_FFI_OK(botan_privkey_export_pubkey, (&pub, priv));
- //char namebuf[32];
- //CHECK(botan_mac_name(mac, namebuf, 10) < 0);
- //CHECK_THAT(botan_mac_name(mac, namebuf, 31), Equals(0));
- //CHECK(std::string(namebuf) == "HMAC(SHA-256)");
+ char namebuf[32] = { 0 };
+ size_t name_len = sizeof(namebuf);
+ TEST_FFI_OK(botan_pubkey_algo_name, (pub, &namebuf[0], &name_len));
+
+ result.test_eq(namebuf, namebuf, "ECDSA");
- size_t ol;
- CHECK_THAT(botan_mac_output_length(mac, &ol), Equals(0));
- CHECK_THAT(ol, Equals(32));
+ std::vector<uint8_t> message(1280), signature;
+ TEST_FFI_OK(botan_rng_get, (rng, message.data(), message.size()));
- const uint8_t key[] = { 0xAA, 0xBB, 0xCC, 0xDD };
+ botan_pk_op_sign_t signer;
- CHECK_THAT(botan_mac_set_key(mac, key, 4), Equals(0));
- const char* s = "ABC";
+ if(TEST_FFI_OK(botan_pk_op_sign_create, (&signer, priv, "EMSA1(SHA-384)", 0)))
+ {
+ // TODO: break input into multiple calls to update
+ TEST_FFI_OK(botan_pk_op_sign_update, (signer, message.data(), message.size()));
- std::vector<uint8_t> outbuf(ol);
+ signature.resize(96); // TODO: no way to derive this from API
+ size_t sig_len = signature.size();
+ TEST_FFI_OK(botan_pk_op_sign_finish, (signer, rng, signature.data(), &sig_len));
+ signature.resize(sig_len);
- int retUpdate = botan_mac_update(mac, reinterpret_cast<const uint8_t*>(s), 3);
- CHECK_THAT(retUpdate, Equals(0));
+ TEST_FFI_OK(botan_pk_op_sign_destroy, (signer));
+ }
- int retFinal = botan_mac_final(mac, outbuf.data());
- CHECK_THAT(retFinal, Equals(0));
+ botan_pk_op_verify_t verifier;
- CHECK_THAT(hex_encode(outbuf), Equals("1A82EEA984BC4A7285617CC0D05F1FE1D6C96675924A81BC965EE8FF7B0697A7"));
+ if(TEST_FFI_OK(botan_pk_op_verify_create, (&verifier, pub, "EMSA1(SHA-384)", 0)))
+ {
+ TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
+ TEST_FFI_OK(botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
- CHECK_THAT(botan_mac_clear(mac), Equals(0));
+ // TODO: randomize this
+ signature[0] ^= 1;
+ TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
+ TEST_FFI_FAIL("bad signature", botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
- int retDestroy = botan_mac_destroy(mac);
- CHECK_THAT(retDestroy, Equals(0));
- }
+ message[0] ^= 1;
+ TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
+ TEST_FFI_FAIL("bad signature", botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
-TEST_CASE("FFI PBKDF", "[ffi]")
- {
- const std::vector<uint8_t> salt = hex_decode("ED1F39A0A7F3889AAF7E60743B3BC1CC2C738E60");
- const std::string passphrase = "ltexmfeyylmlbrsyikaw";
- const size_t out_len = 10;
- const size_t iterations = 1000;
-
- std::vector<uint8_t> outbuf(out_len);
-
- CHECK_THAT(botan_pbkdf("PBKDF2(SHA-1)", outbuf.data(), outbuf.size(),
- passphrase.c_str(), salt.data(), salt.size(), iterations),
- Equals(0));
-
- CHECK_THAT(hex_encode(outbuf), Equals("027AFADD48F4BE8DCC4F"));
-
- size_t iters_10ms, iters_100ms;
- CHECK_THAT(botan_pbkdf_timed("PBKDF2(SHA-1)", outbuf.data(), outbuf.size(),
- passphrase.c_str(), salt.data(), salt.size(), 10, &iters_10ms),
- Equals(0));
- CHECK_THAT(botan_pbkdf_timed("PBKDF2(SHA-1)", outbuf.data(), outbuf.size(),
- passphrase.c_str(), salt.data(), salt.size(), 100, &iters_100ms),
- Equals(0));
-
- CHECK(iters_10ms >= 10000);
-
- /*
- * Tests deactivated due to consistently failing when optimizations are disabled
- * See also: https://github.com/randombit/botan/commit/30b0e3c88e94ba04c1843798f7ac74a008e01d9b
- */
- /*
- INFO("Iterations " << iters_10ms << " " << iters_100ms);
- const double ratio = static_cast<double>(iters_100ms) / iters_10ms;
- // Loose timing to avoid false positives on CI
- CHECK(ratio >= 3);
- CHECK(ratio <= 15);
- */
- }
+ signature[0] ^= 1;
+ TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
+ TEST_FFI_FAIL("bad signature", botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
-TEST_CASE("FFI KDF", "[ffi]")
- {
- const std::vector<uint8_t> secret = hex_decode("92167440112E");
- const std::vector<uint8_t> salt = hex_decode("45A9BEDED69163123D0348F5185F61ABFB1BF18D6AEA454F");
- const size_t out_len = 18;
- std::vector<uint8_t> out_buf(out_len);
+ message[0] ^= 1;
+ TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
+ TEST_FFI_OK(botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
- REQUIRE_THAT(botan_kdf("KDF2(SHA-1)", out_buf.data(), out_len,
- secret.data(), secret.size(), salt.data(), salt.size()),
- Equals(0));
+ TEST_FFI_OK(botan_pk_op_verify_destroy, (verifier));
+ }
- CHECK_THAT(hex_encode(out_buf), Equals("3A5DC9AA1C872B4744515AC2702D6396FC2A"));
- }
+ TEST_FFI_OK(botan_pubkey_destroy, (pub));
+ TEST_FFI_OK(botan_privkey_destroy, (priv));
+ }
-TEST_CASE("FFI bcrypt", "[ffi]")
- {
- botan_rng_t rng;
- botan_rng_init(&rng, "system");
+ return result;
+ }
- std::vector<uint8_t> outbuf(62);
- size_t ol = outbuf.size();
+ Test::Result ffi_test_ecdh(botan_rng_t rng)
+ {
+ Test::Result result("FFI");
- CHECK_THAT(botan_bcrypt_generate(outbuf.data(), &ol, "password", rng, 3, 0), Equals(0));
- botan_rng_destroy(rng);
+ botan_privkey_t priv1;
+ REQUIRE_FFI_OK(botan_privkey_create_ecdh, (&priv1, rng, "secp256r1"));
- REQUIRE(botan_bcrypt_is_valid("wrong", reinterpret_cast<const char*>(outbuf.data())) < 0);
- CHECK_THAT(botan_bcrypt_is_valid("password", reinterpret_cast<const char*>(outbuf.data())), Equals(0));
- }
-
-TEST_CASE("FFI RSA", "[ffi]")
- {
- botan_rng_t rng;
- botan_rng_init(&rng, "system");
+ botan_privkey_t priv2;
+ REQUIRE_FFI_OK(botan_privkey_create_ecdh, (&priv2, rng, "secp256r1"));
- botan_privkey_t priv;
- REQUIRE_THAT(botan_privkey_create_rsa(&priv, rng, 1024), Equals(0));
+ botan_pubkey_t pub1;
+ REQUIRE_FFI_OK(botan_privkey_export_pubkey, (&pub1, priv1));
- botan_pubkey_t pub;
- CHECK_THAT(botan_privkey_export_pubkey(&pub, priv), Equals(0));
+ botan_pubkey_t pub2;
+ REQUIRE_FFI_OK(botan_privkey_export_pubkey, (&pub2, priv2));
- std::string name(64, '\x00');
- size_t name_len = name.size();
- CHECK_THAT(botan_pubkey_algo_name(pub, &name[0], &name_len), Equals(0));
- name.resize(name_len - 1);
+ botan_pk_op_ka_t ka1;
+ REQUIRE_FFI_OK(botan_pk_op_key_agreement_create, (&ka1, priv1, "KDF2(SHA-256)", 0));
+ botan_pk_op_ka_t ka2;
+ REQUIRE_FFI_OK(botan_pk_op_key_agreement_create, (&ka2, priv2, "KDF2(SHA-256)", 0));
- CHECK_THAT(name, Equals("RSA"));
+ std::vector<uint8_t> pubkey1(256); // length problem again
+ size_t pubkey1_len = pubkey1.size();
+ REQUIRE_FFI_OK(botan_pk_op_key_agreement_export_public, (priv1, pubkey1.data(), &pubkey1_len));
+ pubkey1.resize(pubkey1_len);
- botan_pk_op_encrypt_t encrypt;
- CHECK_THAT(botan_pk_op_encrypt_create(&encrypt, pub, "OAEP(SHA-256)", 0), Equals(0));
+ std::vector<uint8_t> pubkey2(256); // length problem again
+ size_t pubkey2_len = pubkey2.size();
+ REQUIRE_FFI_OK(botan_pk_op_key_agreement_export_public, (priv2, pubkey2.data(), &pubkey2_len));
+ pubkey2.resize(pubkey2_len);
- std::vector<uint8_t> plaintext(32);
- CHECK_THAT(botan_rng_get(rng, plaintext.data(), plaintext.size()), Equals(0));
+ std::vector<uint8_t> salt(32);
+ TEST_FFI_OK(botan_rng_get, (rng, salt.data(), salt.size()));
- std::vector<uint8_t> ciphertext(256); // TODO: no way to know this size from API
- size_t ctext_len = ciphertext.size();
- CHECK_THAT(botan_pk_op_encrypt(encrypt, rng, ciphertext.data(), &ctext_len,
- plaintext.data(), plaintext.size()),
- Equals(0));
- ciphertext.resize(ctext_len);
+ const size_t shared_key_len = 64;
- int retEncryptDestroy = botan_pk_op_encrypt_destroy(encrypt);
- CHECK_THAT(retEncryptDestroy, Equals(0));
- //CHECK(botan_pk_op_encrypt_destroy(encrypt) < 0);
+ std::vector<uint8_t> key1(shared_key_len);
+ size_t key1_len = key1.size();
+ TEST_FFI_OK(botan_pk_op_key_agreement, (ka1, key1.data(), &key1_len,
+ pubkey2.data(), pubkey2.size(),
+ salt.data(), salt.size()));
- botan_pk_op_decrypt_t decrypt;
- CHECK_THAT(botan_pk_op_decrypt_create(&decrypt, priv, "OAEP(SHA-256)", 0), Equals(0));
+ std::vector<uint8_t> key2(shared_key_len);
+ size_t key2_len = key2.size();
+ TEST_FFI_OK(botan_pk_op_key_agreement, (ka2, key2.data(), &key2_len,
+ pubkey1.data(), pubkey1.size(),
+ salt.data(), salt.size()));
- std::vector<uint8_t> decrypted(256); // TODO as with above
- size_t decrypted_len = decrypted.size();
- CHECK_THAT(botan_pk_op_decrypt(decrypt, decrypted.data(), &decrypted_len,
- ciphertext.data(), ciphertext.size()),
- Equals(0));
- decrypted.resize(decrypted_len);
+ result.test_eq("shared ECDH key", key1, key2);
- CHECK_THAT(hex_encode(plaintext), Equals(hex_encode(decrypted)));
+ return result;
+ }
+ };
- int retDecryptDestroy = botan_pk_op_decrypt_destroy(decrypt);
- CHECK_THAT(retDecryptDestroy, Equals(0));
- //CHECK(botan_pk_op_decrypt_destroy(decrypt) < 0);
+BOTAN_REGISTER_TEST("ffi", FFI_Unit_Tests);
- botan_rng_destroy(rng);
- }
+#endif
-TEST_CASE("FFI ECDSA", "[ffi]")
- {
- botan_rng_t rng;
- botan_rng_init(&rng, "system");
-
- botan_privkey_t priv;
- int rc = botan_privkey_create_ecdsa(&priv, rng, "secp384r1");
-
- botan_pubkey_t pub;
- CHECK_THAT(botan_privkey_export_pubkey(&pub, priv), Equals(0));
-
- std::string name(64, '\x00');
- size_t name_len = name.size();
- CHECK_THAT(botan_pubkey_algo_name(pub, &name[0], &name_len), Equals(0));
- name.resize(name_len - 1);
-
- CHECK_THAT(name, Equals("ECDSA"));
-
- botan_pk_op_sign_t signer;
- CHECK_THAT(botan_pk_op_sign_create(&signer, priv, "EMSA1(SHA-384)", 0), Equals(0));
-
- std::vector<uint8_t> message(1280);
- CHECK_THAT(botan_rng_get(rng, message.data(), message.size()), Equals(0));
-
- // TODO: break input into multiple calls to update
- int retSignUpdate = botan_pk_op_sign_update(signer, message.data(), message.size());
- CHECK_THAT(retSignUpdate, Equals(0));
-
- std::vector<uint8_t> signature(96); // TODO: no way to derive this from API
- size_t sig_len = signature.size();
-
- int retSignFinish = botan_pk_op_sign_finish(signer, rng, signature.data(), &sig_len);
- CHECK_THAT(retSignFinish, Equals(0));
-
- signature.resize(sig_len);
-
- int retSignDestroy = botan_pk_op_sign_destroy(signer);
- CHECK_THAT(retSignDestroy, Equals(0));
-
- botan_pk_op_verify_t verifier;
- int retVerifyCreate = botan_pk_op_verify_create(&verifier, pub, "EMSA1(SHA-384)", 0);
- CHECK_THAT(retVerifyCreate, Equals(0));
-
- {
- int retVerifyUpdate = botan_pk_op_verify_update(verifier, message.data(), message.size());
- CHECK_THAT(retVerifyUpdate, Equals(0));
- int retVerifyFinish = botan_pk_op_verify_finish(verifier, signature.data(), signature.size());
- CHECK_THAT(retVerifyFinish, Equals(0));
- }
-
- // TODO: randomize this
- signature[0] ^= 1;
- {
- int retVerifyUpdate = botan_pk_op_verify_update(verifier, message.data(), message.size());
- CHECK_THAT(retVerifyUpdate, Equals(0));
- int retVerifyFinish = botan_pk_op_verify_finish(verifier, signature.data(), signature.size());
- CHECK_THAT(retVerifyFinish, Equals(1));
- }
-
- message[0] ^= 1;
- {
- int retVerifyUpdate = botan_pk_op_verify_update(verifier, message.data(), message.size());
- CHECK_THAT(retVerifyUpdate, Equals(0));
- int retVerifyFinish = botan_pk_op_verify_finish(verifier, signature.data(), signature.size());
- CHECK_THAT(retVerifyFinish, Equals(1));
- }
-
- signature[0] ^= 1;
- {
- int retVerifyUpdate = botan_pk_op_verify_update(verifier, message.data(), message.size());
- CHECK_THAT(retVerifyUpdate, Equals(0));
- int retVerifyFinish = botan_pk_op_verify_finish(verifier, signature.data(), signature.size());
- CHECK_THAT(retVerifyFinish, Equals(1));
- }
-
- message[0] ^= 1;
- {
- int retVerifyUpdate = botan_pk_op_verify_update(verifier, message.data(), message.size());
- CHECK_THAT(retVerifyUpdate, Equals(0));
- int retVerifyFinish = botan_pk_op_verify_finish(verifier, signature.data(), signature.size());
- CHECK_THAT(retVerifyFinish, Equals(0));
- }
-
- int retVerifyDestroy = botan_pk_op_verify_destroy(verifier);
- CHECK_THAT(retVerifyDestroy, Equals(0));
-
- botan_rng_destroy(rng);
- }
+}
-TEST_CASE("FFI ECDH", "[ffi]")
- {
- botan_rng_t rng;
- botan_rng_init(&rng, "system");
-
- botan_privkey_t priv1;
- REQUIRE_THAT(botan_privkey_create_ecdh(&priv1, rng, "secp256r1"), Equals(0));
- botan_privkey_t priv2;
- REQUIRE_THAT(botan_privkey_create_ecdh(&priv2, rng, "secp256r1"), Equals(0));
-
- botan_pubkey_t pub1;
- CHECK_THAT(botan_privkey_export_pubkey(&pub1, priv1), Equals(0));
- botan_pubkey_t pub2;
- CHECK_THAT(botan_privkey_export_pubkey(&pub2, priv2), Equals(0));
-
- botan_pk_op_ka_t ka1;
- REQUIRE_THAT(botan_pk_op_key_agreement_create(&ka1, priv1, "KDF2(SHA-256)", 0), Equals(0));
- botan_pk_op_ka_t ka2;
- REQUIRE_THAT(botan_pk_op_key_agreement_create(&ka2, priv2, "KDF2(SHA-256)", 0), Equals(0));
-
- std::vector<uint8_t> pubkey1(256); // length problem again
- size_t pubkey1_len = pubkey1.size();
- CHECK_THAT(botan_pk_op_key_agreement_export_public(priv1, pubkey1.data(), &pubkey1_len), Equals(0));
- pubkey1.resize(pubkey1_len);
-
- std::vector<uint8_t> pubkey2(256); // length problem again
- size_t pubkey2_len = pubkey2.size();
- CHECK_THAT(botan_pk_op_key_agreement_export_public(priv2, pubkey2.data(), &pubkey2_len), Equals(0));
- pubkey2.resize(pubkey2_len);
-
- std::vector<uint8_t> salt(32);
- REQUIRE_THAT(botan_rng_get(rng, salt.data(), salt.size()), Equals(0));
-
- const size_t shared_key_len = 64;
-
- std::vector<uint8_t> key1(shared_key_len);
- size_t key1_len = key1.size();
- CHECK_THAT(botan_pk_op_key_agreement(ka1, key1.data(), &key1_len,
- pubkey2.data(), pubkey2.size(),
- salt.data(), salt.size()),
- Equals(0));
-
- std::vector<uint8_t> key2(shared_key_len);
- size_t key2_len = key2.size();
- CHECK_THAT(botan_pk_op_key_agreement(ka2, key2.data(), &key2_len,
- pubkey1.data(), pubkey1.size(),
- salt.data(), salt.size()),
- Equals(0));
-
- CHECK_THAT(hex_encode(key1), Equals(hex_encode(key2)));
-
- botan_rng_destroy(rng);
- }
+}
-#endif
diff --git a/src/tests/test_fuzzer.cpp b/src/tests/test_fuzzer.cpp
index f2343dc1f..91d301826 100644
--- a/src/tests/test_fuzzer.cpp
+++ b/src/tests/test_fuzzer.cpp
@@ -6,74 +6,82 @@
#include "tests.h"
#include <chrono>
-#include <iostream>
-
-#include <botan/internal/filesystem.h>
#if defined(BOTAN_HAS_X509_CERTIFICATES)
-#include <botan/x509cert.h>
-#include <botan/x509_crl.h>
-#include <botan/base64.h>
+ #include <botan/x509cert.h>
+ #include <botan/x509_crl.h>
+ #include <botan/base64.h>
+ #include <botan/internal/filesystem.h>
#endif
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-const std::string TEST_DATA_DIR_FUZZ_X509 = TEST_DATA_DIR "/fuzz/x509";
-
-#if defined(BOTAN_HAS_X509_CERTIFICATES)
-size_t test_x509_fuzz()
+class Fuzzer_Input_Tests : public Test
{
- size_t fails = 0;
- size_t tests = 0;
+ public:
+ std::vector<Test::Result> run() override
+ {
+ std::vector<Test::Result> results;
+#if defined(BOTAN_HAS_X509_CERTIFICATES)
+ results.push_back(test_x509_fuzz());
+#endif
+ return results;
+ }
+
+ private:
- try
- {
- for(auto vec_file: get_files_recursive(TEST_DATA_DIR_FUZZ_X509))
+#if defined(BOTAN_HAS_X509_CERTIFICATES)
+ Test::Result test_x509_fuzz()
{
- ++tests;
+ Test::Result result("X.509 fuzzing");
+
+ std::vector<std::string> files;
- auto start = std::chrono::steady_clock::now();
try
{
- // TODO: check for memory consumption?
- X509_Certificate cert(vec_file);
+ files = Botan::get_files_recursive(Test::data_dir("fuzz/x509"));
}
- catch(std::exception& e)
+ catch(Botan::No_Filesystem_Access)
{
- //std::cout << e.what() << "\n";
+ result.note_missing("Filesystem access");
+ return result;
}
- auto end = std::chrono::steady_clock::now();
-
- uint64_t duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
- if(duration > 100)
+ for(auto vec_file: files)
{
- std::cout << "Fuzzer test " << vec_file << " took " << duration << " ms" << std::endl;
+ auto start = std::chrono::steady_clock::now();
+
+ try
+ {
+ // TODO: check for memory consumption?
+ Botan::X509_Certificate cert(vec_file);
+ }
+ catch(std::exception& e)
+ {
+ }
+
+ result.test_success();
+
+ auto end = std::chrono::steady_clock::now();
+
+ uint64_t duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
+
+ if(duration > 100)
+ {
+ result.test_note("Fuzzer test " + vec_file + " took " + std::to_string(duration) + " ms");
+ }
}
- }
- test_report("Fuzzer checks", tests, fails);
- }
- catch(No_Filesystem_Access)
- {
- std::cout << "Warning: No filesystem access available to read test files in '"
- << TEST_DATA_DIR_FUZZ_X509 << "'" << std::endl;
- return 0;
- }
-
- return fails;
- }
+ return result;
+ }
#endif
+ };
+
+BOTAN_REGISTER_TEST("fuzzer", Fuzzer_Input_Tests);
+
}
-size_t test_fuzzer()
- {
- size_t fails = 0;
-#if defined(BOTAN_HAS_X509_CERTIFICATES)
- fails += test_x509_fuzz();
-#endif
- return fails;
- }
+}
diff --git a/src/tests/test_gf2m.cpp b/src/tests/test_gf2m.cpp
index 7557672a6..11a15c3fe 100644
--- a/src/tests/test_gf2m.cpp
+++ b/src/tests/test_gf2m.cpp
@@ -7,40 +7,68 @@
#include "tests.h"
#if defined(BOTAN_HAS_MCELIECE)
+ #include <botan/gf2m_small_m.h>
+#endif
-#include <botan/gf2m_small_m.h>
-
-BOTAN_TEST_CASE(gf2m, "GF(2^m)", {
+namespace Botan_Tests {
- using namespace Botan;
+namespace {
- for(size_t degree = 2; degree <= 16; ++degree)
- {
- GF2m_Field field(degree);
+#if defined(BOTAN_HAS_MCELIECE)
- for(size_t i = 0; i <= field.gf_ord(); ++i)
+class GF2m_Tests : public Test
+ {
+ public:
+ std::vector<Test::Result> run() override
{
- gf2m a = i;
+ std::vector<Test::Result> results;
+
+ results.push_back(test_gf_overflow());
- BOTAN_TEST(field.gf_square(a), field.gf_mul(a, a), "Square and multiply");
+ return results;
+ }
+
+ private:
+ Test::Result test_gf_overflow()
+ {
+ Test::Result result("GF2m");
- /*
- * This sequence is from the start of gf2m_decomp_rootfind_state::calc_Fxj_j_neq_0
- */
+ for(size_t degree = 2; degree <= 16; ++degree)
{
- const gf2m jl_gray = field.gf_l_from_n(a);
- gf2m xl_j_tt_5 = field.gf_square_rr(jl_gray);
- const gf2m xl_gray_tt_3 = field.gf_mul_rrr(xl_j_tt_5, jl_gray);
- xl_j_tt_5 = field.gf_mul_rrr(xl_j_tt_5, xl_gray_tt_3);
- gf2m s = field.gf_mul_nrr(xl_gray_tt_3, field.gf_ord());
- BOTAN_CONFIRM(s <= field.gf_ord(), "Less than order");
+ Botan::GF2m_Field field(degree);
+
+ using Botan::gf2m;
+
+ for(size_t i = 0; i <= field.gf_ord(); ++i)
+ {
+ gf2m a = i;
+
+ result.test_eq("square vs multiply",
+ static_cast<size_t>(field.gf_square(a)),
+ static_cast<size_t>(field.gf_mul(a, a)));
+
+ /*
+ * This sequence is from the start of gf2m_decomp_rootfind_state::calc_Fxj_j_neq_0
+ */
+ {
+ const gf2m jl_gray = field.gf_l_from_n(a);
+ gf2m xl_j_tt_5 = field.gf_square_rr(jl_gray);
+ const gf2m xl_gray_tt_3 = field.gf_mul_rrr(xl_j_tt_5, jl_gray);
+ xl_j_tt_5 = field.gf_mul_rrr(xl_j_tt_5, xl_gray_tt_3);
+ gf2m s = field.gf_mul_nrr(xl_gray_tt_3, field.gf_ord());
+
+ result.test_gte("Value less than order", field.gf_ord(), s);
+ }
+ }
}
+ return result;
}
- }
- });
+ };
-#else
-
-SKIP_TEST(gf2m);
+BOTAN_REGISTER_TEST("gf2m", GF2m_Tests);
#endif
+
+}
+
+}
diff --git a/src/tests/test_gost_3410.cpp b/src/tests/test_gost_3410.cpp
index 2f59f7736..a80cd666c 100644
--- a/src/tests/test_gost_3410.cpp
+++ b/src/tests/test_gost_3410.cpp
@@ -7,60 +7,61 @@
#include "tests.h"
#if defined(BOTAN_HAS_GOST_34_10_2001)
+ #include <botan/gost_3410.h>
+ #include <botan/oids.h>
+ #include "test_pubkey.h"
+#endif
-#include "test_pubkey.h"
-
-#include <botan/pubkey.h>
-#include <botan/gost_3410.h>
-#include <botan/oids.h>
-#include <botan/hex.h>
-#include <iostream>
-#include <fstream>
-
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-size_t gost_verify(const std::string& group_id,
- const std::string& x,
- const std::string& hash,
- const std::string& msg,
- const std::string& signature)
- {
- EC_Group group(OIDS::lookup(group_id));
- PointGFp public_point = OS2ECP(hex_decode(x), group.get_curve());
-
- GOST_3410_PublicKey gost(group, public_point);
-
- const std::string padding = "EMSA1(" + hash + ")";
-
- PK_Verifier v(gost, padding);
-
- if(!v.verify_message(hex_decode(msg), hex_decode(signature)))
- return 1;
-
- return 0;
- }
-
-}
+#if defined(BOTAN_HAS_GOST_34_10_2001)
-size_t test_gost_3410()
+class GOST_3410_2001_Verification_Tests : public PK_Signature_Verification_Test
{
- size_t fails = 0;
-
- std::ifstream ecdsa_sig(TEST_DATA_DIR_PK "/gost_3410.vec");
+ public:
+ GOST_3410_2001_Verification_Tests() : PK_Signature_Verification_Test(
+ "GOST 34.10-2001",
+ Test::data_file("pubkey/gost_3410.vec"),
+ {"Group", "Pubkey", "Hash", "Msg", "Signature"})
+ {}
+
+ std::unique_ptr<Botan::Public_Key> load_public_key(const VarMap& vars) override
+ {
+ const std::string group_id = get_req_str(vars, "Group");
+ Botan::EC_Group group(Botan::OIDS::lookup(group_id));
+ const Botan::PointGFp public_point = Botan::OS2ECP(get_req_bin(vars, "Pubkey"), group.get_curve());
+
+ std::unique_ptr<Botan::Public_Key> key(new Botan::GOST_3410_PublicKey(group, public_point));
+ return key;
+ }
+
+ std::string default_padding(const VarMap& vars) const override
+ {
+ return "EMSA1(" + get_req_str(vars, "Hash") + ")";
+ }
+ };
+
+class GOST_3410_2001_Keygen_Tests : public PK_Key_Generation_Test
+ {
+ public:
+ std::vector<std::string> keygen_params() const override { return { "gost_256A", "secp256r1" }; }
- fails += run_tests_bb(ecdsa_sig, "GOST-34.10 Signature", "Signature", true,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return gost_verify(m["Group"], m["Pubkey"], m["Hash"], m["Msg"], m["Signature"]);
- });
+ std::unique_ptr<Botan::Private_Key> make_key(Botan::RandomNumberGenerator& rng,
+ const std::string& param) const override
+ {
+ Botan::EC_Group group(param);
+ std::unique_ptr<Botan::Private_Key> key(new Botan::GOST_3410_PrivateKey(rng, group));
+ return key;
+ }
+ };
- return fails;
- }
+BOTAN_REGISTER_TEST("gost_3410_verify", GOST_3410_2001_Verification_Tests);
+BOTAN_REGISTER_TEST("gost_3410_keygen", GOST_3410_2001_Keygen_Tests);
-#else
+#endif
-SKIP_TEST(gost_3410);
+}
-#endif // BOTAN_HAS_GOST_34_10_2001
+}
diff --git a/src/tests/test_hash.cpp b/src/tests/test_hash.cpp
index 42ffcc11a..6c0dfb1c6 100644
--- a/src/tests/test_hash.cpp
+++ b/src/tests/test_hash.cpp
@@ -7,98 +7,70 @@
#include "tests.h"
#include <botan/hash.h>
-#include <botan/hex.h>
-#include <iostream>
-#include <fstream>
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-size_t hash_test(const std::string& algo,
- const std::string& in_hex,
- const std::string& out_hex)
+class Hash_Function_Tests : public Text_Based_Test
{
- size_t fails = 0;
+ public:
+ Hash_Function_Tests() : Text_Based_Test(Test::data_dir("hash"), {"In", "Out"}) {}
- const std::vector<std::string> providers = HashFunction::providers(algo);
-
- if(providers.empty())
- {
- std::cout << "Unknown hash '" << algo << "'" << std::endl;
- return 0;
- }
-
- for(auto provider: providers)
- {
- std::unique_ptr<HashFunction> hash(HashFunction::create(algo, provider));
-
- if(!hash)
+ Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
{
- std::cout << "Unable to get " << algo << " from " << provider << std::endl;
- ++fails;
- continue;
- }
+ const std::vector<uint8_t> input = get_req_bin(vars, "In");
+ const std::vector<uint8_t> expected = get_req_bin(vars, "Out");
- const std::vector<byte> in = hex_decode(in_hex);
+ Test::Result result(algo);
- hash->update(in);
+ const std::vector<std::string> providers = Botan::HashFunction::providers(algo);
- auto h = hash->final();
+ if(providers.empty())
+ {
+ result.note_missing("block cipher " + algo);
+ return result;
+ }
- if(h != hex_decode_locked(out_hex))
- {
- std::cout << algo << " " << provider << " got " << hex_encode(h) << " != " << out_hex << std::endl;
- ++fails;
- }
+ for(auto&& provider: providers)
+ {
+ std::unique_ptr<Botan::HashFunction> hash(Botan::HashFunction::create(algo, provider));
- // Test to make sure clear() resets what we need it to
- hash->update("some discarded input");
- hash->clear();
+ if(!hash)
+ {
+ result.note_missing(algo + " from " + provider);
+ continue;
+ }
- hash->update(in);
+ result.test_eq(provider.c_str(), hash->name(), algo);
- h = hash->final();
+ hash->update(input);
- if(h != hex_decode_locked(out_hex))
- {
- std::cout << algo << " " << provider << " got " << hex_encode(h) << " != " << out_hex
- << " (with discarded input)" << std::endl;
- ++fails;
- }
+ result.test_eq(provider, "hashing", hash->final(), expected);
- if(in.size() > 1)
- {
- hash->update(in[0]);
- hash->update(&in[1], in.size() - 1);
- h = hash->final();
+ // Test to make sure clear() resets what we need it to
+ hash->update("some discarded input");
+ hash->clear();
+ hash->update(nullptr, 0); // this should be effectively ignored
+ hash->update(input);
- if(h != hex_decode_locked(out_hex))
- {
- std::cout << algo << " " << provider << " got " << hex_encode(h) << " != " << out_hex
- << " (with offset input)" << std::endl;
- ++fails;
+ result.test_eq(provider, "hashing after clear", hash->final(), expected);
+
+ if(input.size() > 1)
+ {
+ hash->update(input[0]);
+ hash->update(&input[1], input.size() - 1);
+ result.test_eq(provider, "hashing split", hash->final(), expected);
+ }
}
+
+ return result;
}
- }
- return fails;
- }
+ };
+
+BOTAN_REGISTER_TEST("hash", Hash_Function_Tests);
}
-size_t test_hash()
- {
- auto test = [](const std::string& input)
- {
- std::ifstream vec(input);
-
- return run_tests_bb(vec, "Hash", "Out", true,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return hash_test(m["Hash"], m["In"], m["Out"]);
- });
- };
-
- return run_tests_in_dir(TEST_DATA_DIR "/hash", test);
- }
+}
diff --git a/src/tests/test_kdf.cpp b/src/tests/test_kdf.cpp
index 30541d459..d9a172bad 100644
--- a/src/tests/test_kdf.cpp
+++ b/src/tests/test_kdf.cpp
@@ -7,38 +7,49 @@
#include "tests.h"
#if defined(BOTAN_HAS_KDF_BASE)
+ #include <botan/kdf.h>
+#endif
-#include <botan/kdf.h>
-#include <botan/hex.h>
-#include <iostream>
-#include <fstream>
+namespace Botan_Tests {
-using namespace Botan;
+namespace {
-size_t test_kdf()
+#if defined(BOTAN_HAS_KDF_BASE)
+class KDF_KAT_Tests : public Text_Based_Test
{
- auto test = [](const std::string& input)
- {
- return run_tests(input, "KDF", "Output", true,
- [](std::map<std::string, std::string> vec)
- {
- std::unique_ptr<KDF> kdf(get_kdf(vec["KDF"]));
+ public:
+ KDF_KAT_Tests() : Text_Based_Test(Test::data_dir("kdf"),
+ {"OutputLen", "Salt", "Secret", "Output"},
+ {"IKM","XTS"})
+ {}
+
+ Test::Result run_one_test(const std::string& kdf_name, const VarMap& vars)
+ {
+ Test::Result result(kdf_name);
+ std::unique_ptr<Botan::KDF> kdf(Botan::get_kdf(kdf_name));
+
+ if(!kdf)
+ {
+ result.note_missing(kdf_name);
+ return result;
+ }
+
+ const size_t outlen = get_req_sz(vars, "OutputLen");
+ const std::vector<uint8_t> salt = get_opt_bin(vars, "Salt");
+ const std::vector<uint8_t> secret = get_req_bin(vars, "Secret");
+ const std::vector<uint8_t> expected = get_req_bin(vars, "Output");
- const size_t outlen = to_u32bit(vec["OutputLen"]);
- const auto salt = hex_decode(vec["Salt"]);
- const auto secret = hex_decode(vec["Secret"]);
+ result.test_eq("derived key", kdf->derive_key(outlen, secret, salt), expected);
- const auto key = kdf->derive_key(outlen, secret, salt);
+ return result;
+ }
- return hex_encode(key);
- });
- };
+ };
- return run_tests_in_dir(TEST_DATA_DIR "/kdf", test);
- }
+BOTAN_REGISTER_TEST("kdf", KDF_KAT_Tests);
-#else
+#endif
-SKIP_TEST(kdf);
+}
-#endif // BOTAN_HAS_KDF_BASE
+}
diff --git a/src/tests/test_keywrap.cpp b/src/tests/test_keywrap.cpp
index 16a165668..01ada5509 100644
--- a/src/tests/test_keywrap.cpp
+++ b/src/tests/test_keywrap.cpp
@@ -12,82 +12,48 @@
#include <botan/rfc3394.h>
#endif
-#include <iostream>
-
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-size_t keywrap_test(const char* key_str,
- const char* expected_str,
- const char* kek_str)
- {
- size_t fail = 0;
-
#if defined(BOTAN_HAS_RFC3394_KEYWRAP)
- try
- {
- SymmetricKey key(key_str);
- SymmetricKey expected(expected_str);
- SymmetricKey kek(kek_str);
-
- secure_vector<byte> enc = rfc3394_keywrap(key.bits_of(), kek);
+class RFC3394_Keywrap_Tests : public Text_Based_Test
+ {
+ public:
+ RFC3394_Keywrap_Tests() : Text_Based_Test(Test::data_file("rfc3394.vec"),
+ {"Key", "KEK", "Output"})
+ {}
- if(enc != expected.bits_of())
+ Test::Result run_one_test(const std::string&, const VarMap& vars) override
{
- std::cout << "NIST key wrap encryption failure: "
- << hex_encode(enc) << " != " << hex_encode(expected.bits_of()) << std::endl;
- fail++;
+ Test::Result result("RFC3394 keywrap");
+
+ try
+ {
+ const std::vector<byte> expected = get_req_bin(vars, "Output");
+ const std::vector<byte> key = get_req_bin(vars, "Key");
+ const std::vector<byte> kek = get_req_bin(vars, "KEK");
+
+ const Botan::SymmetricKey kek_sym(kek);
+ const Botan::secure_vector<uint8_t> key_l(key.begin(), key.end());
+ const Botan::secure_vector<uint8_t> exp_l(expected.begin(), expected.end());
+
+ result.test_eq("encryption", Botan::rfc3394_keywrap(key_l, kek_sym), expected);
+ result.test_eq("decryption", Botan::rfc3394_keyunwrap(exp_l, kek_sym), key);
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure("", e.what());
+ }
+
+ return result;
}
- secure_vector<byte> dec = rfc3394_keyunwrap(expected.bits_of(), kek);
+ };
- if(dec != key.bits_of())
- {
- std::cout << "NIST key wrap decryption failure: "
- << hex_encode(dec) << " != " << hex_encode(key.bits_of()) << std::endl;
- fail++;
- }
- }
- catch(std::exception& e)
- {
- std::cout << e.what() << std::endl;
- fail++;
- }
+BOTAN_REGISTER_TEST("rfc3394", RFC3394_Keywrap_Tests);
#endif
- return fail;
- }
-
}
-size_t test_keywrap()
- {
- size_t fails = 0;
-
- fails += keywrap_test("00112233445566778899AABBCCDDEEFF",
- "1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5",
- "000102030405060708090A0B0C0D0E0F");
-
- fails += keywrap_test("00112233445566778899AABBCCDDEEFF",
- "96778B25AE6CA435F92B5B97C050AED2468AB8A17AD84E5D",
- "000102030405060708090A0B0C0D0E0F1011121314151617");
-
- fails += keywrap_test("00112233445566778899AABBCCDDEEFF",
- "64E8C3F9CE0F5BA263E9777905818A2A93C8191E7D6E8AE7",
- "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
-
- fails += keywrap_test("00112233445566778899AABBCCDDEEFF0001020304050607",
- "031D33264E15D33268F24EC260743EDCE1C6C7DDEE725A936BA814915C6762D2",
- "000102030405060708090A0B0C0D0E0F1011121314151617");
-
- fails += keywrap_test("00112233445566778899AABBCCDDEEFF0001020304050607",
- "A8F9BC1612C68B3FF6E6F4FBE30E71E4769C8B80A32CB8958CD5D17D6B254DA1",
- "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
-
- fails += keywrap_test("00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F",
- "28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21",
- "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
-
- return fails;
- }
+}
diff --git a/src/tests/test_mac.cpp b/src/tests/test_mac.cpp
index e161e5921..a5b2b49ca 100644
--- a/src/tests/test_mac.cpp
+++ b/src/tests/test_mac.cpp
@@ -7,96 +7,74 @@
#include "tests.h"
#if defined(BOTAN_HAS_MAC)
+ #include <botan/mac.h>
+#endif
-#include <botan/mac.h>
-#include <botan/hex.h>
-#include <iostream>
-#include <fstream>
-
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-size_t mac_test(const std::string& algo,
- const std::string& key_hex,
- const std::string& in_hex,
- const std::string& out_hex)
- {
- const std::vector<std::string> providers = MessageAuthenticationCode::providers(algo);
- size_t fails = 0;
-
- if(providers.empty())
- {
- std::cout << "Unknown algo " << algo << std::endl;
- return 0;
- }
+#if defined(BOTAN_HAS_MAC)
- for(auto provider: providers)
- {
- std::unique_ptr<MessageAuthenticationCode> mac(MessageAuthenticationCode::create(algo, provider));
+class Message_Auth_Tests : public Text_Based_Test
+ {
+ public:
+ Message_Auth_Tests() :
+ Text_Based_Test(Test::data_dir("mac"), {"Key", "In", "Out"}) {}
- if(!mac)
+ Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
{
- std::cout << "Unable to get " << algo << " from " << provider << std::endl;
- ++fails;
- continue;
- }
+ const std::vector<uint8_t> key = get_req_bin(vars, "Key");
+ const std::vector<uint8_t> input = get_req_bin(vars, "In");
+ const std::vector<uint8_t> expected = get_req_bin(vars, "Out");
- const std::vector<byte> in = hex_decode(in_hex);
- const std::vector<byte> exp = hex_decode(out_hex);
+ Test::Result result(algo);
- mac->set_key(hex_decode(key_hex));
+ const std::vector<std::string> providers = Botan::MessageAuthenticationCode::providers(algo);
- mac->update(in);
+ if(providers.empty())
+ {
+ result.note_missing("block cipher " + algo);
+ return result;
+ }
- const std::vector<byte> out = unlock(mac->final());
+ for(auto&& provider: providers)
+ {
+ std::unique_ptr<Botan::MessageAuthenticationCode> mac(Botan::MessageAuthenticationCode::create(algo, provider));
- if(out != exp)
- {
- std::cout << algo << " " << provider << " got " << hex_encode(out) << " != " << hex_encode(exp) << std::endl;
- ++fails;
- }
+ if(!mac)
+ {
+ result.note_missing(algo + " from " + provider);
+ continue;
+ }
- if(in.size() > 2)
- {
- mac->set_key(hex_decode(key_hex));
- mac->update(in[0]);
- mac->update(&in[1], in.size() - 2);
- mac->update(in[in.size()-1]);
+ result.test_eq(provider.c_str(), mac->name(), algo);
- const std::vector<byte> out2 = unlock(mac->final());
+ mac->set_key(key);
- if(out2 != exp)
- {
- std::cout << algo << " " << provider << " got " << hex_encode(out2) << " != " << hex_encode(exp) << std::endl;
- ++fails;
- }
- }
- }
+ mac->update(input);
- return fails;
- }
+ result.test_eq(provider, "correct mac", mac->final(), expected);
-}
+ if(input.size() > 2)
+ {
+ mac->set_key(key); // Poly1305 requires the re-key
+ mac->update(input[0]);
+ mac->update(&input[1], input.size() - 2);
+ mac->update(input[input.size()-1]);
-size_t test_mac()
- {
- auto test = [](const std::string& input)
- {
- std::ifstream vec(input);
+ result.test_eq(provider, "split mac", mac->final(), expected);
+ }
+ }
- return run_tests_bb(vec, "Mac", "Out", true,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return mac_test(m["Mac"], m["Key"], m["In"], m["Out"]);
- });
- };
+ return result;
+ }
+ };
- return run_tests_in_dir(TEST_DATA_DIR "/mac", test);
- }
+BOTAN_REGISTER_TEST("mac", Message_Auth_Tests);
-#else
+#endif
-SKIP_TEST(mac);
+}
-#endif // BOTAN_HAS_MAC
+}
diff --git a/src/tests/test_main.cpp b/src/tests/test_main.cpp
new file mode 100644
index 000000000..009073ae1
--- /dev/null
+++ b/src/tests/test_main.cpp
@@ -0,0 +1,244 @@
+/*
+* (C) 2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "tests.h"
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <set>
+#include <deque>
+#include <thread>
+#include <future>
+
+#include <botan/version.h>
+#include <botan/auto_rng.h>
+#include <botan/loadstor.h>
+
+#if defined(BOTAN_HAS_HMAC_DRBG)
+#include <botan/hmac_drbg.h>
+#endif
+
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+#include <botan/system_rng.h>
+#endif
+
+namespace {
+
+using Botan_Tests::Test;
+
+int help(std::ostream& out, char* argv0)
+ {
+ std::ostringstream err;
+
+ err << "Usage:\n"
+ << argv0 << " test1 test2 ...\n"
+ << "Available tests: ";
+
+ for(auto&& test : Test::registered_tests())
+ {
+ err << test << " ";
+ }
+ err << "\n";
+
+ out << err.str();
+ return 1;
+ }
+
+std::string report_out(const std::vector<Test::Result>& results,
+ size_t& tests_failed,
+ size_t& tests_ran)
+ {
+ std::ostringstream out;
+
+ std::map<std::string, Test::Result> combined;
+ for(auto&& result : results)
+ {
+ const std::string who = result.who();
+ auto i = combined.find(who);
+ if(i == combined.end())
+ {
+ combined[who] = Test::Result(who);
+ i = combined.find(who);
+ }
+
+ i->second.merge(result);
+ }
+
+ for(auto&& result : combined)
+ {
+ out << result.second.result_string();
+ tests_failed += result.second.tests_failed();
+ tests_ran += result.second.tests_run();
+ }
+
+ return out.str();
+ }
+
+size_t run_tests(const std::vector<std::string>& tests_to_run,
+ std::ostream& out,
+ size_t threads)
+ {
+ size_t tests_ran = 0, tests_failed = 0;
+
+ if(threads <= 1)
+ {
+ for(auto&& test_name : tests_to_run)
+ {
+ std::vector<Test::Result> results = Test::run_test(test_name, false);
+ out << report_out(results, tests_failed, tests_ran) << std::flush;
+ }
+ }
+ else
+ {
+
+ /*
+ We're not doing this in a particularly nice way, and variance in time is
+ high so commonly we'll 'run dry' by blocking on the first future. But
+ plain C++11 <thread> is missing a lot of tools we'd need (like
+ wait_for_any on a set of futures) and there is no point pulling in an
+ additional dependency just for this. In any case it helps somewhat
+ (50-100% speedup) and provides a proof of concept for parallel testing.
+ */
+
+ typedef std::future<std::vector<Test::Result>> FutureResults;
+ std::deque<FutureResults> fut_results;
+
+ for(auto&& test_name : tests_to_run)
+ {
+ fut_results.push_back(std::async(std::launch::async,
+ [test_name]() { return Test::run_test(test_name, false); }));
+
+ while(fut_results.size() > threads)
+ {
+ out << report_out(fut_results[0].get(), tests_failed, tests_ran) << std::flush;
+ fut_results.pop_front();
+ }
+ }
+
+ while(fut_results.size() > 0)
+ {
+ out << report_out(fut_results[0].get(), tests_failed, tests_ran) << std::flush;
+ fut_results.pop_front();
+ }
+ }
+
+ out << "Tests complete ran " << tests_ran << " tests ";
+
+ if(tests_failed > 0)
+ {
+ out << tests_failed << " tests failed";
+ }
+ else if(tests_ran > 0)
+ {
+ out << "all tests ok";
+ }
+
+ out << std::endl;
+
+ return tests_failed;
+ }
+
+std::unique_ptr<Botan::RandomNumberGenerator>
+setup_tests(std::ostream& out, size_t threads, size_t soak_level, bool log_success, std::string drbg_seed)
+ {
+ out << "Testing " << Botan::version_string() << "\n";
+ out << "Starting tests";
+
+ if(threads > 1)
+ out << " threads:" << threads;
+
+ out << " soak level:" << soak_level;
+
+ std::unique_ptr<Botan::RandomNumberGenerator> rng;
+
+#if defined(BOTAN_HAS_HMAC_DRBG)
+ if(drbg_seed == "")
+ {
+ const uint64_t ts = Test::timestamp();
+ std::vector<uint8_t> ts8(8);
+ Botan::store_be(ts, ts8.data());
+ drbg_seed = Botan::hex_encode(ts8);
+ }
+
+ out << " rng:HMAC_DRBG with seed '" << drbg_seed << "'";
+ rng.reset(new Botan::Serialized_RNG(new Botan::HMAC_DRBG("HMAC(SHA-384)")));
+ const std::vector<uint8_t> seed = Botan::hex_decode(drbg_seed);
+ rng->add_entropy(seed.data(), seed.size());
+
+#else
+
+ if(drbg_seed != "")
+ throw std::runtime_error("HMAC_DRBG disabled in build, cannot specify DRBG seed");
+
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ out << " rng:system";
+ rng.reset(new Botan::System_RNG);
+#else
+ // AutoSeeded_RNG always available
+ out << " rng:autoseeded";
+ rng.reset(new Botan::Serialized_RNG(new Botan::AutoSeeded_RNG));
+#endif
+
+#endif
+
+ out << std::endl;
+
+ Botan_Tests::Test::setup_tests(soak_level, log_success, rng.get());
+
+ return rng;
+ }
+
+}
+
+int main(int argc, char* argv[])
+ {
+ try
+ {
+ if(argc == 2 && (std::string(argv[1]) == "--help" || std::string(argv[1])== "help"))
+ {
+ return help(std::cout, argv[0]);
+ }
+
+ size_t threads = 0;//std::thread::hardware_concurrency();
+ size_t soak = 5;
+ const std::string drbg_seed = "";
+ bool log_success = false;
+
+ std::vector<std::string> req(argv + 1, argv + argc);
+
+ if(req.empty())
+ {
+ req = {"block", "stream", "hash", "mac", "modes", "aead", "kdf", "pbkdf", "hmac_drbg", "x931_rng", "util"};
+
+ std::set<std::string> all_others = Botan_Tests::Test::registered_tests();
+
+ for(auto f : req)
+ all_others.erase(f);
+
+ req.insert(req.end(), all_others.begin(), all_others.end());
+ }
+
+ std::unique_ptr<Botan::RandomNumberGenerator> rng =
+ setup_tests(std::cout, threads, soak, log_success, drbg_seed);
+
+ size_t failed = run_tests(req, std::cout, threads);
+
+ if(failed)
+ return 2;
+
+ return 0;
+ }
+ catch(std::exception& e)
+ {
+ std::cout << "Exception caused test abort: " << e.what() << std::endl;
+ return 3;
+ }
+ catch(...)
+ {
+ std::cout << "Unknown exception caused test abort" << std::endl;
+ return 3;
+ }
+ }
diff --git a/src/tests/test_mce.cpp b/src/tests/test_mce.cpp
deleted file mode 100644
index dbe5cc046..000000000
--- a/src/tests/test_mce.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
-* (C) 2015 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include "tests.h"
-
-#if defined(BOTAN_HAS_MCELIECE)
-
-#include <botan/mceliece.h>
-#include <botan/mce_kem.h>
-#include <botan/hmac_drbg.h>
-#include <botan/hash.h>
-#include <botan/hex.h>
-#include <iostream>
-#include <fstream>
-
-using namespace Botan;
-
-namespace {
-
-std::string hash_bytes(const byte b[], size_t len)
- {
- std::unique_ptr<HashFunction> hash(HashFunction::create("SHA-256"));
- hash->update(b, len);
- return hex_encode(hash->final());
- }
-
-template<typename A>
-std::string hash_bytes(const std::vector<byte, A>& v)
- {
- return hash_bytes(v.data(), v.size());
- }
-
-size_t mce_test(const std::string& key_seed_hex,
- size_t n, size_t t,
- const std::string& exp_fingerprint_pub,
- const std::string& exp_fingerprint_priv,
- const std::string& encrypt_rng_seed_hex,
- const std::string& ct_hex,
- const std::string& shared_key_hex)
- {
- const secure_vector<byte> keygen_seed = hex_decode_locked(key_seed_hex);
- const secure_vector<byte> encrypt_seed = hex_decode_locked(encrypt_rng_seed_hex);
-
- Test_State _test;
-
- HMAC_DRBG rng("HMAC(SHA-384)");
-
- rng.add_entropy(keygen_seed.data(), keygen_seed.size());
-
- McEliece_PrivateKey mce_priv(rng, n, t);
-
- const std::string f_pub = hash_bytes(mce_priv.x509_subject_public_key());
- const std::string f_priv = hash_bytes(mce_priv.pkcs8_private_key());
-
- BOTAN_TEST(f_pub, exp_fingerprint_pub, "Public fingerprint");
- BOTAN_TEST(f_priv, exp_fingerprint_priv, "Private fingerprint");
-
- rng.clear();
- rng.add_entropy(encrypt_seed.data(), encrypt_seed.size());
-
- McEliece_KEM_Encryptor kem_enc(mce_priv);
- McEliece_KEM_Decryptor kem_dec(mce_priv);
-
- const std::pair<secure_vector<byte>,secure_vector<byte> > ciphertext__sym_key = kem_enc.encrypt(rng);
- const secure_vector<byte>& ciphertext = ciphertext__sym_key.first;
- const secure_vector<byte>& sym_key_encr = ciphertext__sym_key.second;
-
- const secure_vector<byte> sym_key_decr = kem_dec.decrypt(ciphertext.data(), ciphertext.size());
-
- BOTAN_TEST(ct_hex, hex_encode(ciphertext), "Ciphertext");
- BOTAN_TEST(hex_encode(sym_key_encr), shared_key_hex, "Encrypted key");
- BOTAN_TEST(hex_encode(sym_key_decr), shared_key_hex, "Decrypted key");
-
- return _test.failed();
- }
-
-}
-
-size_t test_mce()
- {
-
- std::ifstream vec(TEST_DATA_DIR "/pubkey/mce.vec");
- return run_tests_bb(vec, "McElieceSeed", "Ciphertext", true,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return mce_test(m["McElieceSeed"],
- to_u32bit(m["KeyN"]),
- to_u32bit(m["KeyT"]),
- m["PublicKeyFingerprint"],
- m["PrivateKeyFingerprint"],
- m["EncryptPRNGSeed"],
- m["Ciphertext"],
- m["SharedKey"]);
- });
- }
-
-#else
-
-SKIP_TEST(mce);
-
-#endif
diff --git a/src/tests/test_mceliece.cpp b/src/tests/test_mceliece.cpp
index fc20d93f7..a2cf5bf8f 100644
--- a/src/tests/test_mceliece.cpp
+++ b/src/tests/test_mceliece.cpp
@@ -10,238 +10,239 @@
#if defined(BOTAN_HAS_MCELIECE)
-#include <botan/pubkey.h>
-#include <botan/oids.h>
#include <botan/mceliece.h>
-#include <botan/internal/code_based_util.h>
#include <botan/mce_kem.h>
+#include <botan/pubkey.h>
+#include <botan/oids.h>
+#include <botan/hmac_drbg.h>
#include <botan/loadstor.h>
+#include <botan/hash.h>
#include <botan/hex.h>
-#include <iostream>
-#include <memory>
#if defined(BOTAN_HAS_MCEIES)
#include <botan/mceies.h>
#endif
-using namespace Botan;
+#endif
-#define CHECK_MESSAGE(expr, print) do {if(!(expr)) {std::cout << print << std::endl; return 1;} }while(0)
-#define CHECK(expr) do {if(!(expr)) { std::cout << #expr << std::endl; return 1; } }while(0)
+namespace Botan_Tests {
namespace {
-const size_t MCE_RUNS = 5;
+#if defined(BOTAN_HAS_MCELIECE)
-size_t test_mceliece_kem(const McEliece_PrivateKey& sk,
- const McEliece_PublicKey& pk,
- RandomNumberGenerator& rng)
+std::vector<byte> hash_bytes(const byte b[], size_t len, const std::string& hash_fn = "SHA-256")
{
- size_t fails = 0;
+ std::unique_ptr<Botan::HashFunction> hash(Botan::HashFunction::create(hash_fn));
+ hash->update(b, len);
+ std::vector<byte> r(hash->output_length());
+ hash->final(r.data());
+ return r;
+ }
- McEliece_KEM_Encryptor pub_op(pk);
- McEliece_KEM_Decryptor priv_op(sk);
+template<typename A>
+std::vector<byte> hash_bytes(const std::vector<byte, A>& v)
+ {
+ return hash_bytes(v.data(), v.size());
+ }
- for(size_t i = 0; i != MCE_RUNS; i++)
- {
- const std::pair<secure_vector<byte>,secure_vector<byte> > ciphertext__sym_key = pub_op.encrypt(rng);
- const secure_vector<byte>& ciphertext = ciphertext__sym_key.first;
- const secure_vector<byte>& sym_key_encr = ciphertext__sym_key.second;
+class McEliece_Keygen_Encrypt_Test : public Text_Based_Test
+ {
+ public:
+ McEliece_Keygen_Encrypt_Test() :
+ Text_Based_Test("McEliece",
+ Test::data_file("pubkey/mce.vec"),
+ {"McElieceSeed", "KeyN","KeyT","PublicKeyFingerprint",
+ "PrivateKeyFingerprint", "EncryptPRNGSeed",
+ "SharedKey", "Ciphertext" })
+ {}
+
+ Test::Result run_one_test(const std::string&, const VarMap& vars) override
+ {
+ const std::vector<byte> keygen_seed = get_req_bin(vars, "McElieceSeed");
+ const std::vector<byte> fprint_pub = get_req_bin(vars, "PublicKeyFingerprint");
+ const std::vector<byte> fprint_priv = get_req_bin(vars, "PrivateKeyFingerprint");
+ const std::vector<byte> encrypt_seed = get_req_bin(vars, "EncryptPRNGSeed");
+ const std::vector<byte> ciphertext = get_req_bin(vars, "Ciphertext");
+ const std::vector<byte> shared_key = get_req_bin(vars, "SharedKey");
+ const size_t keygen_n = get_req_sz(vars, "KeyN");
+ const size_t keygen_t = get_req_sz(vars, "KeyT");
- const secure_vector<byte> sym_key_decr = priv_op.decrypt(ciphertext.data(), ciphertext.size());
+ Botan::HMAC_DRBG rng("HMAC(SHA-384)");
- if(sym_key_encr != sym_key_decr)
- {
- std::cout << "mce KEM test failed, error during encryption/decryption" << std::endl;
- ++fails;
- }
- }
+ rng.add_entropy(keygen_seed.data(), keygen_seed.size());
+ Botan::McEliece_PrivateKey mce_priv(rng, keygen_n, keygen_t);
- return fails;
- }
+ Test::Result result("McEliece keygen");
-/*
-size_t test_mceliece_raw(const McEliece_PrivateKey& sk,
- const McEliece_PublicKey& pk,
- RandomNumberGenerator& rng)
- {
- const size_t code_length = pk.get_code_length();
- McEliece_Private_Operation priv_op(sk);
- McEliece_Public_Operation pub_op(pk);
- size_t err_cnt = 0;
-
- for(size_t i = 0; i != MCE_RUNS; i++)
- {
- const secure_vector<byte> plaintext = pk.random_plaintext_element(rng);
- secure_vector<gf2m> err_pos = create_random_error_positions(code_length, pk.get_t(), rng);
-
- mceliece_message_parts parts(err_pos, plaintext, code_length);
- secure_vector<byte> message_and_error_input = parts.get_concat();
- secure_vector<byte> ciphertext = pub_op.encrypt(message_and_error_input.data(), message_and_error_input.size(), rng);
- //std::cout << "ciphertext byte length = " << ciphertext.size() << std::endl;
- secure_vector<byte> message_and_error_output = priv_op.decrypt(ciphertext.data(), ciphertext.size() );
- if(message_and_error_input != message_and_error_output)
- {
- mceliece_message_parts combined(message_and_error_input.data(), message_and_error_input.size(), code_length);
- secure_vector<byte> orig_pt = combined.get_message_word();
- secure_vector<byte> orig_ev = combined.get_error_vector();
-
- mceliece_message_parts decr_combined(message_and_error_output.data(), message_and_error_output.size(), code_length);
- secure_vector<byte> decr_pt = decr_combined.get_message_word();
- secure_vector<byte> decr_ev = decr_combined.get_error_vector();
- std::cout << "ciphertext = " << hex_encode(ciphertext) << std::endl;
- std::cout << "original plaintext = " << hex_encode(orig_pt) << std::endl;
- std::cout << "original error vector = " << hex_encode(orig_ev) << std::endl;
- std::cout << "decrypted plaintext = " << hex_encode(decr_pt) << std::endl;
- std::cout << "decrypted error vector = " << hex_encode(decr_ev) << std::endl;
- err_cnt++;
- std::cout << "mce test failed, error during encryption/decryption" << std::endl;
- std::cout << "err pos during encryption = ";
- for(size_t j = 0; j < err_pos.size(); j++) std::printf("%u, ", err_pos[j]);
- printf("\n");
- return 1;
+ result.test_eq("public key fingerprint", hash_bytes(mce_priv.x509_subject_public_key()), fprint_pub);
+ result.test_eq("private key fingerprint", hash_bytes(mce_priv.pkcs8_private_key()), fprint_priv);
+
+ rng.clear();
+ rng.add_entropy(encrypt_seed.data(), encrypt_seed.size());
+
+ Botan::McEliece_KEM_Encryptor kem_enc(mce_priv);
+ Botan::McEliece_KEM_Decryptor kem_dec(mce_priv);
+
+ const auto kem = kem_enc.encrypt(rng);
+ result.test_eq("ciphertext", kem.first, ciphertext);
+ result.test_eq("encrypt shared", kem.second, shared_key);
+ result.test_eq("decrypt shared", kem_dec.decrypt_vec(kem.first), shared_key);
+ return result;
}
- }
- return err_cnt;
- }
-*/
+ };
-#if defined(BOTAN_HAS_MCEIES)
-size_t test_mceies(const McEliece_PrivateKey& sk,
- const McEliece_PublicKey& pk,
- RandomNumberGenerator& rng)
+BOTAN_REGISTER_TEST("mce_keygen", McEliece_Keygen_Encrypt_Test);
+
+class McEliece_Tests : public Test
{
- size_t fails = 0;
+ public:
- for(size_t i = 0; i != 5; ++i)
- {
- byte ad[8];
- store_be(static_cast<u64bit>(i), ad);
- const size_t ad_len = sizeof(ad);
+ std::string fingerprint(const Botan::Private_Key& key, const std::string& hash_algo = "SHA-256")
+ {
+ std::unique_ptr<Botan::HashFunction> hash(Botan::HashFunction::create(hash_algo));
+ if(!hash)
+ throw std::runtime_error("Hash " + hash_algo + " not available");
- const secure_vector<byte> pt = rng.random_vec(rng.next_byte());
- const secure_vector<byte> ct = mceies_encrypt(pk, pt.data(), pt.size(), ad, ad_len, rng);
- const secure_vector<byte> dec = mceies_decrypt(sk, ct.data(), ct.size(), ad, ad_len);
+ hash->update(key.pkcs8_private_key());
+ return Botan::hex_encode(hash->final());
+ }
- if(pt != dec)
+ std::string fingerprint(const Botan::Public_Key& key, const std::string& hash_algo = "SHA-256")
{
- std::cout << "MCEIES " << hex_encode(pt) << " != " << hex_encode(dec) << std::endl;
- ++fails;
+ std::unique_ptr<Botan::HashFunction> hash(Botan::HashFunction::create(hash_algo));
+ if(!hash)
+ throw std::runtime_error("Hash " + hash_algo + " not available");
+
+ hash->update(key.x509_subject_public_key());
+ return Botan::hex_encode(hash->final());
}
- secure_vector<byte> bad_ct = ct;
- for(size_t j = 0; j != 2; ++j)
+ std::vector<Test::Result> run() override
{
- bad_ct = ct;
+ size_t params__n__t_min_max[] = {
+ 256, 5, 15,
+ 512, 5, 33,
+ 1024, 15, 35,
+ 2048, 33, 50,
+ 2960, 50, 56,
+ 6624, 110, 115
+ };
+
+ std::vector<Test::Result> results;
+
+ for(size_t i = 0; i < sizeof(params__n__t_min_max)/sizeof(params__n__t_min_max[0]); i+=3)
+ {
+ const size_t code_length = params__n__t_min_max[i];
+ const size_t min_t = params__n__t_min_max[i+1];
+ const size_t max_t = params__n__t_min_max[i+2];
- byte nonzero = 0;
- while(nonzero == 0)
- nonzero = rng.next_byte();
+ for(size_t t = min_t; t <= max_t; ++t)
+ {
+ Botan::McEliece_PrivateKey sk1(Test::rng(), code_length, t);
+ const Botan::McEliece_PublicKey& pk1 = sk1;
- bad_ct[rng.next_byte() % bad_ct.size()] ^= nonzero;
+ const std::vector<byte> pk_enc = pk1.x509_subject_public_key();
+ const Botan::secure_vector<byte> sk_enc = sk1.pkcs8_private_key();
- try
- {
- mceies_decrypt(sk, bad_ct.data(), bad_ct.size(), ad, ad_len);
- std::cout << "Successfully decrypted manipulated ciphertext!" << std::endl;
- ++fails;
- }
- catch(std::exception& e) { /* Yay */ }
+ Botan::McEliece_PublicKey pk(pk_enc);
+ Botan::McEliece_PrivateKey sk(sk_enc);
- bad_ct[i] ^= nonzero;
- }
- }
+ Test::Result result("McEliece keygen");
- return fails;
- }
-#endif // BOTAN_HAS_MCEIES
+ result.test_eq("decoded public key equals original", fingerprint(pk1), fingerprint(pk));
-}
+ result.test_eq("decoded private key equals original", fingerprint(sk1), fingerprint(sk));
-size_t test_mceliece()
- {
- auto& rng = test_rng();
-
- size_t fails = 0;
- size_t params__n__t_min_max[] = {
- 256, 5, 15,
- 512, 5, 33,
- 1024, 15, 35,
- 2048, 33, 50,
- 2960, 50, 56,
- 6624, 110, 115
- };
+ result.test_eq("key validation passes", sk.check_key(Test::rng(), false), true);
- size_t tests = 0;
+ results.push_back(result);
- for(size_t i = 0; i < sizeof(params__n__t_min_max)/sizeof(params__n__t_min_max[0]); i+=3)
- {
- size_t code_length = params__n__t_min_max[i];
- for(size_t t = params__n__t_min_max[i+1]; t <= params__n__t_min_max[i+2]; t++)
- {
- //std::cout << "testing parameters n = " << code_length << ", t = " << t << std::endl;
+ results.push_back(test_kem(sk, pk));
- McEliece_PrivateKey sk1(rng, code_length, t);
- const McEliece_PublicKey& pk1 = sk1;
+#if defined(BOTAN_HAS_MCEIES)
+ results.push_back(test_mceies(sk, pk));
+#endif
+ }
+ }
- const std::vector<byte> pk_enc = pk1.x509_subject_public_key();
- const secure_vector<byte> sk_enc = sk1.pkcs8_private_key();
+ return results;
+ }
- McEliece_PublicKey pk(pk_enc);
- McEliece_PrivateKey sk(sk_enc);
+ private:
+ Test::Result test_kem(const Botan::McEliece_PrivateKey& sk,
+ const Botan::McEliece_PublicKey& pk)
+ {
+ Test::Result result("McEliece KEM");
- if(pk1 != pk)
- {
- std::cout << "Decoded McEliece public key differs from original one" << std::endl;
- ++fails;
- }
+ Botan::McEliece_KEM_Encryptor pub_op(pk);
+ Botan::McEliece_KEM_Decryptor priv_op(sk);
- if(sk1 != sk)
+ for(size_t i = 0; i <= Test::soak_level(); i++)
{
- std::cout << "Decoded McEliece private key differs from original one" << std::endl;
- ++fails;
- }
+ const std::pair<Botan::secure_vector<byte>,Botan::secure_vector<byte> > ciphertext__sym_key = pub_op.encrypt(Test::rng());
+ const Botan::secure_vector<byte>& ciphertext = ciphertext__sym_key.first;
+ const Botan::secure_vector<byte>& sym_key_encr = ciphertext__sym_key.second;
- if(!sk.check_key(rng, false))
- {
- std::cout << "Error calling check key on McEliece key" << std::endl;
- ++fails;
- }
+ const Botan::secure_vector<byte> sym_key_decr = priv_op.decrypt(ciphertext.data(), ciphertext.size());
- try
- {
- fails += test_mceliece_kem(sk, pk, rng);
- }
- catch(std::exception& e)
- {
- std::cout << e.what() << std::endl;
- fails++;
+ result.test_eq("same key", sym_key_decr, sym_key_encr);
}
- tests += 1;
+ return result;
+ }
#if defined(BOTAN_HAS_MCEIES)
- try
- {
- fails += test_mceies(sk, pk, rng);
- }
- catch(std::exception& e)
+ Test::Result test_mceies(const Botan::McEliece_PrivateKey& sk,
+ const Botan::McEliece_PublicKey& pk)
+ {
+ Test::Result result("McEliece IES");
+
+ for(size_t i = 0; i <= Test::soak_level(); ++i)
{
- std::cout << e.what() << std::endl;
- fails++;
+ uint8_t ad[8];
+ Botan::store_be(static_cast<Botan::u64bit>(i), ad);
+ const size_t ad_len = sizeof(ad);
+
+ const Botan::secure_vector<byte> pt = Test::rng().random_vec(Test::rng().next_byte());
+
+ const Botan::secure_vector<byte> ct = mceies_encrypt(pk, pt.data(), pt.size(), ad, ad_len, Test::rng());
+ const Botan::secure_vector<byte> dec = mceies_decrypt(sk, ct.data(), ct.size(), ad, ad_len);
+
+ result.test_eq("decrypted ok", dec, pt);
+
+ Botan::secure_vector<byte> bad_ct = ct;
+ for(size_t j = 0; j != 3; ++j)
+ {
+ bad_ct = mutate_vec(ct, true);
+
+ try
+ {
+ mceies_decrypt(sk, bad_ct.data(), bad_ct.size(), ad, ad_len);
+ result.test_failure("AEAD decrypted manipulated ciphertext");
+ result.test_note("Manipulated text was " + Botan::hex_encode(bad_ct));
+ }
+ catch(Botan::Integrity_Failure& e)
+ {
+ result.test_note("AEAD rejected manipulated ciphertext");
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure("AEAD rejected manipulated ciphertext with unexpected error", e.what());
+ }
+ }
}
- tests += 1;
-#endif // BOTAN_HAS_MCEIES
+ return result;
}
- }
+#endif
- test_report("McEliece", tests, fails);
- return fails;
- }
+ };
-#else
+BOTAN_REGISTER_TEST("mceliece", McEliece_Tests);
-SKIP_TEST(mceliece);
+#endif
-#endif // BOTAN_HAS_MCELIECE
+}
+
+}
diff --git a/src/tests/test_modes.cpp b/src/tests/test_modes.cpp
index f443ddabf..cc1645e92 100644
--- a/src/tests/test_modes.cpp
+++ b/src/tests/test_modes.cpp
@@ -7,93 +7,62 @@
#include "tests.h"
#if defined(BOTAN_HAS_MODES)
+ #include <botan/cipher_mode.h>
+#endif
-#include <botan/hex.h>
-#include <botan/cipher_mode.h>
-#include <iostream>
-#include <fstream>
-#include <memory>
+namespace Botan_Tests {
-using namespace Botan;
-
-namespace {
+#if defined(BOTAN_HAS_MODES)
-secure_vector<byte> run_mode(const std::string& algo,
- Cipher_Dir dir,
- const secure_vector<byte>& pt,
- const secure_vector<byte>& nonce,
- const secure_vector<byte>& key)
+class Cipher_Mode_Tests : public Text_Based_Test
{
- std::unique_ptr<Cipher_Mode> cipher(get_cipher_mode(algo, dir));
- if(!cipher)
- throw std::runtime_error("No cipher " + algo + " enabled in build");
-
- cipher->set_key(key);
- cipher->start(nonce);
-
- secure_vector<byte> ct = pt;
- cipher->finish(ct);
- return ct;
- }
-
-size_t mode_test(const std::string& algo,
- const std::string& pt,
- const std::string& ct,
- const std::string& key_hex,
- const std::string& nonce_hex)
- {
- auto nonce = hex_decode_locked(nonce_hex);
- auto key = hex_decode_locked(key_hex);
-
- size_t fails = 0;
-
- const std::string ct2 = hex_encode(run_mode(algo,
- ENCRYPTION,
- hex_decode_locked(pt),
- nonce,
- key));
-
- if(ct != ct2)
- {
- std::cout << algo << " got ct " << ct2 << " expected " << ct << std::endl;
- ++fails;
- }
-
- const std::string pt2 = hex_encode(run_mode(algo,
- DECRYPTION,
- hex_decode_locked(ct),
- nonce,
- key));
-
- if(pt != pt2)
- {
- std::cout << algo << " got pt " << pt2 << " expected " << pt << std::endl;
- ++fails;
- }
-
- return fails;
- }
+ public:
+ Cipher_Mode_Tests() :
+ Text_Based_Test(Test::data_dir("modes"), {"Key", "Nonce", "In", "Out"})
+ {}
-}
+ Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
+ {
+ const std::vector<uint8_t> key = get_req_bin(vars, "Key");
+ const std::vector<uint8_t> nonce = get_opt_bin(vars, "Nonce");
+ const std::vector<uint8_t> input = get_req_bin(vars, "In");
+ const std::vector<uint8_t> expected = get_req_bin(vars, "Out");
-size_t test_modes()
- {
- auto test = [](const std::string& input)
- {
- std::ifstream vec(input);
+ Test::Result result(algo);
+
+ std::unique_ptr<Botan::Cipher_Mode> enc(Botan::get_cipher_mode(algo, Botan::ENCRYPTION));
+ std::unique_ptr<Botan::Cipher_Mode> dec(Botan::get_cipher_mode(algo, Botan::DECRYPTION));
+
+ if(!enc || !dec)
+ {
+ result.note_missing(algo);
+ return result;
+ }
- return run_tests_bb(vec, "Mode", "Out", true,
- [](std::map<std::string, std::string> m)
- {
- return mode_test(m["Mode"], m["In"], m["Out"], m["Key"], m["Nonce"]);
- });
- };
+ result.test_eq("mode not authenticated", enc->authenticated(), false);
- return run_tests_in_dir(TEST_DATA_DIR "/modes", test);
- }
+ enc->set_key(key);
+ enc->start(nonce);
-#else
+ Botan::secure_vector<uint8_t> buf(input.begin(), input.end());
+ // TODO: should first update if possible
+ enc->finish(buf);
-SKIP_TEST(modes);
+ result.test_eq("encrypt", buf, expected);
-#endif // BOTAN_HAS_MODES
+ buf.assign(expected.begin(), expected.end());
+
+ dec->set_key(key);
+ dec->start(nonce);
+ dec->finish(buf);
+ result.test_eq("decrypt", buf, input);
+
+ return result;
+ }
+ };
+
+BOTAN_REGISTER_TEST("modes", Cipher_Mode_Tests);
+
+#endif
+
+}
diff --git a/src/tests/test_nr.cpp b/src/tests/test_nr.cpp
index 334b10359..856954cd2 100644
--- a/src/tests/test_nr.cpp
+++ b/src/tests/test_nr.cpp
@@ -7,66 +7,63 @@
#include "tests.h"
#if defined(BOTAN_HAS_NYBERG_RUEPPEL)
+ #include <botan/nr.h>
+ #include "test_pubkey.h"
+#endif
-#include "test_pubkey.h"
-
-#include <botan/hex.h>
-#include <botan/nr.h>
-#include <botan/pubkey.h>
-#include <botan/dl_group.h>
-#include <iostream>
-#include <fstream>
-
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-size_t nr_sig_kat(const std::string& p,
- const std::string& q,
- const std::string& g,
- const std::string& x,
- const std::string& hash,
- const std::string& msg,
- const std::string& nonce,
- const std::string& signature)
- {
- auto& rng = test_rng();
-
- BigInt p_bn(p), q_bn(q), g_bn(g), x_bn(x);
-
- DL_Group group(p_bn, q_bn, g_bn);
-
- NR_PrivateKey privkey(rng, group, x_bn);
-
- NR_PublicKey pubkey = privkey;
-
- const std::string padding = "EMSA1(" + hash + ")";
-
- PK_Verifier verify(pubkey, padding);
- PK_Signer sign(privkey, padding);
-
- return validate_signature(verify, sign, "nr/" + hash, msg, rng, nonce, signature);
- }
-
-}
+#if defined(BOTAN_HAS_NYBERG_RUEPPEL)
-size_t test_nr()
+class NR_KAT_Tests : public PK_Signature_Generation_Test
{
- size_t fails = 0;
-
- std::ifstream nr_sig(TEST_DATA_DIR_PK "/nr.vec");
+ public:
+ NR_KAT_Tests() : PK_Signature_Generation_Test(
+ "Nyberg-Rueppel",
+ Test::data_file("pubkey/nr.vec"),
+ {"P", "Q", "G", "X", "Hash", "Nonce", "Msg", "Signature"})
+ {}
+
+ std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override
+ {
+ const Botan::BigInt p = get_req_bn(vars, "P");
+ const Botan::BigInt q = get_req_bn(vars, "Q");
+ const Botan::BigInt g = get_req_bn(vars, "G");
+ const Botan::BigInt x = get_req_bn(vars, "X");
+
+ const Botan::DL_Group grp(p, q, g);
+
+ std::unique_ptr<Botan::Private_Key> key(new Botan::NR_PrivateKey(Test::rng(), grp, x));
+ return key;
+ }
+
+ std::string default_padding(const VarMap& vars) const override
+ {
+ return "EMSA1(" + get_req_str(vars, "Hash") + ")";
+ }
+ };
+
+class NR_Keygen_Tests : public PK_Key_Generation_Test
+ {
+ public:
+ std::vector<std::string> keygen_params() const override { return { "dsa/jce/1024", "dsa/botan/2048" }; }
- fails += run_tests_bb(nr_sig, "NR Signature", "Signature", true,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return nr_sig_kat(m["P"], m["Q"], m["G"], m["X"], m["Hash"], m["Msg"], m["Nonce"], m["Signature"]);
- });
+ std::unique_ptr<Botan::Private_Key> make_key(Botan::RandomNumberGenerator& rng,
+ const std::string& param) const override
+ {
+ Botan::DL_Group group(param);
+ std::unique_ptr<Botan::Private_Key> key(new Botan::NR_PrivateKey(rng, group));
+ return key;
+ }
+ };
- return fails;
- }
+BOTAN_REGISTER_TEST("nr_kat", NR_KAT_Tests);
+BOTAN_REGISTER_TEST("nr_keygen", NR_Keygen_Tests);
-#else
+#endif
-SKIP_TEST(nr);
+}
-#endif // BOTAN_HAS_NYBERG_RUEPPEL
+}
diff --git a/src/tests/test_ocb.cpp b/src/tests/test_ocb.cpp
index 891ecb54d..314fa31df 100644
--- a/src/tests/test_ocb.cpp
+++ b/src/tests/test_ocb.cpp
@@ -7,133 +7,115 @@
#include "tests.h"
#if defined(BOTAN_HAS_AEAD_OCB)
+ #include <botan/ocb.h>
+ #include <botan/loadstor.h>
+#endif
-#if defined(BOTAN_HAS_AES)
-
-#include <iostream>
-#include <botan/ocb.h>
-#include <botan/hex.h>
-#include <botan/sha2_32.h>
-#include <botan/aes.h>
-#include <botan/loadstor.h>
-
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-std::vector<byte> ocb_encrypt(OCB_Encryption& enc,
- OCB_Decryption& dec,
- const std::vector<byte>& nonce,
- const std::vector<byte>& pt,
- const std::vector<byte>& ad)
- {
- enc.set_associated_data(ad.data(), ad.size());
-
- enc.start(nonce.data(), nonce.size());
-
- secure_vector<byte> buf(pt.begin(), pt.end());
- enc.finish(buf, 0);
-
- try
- {
- secure_vector<byte> ct = buf;
+#if defined(BOTAN_HAS_AEAD_OCB)
- dec.set_associated_data(ad.data(), ad.size());
+class OCB_Long_KAT_Tests : public Text_Based_Test
+ {
+ public:
+ OCB_Long_KAT_Tests() : Text_Based_Test(Test::data_file("ocb_long.vec"),
+ {"Keylen", "Taglen", "Output"}) {}
- dec.start(nonce.data(), nonce.size());
+ Test::Result run_one_test(const std::string&, const VarMap& vars)
+ {
+ const size_t keylen = get_req_sz(vars, "Keylen");
+ const size_t taglen = get_req_sz(vars, "Taglen");
+ const std::vector<byte> expected = get_req_bin(vars, "Output");
- dec.finish(ct, 0);
+ // Test from RFC 7253 Appendix A
- if(ct != pt)
- std::cout << "OCB failed to decrypt correctly" << std::endl;
- }
- catch(std::exception& e)
- {
- std::cout << "OCB round trip error - " << e.what() << std::endl;
- }
+ const std::string algo = "AES-" + std::to_string(keylen);
- return unlock(buf);
- }
+ Test::Result result("OCB long");
-size_t test_ocb_long(size_t keylen, size_t taglen,
- const std::string &expected)
- {
- // Test from RFC 7253 Appendix A
+ std::unique_ptr<Botan::BlockCipher> aes(Botan::BlockCipher::create(algo));
+ if(!aes)
+ {
+ result.note_missing(algo);
+ return result;
+ }
- const std::string algo = "AES-" + std::to_string(keylen);
+ Botan::OCB_Encryption enc(aes->clone(), taglen / 8);
+ Botan::OCB_Decryption dec(aes->clone(), taglen / 8);
- std::unique_ptr<BlockCipher> aes(BlockCipher::create(algo));
- if(!aes)
- throw Algorithm_Not_Found(algo);
+ std::vector<byte> key(keylen/8);
+ key[keylen/8-1] = taglen;
- OCB_Encryption enc(aes->clone(), taglen / 8);
- OCB_Decryption dec(aes->clone(), taglen / 8);
+ enc.set_key(key);
+ dec.set_key(key);
- std::vector<byte> key(keylen/8);
- key[keylen/8-1] = taglen;
+ const std::vector<byte> empty;
+ std::vector<byte> N(12);
+ std::vector<byte> C;
- enc.set_key(key);
- dec.set_key(key);
+ for(size_t i = 0; i != 128; ++i)
+ {
+ const std::vector<byte> S(i);
- const std::vector<byte> empty;
- std::vector<byte> N(12);
- std::vector<byte> C;
+ Botan::store_be(static_cast<uint32_t>(3*i+1), &N[8]);
- for(size_t i = 0; i != 128; ++i)
- {
- const std::vector<byte> S(i);
+ ocb_encrypt(result, C, enc, dec, N, S, S);
+ Botan::store_be(static_cast<uint32_t>(3*i+2), &N[8]);
+ ocb_encrypt(result, C, enc, dec, N, S, empty);
+ Botan::store_be(static_cast<uint32_t>(3*i+3), &N[8]);
+ ocb_encrypt(result, C, enc, dec, N, empty, S);
+ }
- store_be(static_cast<u32bit>(3*i+1), &N[8]);
- C += ocb_encrypt(enc, dec, N, S, S);
- store_be(static_cast<u32bit>(3*i+2), &N[8]);
- C += ocb_encrypt(enc, dec, N, S, empty);
- store_be(static_cast<u32bit>(3*i+3), &N[8]);
- C += ocb_encrypt(enc, dec, N, empty, S);
- }
+ Botan::store_be(static_cast<uint32_t>(385), &N[8]);
+ std::vector<byte> final_result;
+ ocb_encrypt(result, final_result, enc, dec, N, empty, C);
- store_be(static_cast<u32bit>(385), &N[8]);
- const std::vector<byte> cipher = ocb_encrypt(enc, dec, N, empty, C);
+ result.test_eq("correct value", final_result, expected);
- const std::string cipher_hex = hex_encode(cipher);
+ return result;
+ }
+ private:
+ void ocb_encrypt(Test::Result& result,
+ std::vector<byte>& output_to,
+ Botan::OCB_Encryption& enc,
+ Botan::OCB_Decryption& dec,
+ const std::vector<byte>& nonce,
+ const std::vector<byte>& pt,
+ const std::vector<byte>& ad)
+ {
+ enc.set_associated_data(ad.data(), ad.size());
- if(cipher_hex != expected)
- {
- std::cout << "OCB " << algo << " long test mistmatch "
- << cipher_hex << " != " << expected << std::endl;
- return 1;
- }
+ enc.start(nonce.data(), nonce.size());
- return 0;
- }
+ Botan::secure_vector<byte> buf(pt.begin(), pt.end());
+ enc.finish(buf, 0);
+ output_to.insert(output_to.end(), buf.begin(), buf.end());
-}
+ try
+ {
+ dec.set_associated_data(ad.data(), ad.size());
-size_t test_ocb()
- {
- size_t fails = 0;
+ dec.start(nonce.data(), nonce.size());
- fails += test_ocb_long(128, 128, "67E944D23256C5E0B6C61FA22FDF1EA2");
- fails += test_ocb_long(192, 128, "F673F2C3E7174AAE7BAE986CA9F29E17");
- fails += test_ocb_long(256, 128, "D90EB8E9C977C88B79DD793D7FFA161C");
- fails += test_ocb_long(128, 96, "77A3D8E73589158D25D01209");
- fails += test_ocb_long(192, 96, "05D56EAD2752C86BE6932C5E");
- fails += test_ocb_long(256, 96, "5458359AC23B0CBA9E6330DD");
- fails += test_ocb_long(128, 64, "192C9B7BD90BA06A");
- fails += test_ocb_long(192, 64, "0066BC6E0EF34E24");
- fails += test_ocb_long(256, 64, "7D4EA5D445501CBE");
- test_report("OCB long", 9, fails);
+ dec.finish(buf, 0);
- return fails;
- }
+ result.test_eq("OCB round tripped", buf, pt);
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure("OCB round trip error", e.what());
+ }
-#else
+ }
+ };
-UNTESTED_WARNING(ocb);
+BOTAN_REGISTER_TEST("ocb_long", OCB_Long_KAT_Tests);
-#endif // BOTAN_HAS_AES
+#endif
-#else
+}
-SKIP_TEST(ocb);
+}
-#endif // BOTAN_HAS_AEAD_OCB
diff --git a/src/tests/test_passhash.cpp b/src/tests/test_passhash.cpp
index 4bc69125b..e9606062c 100644
--- a/src/tests/test_passhash.cpp
+++ b/src/tests/test_passhash.cpp
@@ -6,94 +6,99 @@
#include "tests.h"
-#include <iostream>
+#if defined(BOTAN_HAS_BCRYPT)
+ #include <botan/bcrypt.h>
+#endif
#if defined(BOTAN_HAS_PASSHASH9)
#include <botan/passhash9.h>
#endif
-#if defined(BOTAN_HAS_BCRYPT)
- #include <botan/bcrypt.h>
-#endif
-
-using namespace Botan;
+namespace Botan_Tests {
-size_t test_bcrypt()
- {
- size_t fails = 0;
+namespace {
#if defined(BOTAN_HAS_BCRYPT)
+class Bcrypt_Tests : public Text_Based_Test
+ {
+ public:
+ Bcrypt_Tests() : Text_Based_Test(Test::data_file("bcrypt.vec"), {"Password","Passhash"}) {}
- // Generated by jBCrypt 0.3
- if(!check_bcrypt("abc", "$2a$05$DfPyLs.G6.To9fXEFgUL1O6HpYw3jIXgPcl/L3Qt3jESuWmhxtmpS"))
- {
- std::cout << "Bcrypt test 1 failed" << std::endl;
- fails++;
- }
-
- // http://www.openwall.com/lists/john-dev/2011/06/19/2
- if(!check_bcrypt("\xA3",
- "$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq"))
- {
- std::cout << "Bcrypt test 2 failed" << std::endl;
- fails++;
- }
-
- auto& rng = test_rng();
-
- for(u16bit level = 1; level != 5; ++level)
- {
- const std::string input = "some test passphrase 123";
- const std::string gen_hash = generate_bcrypt(input, rng, level);
-
- if(!check_bcrypt(input, gen_hash))
+ Test::Result run_one_test(const std::string&, const VarMap& vars) override
{
- std::cout << "Gen and check for bcrypt failed: " << gen_hash << " not valid" << std::endl;
- ++fails;
- }
- }
+ // Encoded as binary so we can test binary inputs
+ const std::vector<byte> password_vec = get_req_bin(vars, "Password");
+ const std::string password(reinterpret_cast<const char*>(password_vec.data()),
+ password_vec.size());
- test_report("Bcrypt", 6, fails);
+ const std::string passhash = get_req_str(vars, "Passhash");
-#endif
+ Test::Result result("bcrypt");
+ result.test_eq("correct hash accepted", Botan::check_bcrypt(password, passhash), true);
- return fails;
- }
+ const size_t max_level = 1 + std::min<size_t>(Test::soak_level() / 2, 10);
-size_t test_passhash9()
- {
- size_t fails = 0;
+ for(size_t level = 1; level <= max_level; ++level)
+ {
+ const std::string gen_hash = generate_bcrypt(password, Test::rng(), level);
+ result.test_eq("generated hash accepted", Botan::check_bcrypt(password, gen_hash), true);
+ }
-#if defined(BOTAN_HAS_PASSHASH9)
- const std::string input = "secret";
- const std::string fixed_hash =
- "$9$AAAKhiHXTIUhNhbegwBXJvk03XXJdzFMy+i3GFMIBYKtthTTmXZA";
-
- size_t ran = 0;
+ return result;
+ }
+ };
- ++ran;
- if(!check_passhash9(input, fixed_hash))
- {
- std::cout << "Passhash9 fixed input test failed" << std::endl;
- fails++;
- }
+BOTAN_REGISTER_TEST("bcrypt", Bcrypt_Tests);
- auto& rng = test_rng();
+#endif
- for(byte alg_id = 0; alg_id <= 4; ++alg_id)
- {
- std::string gen_hash = generate_passhash9(input, rng, 2, alg_id);
+#if defined(BOTAN_HAS_PASSHASH9)
+class Passhash9_Tests : public Text_Based_Test
+ {
+ public:
+ Passhash9_Tests() : Text_Based_Test(Test::data_file("passhash9.vec"), {"Password","Passhash"}) {}
- ++ran;
- if(!check_passhash9(input, gen_hash))
+ Test::Result run_one_test(const std::string&, const VarMap& vars) override
{
- std::cout << "Passhash9 gen and check " << static_cast<int>(alg_id) << " failed" << std::endl;
- ++fails;
+ // Encoded as binary so we can test binary inputs
+ const std::vector<byte> password_vec = get_req_bin(vars, "Password");
+ const std::string password(reinterpret_cast<const char*>(password_vec.data()),
+ password_vec.size());
+
+ const std::string passhash = get_req_str(vars, "Passhash");
+
+ Test::Result result("passhash9");
+ result.test_eq("correct hash accepted", Botan::check_passhash9(password, passhash), true);
+
+ for(byte alg_id = 0; alg_id <= 4; ++alg_id)
+ {
+ const std::string gen_hash = Botan::generate_passhash9(password, Test::rng(), 2, alg_id);
+
+ if(!result.test_eq("generated hash accepted", Botan::check_passhash9(password, gen_hash), true))
+ {
+ result.test_note("hash was " + gen_hash);
+ }
+ }
+
+ const size_t max_level = 1 + std::min<size_t>(Test::soak_level() / 2, 10);
+
+ for(size_t level = 1; level <= max_level; ++level)
+ {
+ const std::string gen_hash = Botan::generate_passhash9(password, Test::rng(), level);
+ if(!result.test_eq("generated hash accepted", Botan::check_passhash9(password, gen_hash), true))
+ {
+ result.test_note("hash was " + gen_hash);
+ }
+ }
+
+ return result;
}
- }
+ };
+
+BOTAN_REGISTER_TEST("passhash9", Passhash9_Tests);
- test_report("Passhash9", ran, fails);
#endif
- return fails;
- }
+}
+
+}
diff --git a/src/tests/test_pbkdf.cpp b/src/tests/test_pbkdf.cpp
index 1f5a0a6a1..2e3b26d48 100644
--- a/src/tests/test_pbkdf.cpp
+++ b/src/tests/test_pbkdf.cpp
@@ -7,40 +7,52 @@
#include "tests.h"
#if defined(BOTAN_HAS_PBKDF)
+ #include <botan/pbkdf.h>
+#endif
-#include <botan/pbkdf.h>
-#include <botan/hex.h>
-#include <iostream>
-#include <fstream>
+namespace Botan_Tests {
-using namespace Botan;
+namespace {
-size_t test_pbkdf()
+#if defined(BOTAN_HAS_PBKDF)
+class PBKDF_KAT_Tests : public Text_Based_Test
{
- auto test = [](const std::string& input)
- {
- return run_tests(input, "PBKDF", "Output", true,
- [](std::map<std::string, std::string> vec)
- {
- std::unique_ptr<PBKDF> pbkdf(get_pbkdf(vec["PBKDF"]));
+ public:
+ PBKDF_KAT_Tests() : Text_Based_Test(Test::data_dir("pbkdf"),
+ {"OutputLen", "Iterations", "Salt", "Passphrase", "Output"})
+ {}
+
+ Test::Result run_one_test(const std::string& pbkdf_name, const VarMap& vars)
+ {
+ Test::Result result(pbkdf_name);
+ std::unique_ptr<Botan::PBKDF> pbkdf(Botan::get_pbkdf(pbkdf_name));
+
+ if(!pbkdf)
+ {
+ result.note_missing(pbkdf_name);
+ return result;
+ }
+
+ const size_t outlen = get_req_sz(vars, "OutputLen");
+ const size_t iterations = get_req_sz(vars, "Iterations");
+ const std::vector<uint8_t> salt = get_req_bin(vars, "Salt");
+ const std::string passphrase = get_req_str(vars, "Passphrase");
+ const std::vector<uint8_t> expected = get_req_bin(vars, "Output");
+
+ const Botan::secure_vector<byte> derived =
+ pbkdf->derive_key(outlen, passphrase, salt.data(), salt.size(), iterations).bits_of();
+
+ result.test_eq("derived key", derived, expected);
- const size_t iterations = to_u32bit(vec["Iterations"]);
- const size_t outlen = to_u32bit(vec["OutputLen"]);
- const auto salt = hex_decode(vec["Salt"]);
- const std::string pass = vec["Passphrase"];
+ return result;
+ }
- const auto key = pbkdf->derive_key(outlen, pass,
- salt.data(), salt.size(),
- iterations).bits_of();
- return hex_encode(key);
- });
- };
+ };
- return run_tests_in_dir(TEST_DATA_DIR "/pbkdf", test);
- }
+BOTAN_REGISTER_TEST("pbkdf", PBKDF_KAT_Tests);
-#else
+#endif
-SKIP_TEST(pbkdf);
+}
-#endif // BOTAN_HAS_PBKDF
+}
diff --git a/src/tests/test_pubkey.cpp b/src/tests/test_pubkey.cpp
index 09f3843bb..d2bc4e9eb 100644
--- a/src/tests/test_pubkey.cpp
+++ b/src/tests/test_pubkey.cpp
@@ -1,405 +1,333 @@
/*
-* (C) 2009 Jack Lloyd
+* (C) 2009,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
-#include "tests.h"
+#include "test_pubkey.h"
#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO)
#include "test_rng.h"
-#include "test_pubkey.h"
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <vector>
-#include <cstdlib>
-#include <memory>
-#include <botan/oids.h>
+#include <botan/pubkey.h>
#include <botan/x509_key.h>
#include <botan/pkcs8.h>
-#include <botan/pubkey.h>
+#include <botan/oids.h>
#include <botan/hex.h>
-#if defined(BOTAN_HAS_RSA)
- #include <botan/rsa.h>
-#endif
-
-#if defined(BOTAN_HAS_DSA)
- #include <botan/dsa.h>
-#endif
-
-#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
- #include <botan/dh.h>
-#endif
-
-#if defined(BOTAN_HAS_NYBERG_RUEPPEL)
- #include <botan/nr.h>
-#endif
-
-#if defined(BOTAN_HAS_RW)
- #include <botan/rw.h>
-#endif
-
-#if defined(BOTAN_HAS_ELGAMAL)
- #include <botan/elgamal.h>
-#endif
-
-#if defined(BOTAN_HAS_ECDSA)
- #include <botan/ecdsa.h>
-#endif
-
-#if defined(BOTAN_HAS_ECDH)
- #include <botan/ecdh.h>
-#endif
-
-#if defined(BOTAN_HAS_GOST_34_10_2001)
- #include <botan/gost_3410.h>
-#endif
-
-#if defined(BOTAN_HAS_DLIES)
- #include <botan/dlies.h>
- #include <botan/kdf.h>
-#endif
-
-#include <botan/numthry.h>
-
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-void dump_data(const std::vector<byte>& out,
- const std::vector<byte>& expected)
+std::vector<std::string> possible_pk_providers()
{
- std::cout << "Got: " << hex_encode(out) << std::endl;
- std::cout << "Exp: " << hex_encode(expected) << std::endl;
+ return { "base", "openssl", "tpm" };
}
-size_t validate_save_and_load(const Private_Key* priv_key,
- RandomNumberGenerator& rng)
+}
+
+void check_invalid_signatures(Test::Result& result,
+ Botan::PK_Verifier& verifier,
+ const std::vector<uint8_t>& message,
+ const std::vector<uint8_t>& signature)
{
- std::string name = priv_key->algo_name();
+ const std::vector<uint8_t> zero_sig(signature.size());
+ result.test_eq("all zero signature invalid", verifier.verify_message(message, zero_sig), false);
- size_t fails = 0;
- std::string pub_pem = X509::PEM_encode(*priv_key);
+ std::vector<uint8_t> bad_sig = signature;
- try
+ for(size_t i = 0; i <= Test::soak_level(); ++i)
{
- DataSource_Memory input_pub(pub_pem);
- std::unique_ptr<Public_Key> restored_pub(X509::load_key(input_pub));
+ while(bad_sig == signature)
+ bad_sig = Test::mutate_vec(bad_sig, true);
- if(!restored_pub.get())
- {
- std::cout << "Could not recover " << name << " public key" << std::endl;
- ++fails;
- }
- else if(restored_pub->check_key(rng, true) == false)
+ if(!result.test_eq("incorrect signature invalid", verifier.verify_message(message, bad_sig), false))
{
- std::cout << "Restored pubkey failed self tests " << name << std::endl;
- ++fails;
+ result.test_note("Accepted invalid signature " + Botan::hex_encode(bad_sig));
}
}
- catch(std::exception& e)
- {
- std::cout << "Exception during load of " << name
- << " key: " << e.what() << std::endl;
- std::cout << "PEM for pubkey was:\n" << pub_pem << std::endl;
- ++fails;
- }
+ }
- std::string priv_pem = PKCS8::PEM_encode(*priv_key);
+void check_invalid_ciphertexts(Test::Result& result,
+ Botan::PK_Decryptor& decryptor,
+ const std::vector<uint8_t>& plaintext,
+ const std::vector<uint8_t>& ciphertext)
+ {
+ std::vector<uint8_t> bad_ctext = ciphertext;
- try
+ size_t ciphertext_accepted = 0, ciphertext_rejected = 0;
+
+ for(size_t i = 0; i <= Test::soak_level(); ++i)
{
- DataSource_Memory input_priv(priv_pem);
- std::unique_ptr<Private_Key> restored_priv(
- PKCS8::load_key(input_priv, rng));
+ while(bad_ctext == ciphertext)
+ bad_ctext = Test::mutate_vec(bad_ctext, true);
- if(!restored_priv.get())
+ try
{
- std::cout << "Could not recover " << name << " privlic key" << std::endl;
- ++fails;
+ const Botan::secure_vector<uint8_t> decrypted = decryptor.decrypt(bad_ctext);
+ ++ciphertext_accepted;
+
+ if(!result.test_ne("incorrect ciphertext different", decrypted, plaintext))
+ {
+ result.test_eq("used corrupted ciphertext", bad_ctext, ciphertext);
+ }
}
- else if(restored_priv->check_key(rng, true) == false)
+ catch(std::exception& e)
{
- std::cout << "Restored privkey failed self tests " << name << std::endl;
- ++fails;
+ ++ciphertext_rejected;
}
}
- catch(std::exception& e)
- {
- std::cout << "Exception during load of " << name
- << " key: " << e.what() << std::endl;
- std::cout << "PEM for privkey was:\n" << priv_pem << std::endl;
- ++fails;
- }
- return fails;
+ result.test_note("Accepted " + std::to_string(ciphertext_accepted) +
+ " invalid ciphertexts, rejected " + std::to_string(ciphertext_rejected));
}
-byte nonzero_byte(RandomNumberGenerator& rng)
+Test::Result
+PK_Signature_Generation_Test::run_one_test(const std::string&, const VarMap& vars)
{
- byte b = 0;
- while(b == 0)
- b = rng.next_byte();
- return b;
- }
+ const std::vector<uint8_t> message = get_req_bin(vars, "Msg");
+ const std::vector<uint8_t> signature = get_req_bin(vars, "Signature");
+ const std::string padding = get_opt_str(vars, "Padding", default_padding(vars));
-}
-
-#define PK_TEST(expr, msg) \
- do { \
- const bool test_result = expr; \
- if(!test_result) \
- { \
- std::cout << "Test " << #expr << " failed: " << msg << std::endl; \
- ++fails; \
- } \
- } while(0)
-
-size_t validate_encryption(PK_Encryptor& e, PK_Decryptor& d,
- const std::string& algo, const std::string& input,
- const std::string& random, const std::string& exp)
- {
- std::vector<byte> message = hex_decode(input);
- std::vector<byte> expected = hex_decode(exp);
- Fixed_Output_RNG kat_rng(hex_decode(random));
+ Test::Result result(algo_name() + "/" + padding + " signature generation");
- size_t fails = 0;
+ std::unique_ptr<Botan::Private_Key> privkey = load_private_key(vars);
+ std::unique_ptr<Botan::Public_Key> pubkey(Botan::X509::load_key(Botan::X509::BER_encode(*privkey)));
- const std::vector<byte> ctext = e.encrypt(message, kat_rng);
- if(ctext != expected)
+ for(auto&& sign_provider : possible_pk_providers())
{
- std::cout << "FAILED (encrypt): " << algo << std::endl;
- dump_data(ctext, expected);
- ++fails;
- }
+ std::unique_ptr<Botan::PK_Signer> signer;
- std::vector<byte> decrypted = unlock(d.decrypt(ctext));
+ try
+ {
+ signer.reset(new Botan::PK_Signer(*privkey, padding, Botan::IEEE_1363, sign_provider));
+ }
+ catch(Botan::Lookup_Error)
+ {
+ //result.test_note("Skipping signing with " + sign_provider);
+ continue;
+ }
- if(decrypted != message)
- {
- std::cout << "FAILED (decrypt): " << algo << std::endl;
- dump_data(decrypted, message);
- ++fails;
- }
+ std::unique_ptr<Botan::RandomNumberGenerator> rng;
+ if(vars.count("Nonce"))
+ {
+ rng.reset(new Fixed_Output_RNG(get_req_bin(vars, "Nonce")));
+ }
- if(algo.find("/Raw") == std::string::npos)
- {
- auto& rng = test_rng();
+ const std::vector<uint8_t> generated_signature = signer->sign_message(message, rng ? *rng : Test::rng());
- for(size_t i = 0; i != ctext.size(); ++i)
+ if(sign_provider == "base")
{
- std::vector<byte> bad_ctext = ctext;
-
- bad_ctext[i] ^= nonzero_byte(rng);
+ result.test_eq("generated signature matches KAT", generated_signature, signature);
+ }
- BOTAN_ASSERT(bad_ctext != ctext, "Made them different");
+ for(auto&& verify_provider : possible_pk_providers())
+ {
+ std::unique_ptr<Botan::PK_Verifier> verifier;
try
{
- auto bad_ptext = unlock(d.decrypt(bad_ctext));
- std::cout << algo << " failed - decrypted bad data" << std::endl;
- std::cout << hex_encode(bad_ctext) << " -> " << hex_encode(bad_ptext) << std::endl;
- std::cout << hex_encode(ctext) << " -> " << hex_encode(decrypted) << std::endl;
-
- // Ignore PKCS #1 failures as they do occur occasionally (million message attack)
- const bool is_pkcs1 = algo.find("/EME-PKCS1-v1_5") != std::string::npos;
-
- if(is_pkcs1)
- std::cout << "Ignoring PKCS #1 failure" << std::endl;
- else
- ++fails;
+ verifier.reset(new Botan::PK_Verifier(*pubkey, padding, Botan::IEEE_1363, verify_provider));
+ }
+ catch(Botan::Lookup_Error)
+ {
+ //result.test_note("Skipping verifying with " + verify_provider);
+ continue;
+ }
+
+ if(!result.test_eq("generated signature valid", verifier->verify_message(message, generated_signature), true))
+ {
+ result.test_failure("generated signature", generated_signature);
}
- catch(...) {}
+
+ check_invalid_signatures(result, *verifier, message, signature);
+ result.test_eq("KAT signature valid", verifier->verify_message(message, signature), true);
}
}
- return fails;
+ return result;
}
-size_t validate_signature(PK_Verifier& v, PK_Signer& s, const std::string& algo,
- const std::string& input,
- RandomNumberGenerator& rng,
- const std::string& exp)
+Test::Result
+PK_Signature_Verification_Test::run_one_test(const std::string&, const VarMap& vars)
{
- return validate_signature(v, s, algo, input, rng, rng, exp);
+ const std::vector<uint8_t> message = get_req_bin(vars, "Msg");
+ const std::vector<uint8_t> signature = get_req_bin(vars, "Signature");
+ const std::string padding = get_opt_str(vars, "Padding", default_padding(vars));
+ std::unique_ptr<Botan::Public_Key> pubkey = load_public_key(vars);
+
+ Test::Result result(algo_name() + "/" + padding + " signature verification");
+
+ Botan::PK_Verifier verifier(*pubkey, padding);
+
+ result.test_eq("correct signature valid", verifier.verify_message(message, signature), true);
+
+ check_invalid_signatures(result, verifier, message, signature);
+
+ return result;
}
-size_t validate_signature(PK_Verifier& v, PK_Signer& s, const std::string& algo,
- const std::string& input,
- RandomNumberGenerator& signer_rng,
- RandomNumberGenerator& test_rng,
- const std::string& exp)
+Test::Result
+PK_Encryption_Decryption_Test::run_one_test(const std::string&, const VarMap& vars)
{
- std::vector<byte> message = hex_decode(input);
- std::vector<byte> expected = hex_decode(exp);
- std::vector<byte> sig = s.sign_message(message, signer_rng);
+ const std::vector<uint8_t> plaintext = get_req_bin(vars, "Msg");
+ const std::vector<uint8_t> ciphertext = get_req_bin(vars, "Ciphertext");
- size_t fails = 0;
+ const std::string padding = get_opt_str(vars, "Padding", default_padding(vars));
- if(sig != expected)
- {
- std::cout << "FAILED (sign): " << algo << std::endl;
- dump_data(sig, expected);
- ++fails;
- }
+ Test::Result result(algo_name() + "/" + padding + " decryption");
+
+ std::unique_ptr<Botan::Private_Key> privkey = load_private_key(vars);
- PK_TEST(v.verify_message(message, sig), "Correct signature is valid");
+ // instead slice the private key to work around elgamal test inputs
+ //std::unique_ptr<Botan::Public_Key> pubkey(Botan::X509::load_key(Botan::X509::BER_encode(*privkey)));
- for(size_t i = 0; i != 5; ++i)
+ for(auto&& enc_provider : possible_pk_providers())
{
- auto bad_sig = sig;
+ std::unique_ptr<Botan::PK_Encryptor> encryptor;
- const size_t idx = (test_rng.next_byte() * 256 + test_rng.next_byte()) % sig.size();
- bad_sig[idx] ^= nonzero_byte(test_rng);
+ try
+ {
+ encryptor.reset(new Botan::PK_Encryptor_EME(*privkey, padding, enc_provider));
+ }
+ catch(Botan::Lookup_Error)
+ {
+ //result.test_note("Skipping encryption with provider " + enc_provider);
+ continue;
+ }
- PK_TEST(!v.verify_message(message, bad_sig), "Incorrect signature is invalid");
- }
+ std::unique_ptr<Botan::RandomNumberGenerator> kat_rng;
+ if(vars.count("Nonce"))
+ {
+ kat_rng.reset(new Fixed_Output_RNG(get_req_bin(vars, "Nonce")));
+ }
+
+ const std::vector<uint8_t> generated_ciphertext =
+ encryptor->encrypt(plaintext, kat_rng ? *kat_rng : Test::rng());
- zero_mem(sig.data(), sig.size());
+ if(enc_provider == "base")
+ {
+ result.test_eq("generated ciphertext matches KAT", generated_ciphertext, ciphertext);
+ }
- PK_TEST(!v.verify_message(message, sig), "All-zero signature is invalid");
+ for(auto&& dec_provider : possible_pk_providers())
+ {
+ std::unique_ptr<Botan::PK_Decryptor> decryptor;
- return fails;
- }
+ try
+ {
+ decryptor.reset(new Botan::PK_Decryptor_EME(*privkey, padding, dec_provider));
+ }
+ catch(Botan::Lookup_Error)
+ {
+ //result.test_note("Skipping decryption with provider " + dec_provider);
+ continue;
+ }
-size_t validate_signature(PK_Verifier& v, PK_Signer& s, const std::string& algo,
- const std::string& input,
- RandomNumberGenerator& rng,
- const std::string& random,
- const std::string& exp)
- {
- Fixed_Output_RNG fixed_rng(hex_decode(random));
+ result.test_eq("decryption of KAT", decryptor->decrypt(ciphertext), plaintext);
+ check_invalid_ciphertexts(result, *decryptor, plaintext, ciphertext);
+ result.test_eq("decryption of generated ciphertext",
+ decryptor->decrypt(generated_ciphertext), plaintext);
+ }
+ }
- return validate_signature(v, s, algo, input, fixed_rng, rng, exp);
+ return result;
}
-size_t validate_kas(PK_Key_Agreement& kas, const std::string& algo,
- const std::vector<byte>& pubkey, const std::string& output,
- size_t keylen)
+Test::Result PK_Key_Agreement_Test::run_one_test(const std::string&, const VarMap& vars)
{
- std::vector<byte> expected = hex_decode(output);
+ const std::vector<uint8_t> shared = get_req_bin(vars, "K");
+ const std::string kdf = get_opt_str(vars, "KDF", default_kdf(vars));
- std::vector<byte> got = unlock(kas.derive_key(keylen, pubkey).bits_of());
+ Test::Result result(algo_name() + "/" + kdf + " key agreement");
- size_t fails = 0;
+ std::unique_ptr<Botan::Private_Key> privkey = load_our_key(vars);
+ const std::vector<uint8_t> pubkey = load_their_key(vars);
- if(got != expected)
- {
- std::cout << "FAILED: " << algo << std::endl;
- dump_data(got, expected);
- ++fails;
- }
+ const size_t key_len = get_opt_sz(vars, "OutLen", 0);
+
+ Botan::PK_Key_Agreement kas(*privkey, kdf);
- return fails;
+ result.test_eq("agreement", kas.derive_key(key_len, pubkey).bits_of(), shared);
+
+ return result;
}
-size_t test_pk_keygen()
+std::vector<Test::Result> PK_Key_Generation_Test::run()
{
- auto& rng = test_rng();
+ std::vector<Test::Result> results;
+
+ for(auto&& param : keygen_params())
+ {
+ std::unique_ptr<Botan::Private_Key> key = make_key(Test::rng(), param);
- size_t tests = 0;
- size_t fails = 0;
+ const std::string report_name = key->algo_name() + (param.empty() ? param : " " + param);
-#define DL_KEY(TYPE, GROUP) \
- { \
- TYPE key(rng, DL_Group(GROUP)); \
- key.check_key(rng, true); \
- ++tests; \
- fails += validate_save_and_load(&key, rng); \
+ results.push_back(test_key(report_name, *key));
+ }
+ return results;
}
-#define EC_KEY(TYPE, GROUP) \
- { \
- TYPE key(rng, EC_Group(OIDS::lookup(GROUP))); \
- key.check_key(rng, true); \
- ++tests; \
- fails += validate_save_and_load(&key, rng); \
- }
+Test::Result
+PK_Key_Generation_Test::test_key(const std::string& algo, const Botan::Private_Key& key)
+ {
+ Test::Result result(algo + " keygen");
+
+ const std::string pub_pem = Botan::X509::PEM_encode(key);
-#if defined(BOTAN_HAS_RSA)
+ try
{
- RSA_PrivateKey rsa1024(rng, 1024);
- rsa1024.check_key(rng, true);
- ++tests;
- fails += validate_save_and_load(&rsa1024, rng);
-
- RSA_PrivateKey rsa2048(rng, 2048);
- rsa2048.check_key(rng, true);
- ++tests;
- fails += validate_save_and_load(&rsa2048, rng);
- }
-#endif
+ Botan::DataSource_Memory input_pub(pub_pem);
+ std::unique_ptr<Botan::Public_Key> restored_pub(Botan::X509::load_key(input_pub));
-#if defined(BOTAN_HAS_RW)
+ result.test_eq("recovered public key from private", restored_pub.get(), true);
+ result.test_eq("public key has same type", restored_pub->algo_name(), key.algo_name());
+ result.test_eq("public key passes checks", restored_pub->check_key(Test::rng(), false), true);
+ }
+ catch(std::exception& e)
{
- RW_PrivateKey rw1024(rng, 1024);
- rw1024.check_key(rng, true);
- ++tests;
- fails += validate_save_and_load(&rw1024, rng);
+ result.test_failure("roundtrip public key", e.what());
}
-#endif
-
-#if defined(BOTAN_HAS_DSA)
- DL_KEY(DSA_PrivateKey, "dsa/jce/1024");
- DL_KEY(DSA_PrivateKey, "dsa/botan/2048");
- DL_KEY(DSA_PrivateKey, "dsa/botan/3072");
-#endif
-#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
- DL_KEY(DH_PrivateKey, "modp/ietf/1024");
- DL_KEY(DH_PrivateKey, "modp/ietf/2048");
- DL_KEY(DH_PrivateKey, "modp/ietf/4096");
- DL_KEY(DH_PrivateKey, "dsa/jce/1024");
-#endif
-
-#if defined(BOTAN_HAS_NYBERG_RUEPPEL)
- DL_KEY(NR_PrivateKey, "dsa/jce/1024");
- DL_KEY(NR_PrivateKey, "dsa/botan/2048");
- DL_KEY(NR_PrivateKey, "dsa/botan/3072");
-#endif
+ const std::string priv_pem = Botan::PKCS8::PEM_encode(key);
-#if defined(BOTAN_HAS_ELGAMAL)
- DL_KEY(ElGamal_PrivateKey, "modp/ietf/1024");
- DL_KEY(ElGamal_PrivateKey, "dsa/jce/1024");
- DL_KEY(ElGamal_PrivateKey, "dsa/botan/2048");
- DL_KEY(ElGamal_PrivateKey, "dsa/botan/3072");
-#endif
+ try
+ {
+ Botan::DataSource_Memory input_priv(priv_pem);
+ std::unique_ptr<Botan::Private_Key> restored_priv(
+ Botan::PKCS8::load_key(input_priv, Test::rng()));
-#if defined(BOTAN_HAS_ECDSA)
- EC_KEY(ECDSA_PrivateKey, "secp112r1");
- EC_KEY(ECDSA_PrivateKey, "secp128r1");
- EC_KEY(ECDSA_PrivateKey, "secp160r1");
- EC_KEY(ECDSA_PrivateKey, "secp192r1");
- EC_KEY(ECDSA_PrivateKey, "secp224r1");
- EC_KEY(ECDSA_PrivateKey, "secp256r1");
- EC_KEY(ECDSA_PrivateKey, "secp384r1");
- EC_KEY(ECDSA_PrivateKey, "secp521r1");
-#endif
+ result.test_eq("recovered private key from blob", restored_priv.get(), true);
+ result.test_eq("reloaded key has same type", restored_priv->algo_name(), key.algo_name());
+ result.test_eq("private key passes checks", restored_priv->check_key(Test::rng(), false), true);
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure("roundtrip private key", e.what());
+ }
-#if defined(BOTAN_HAS_GOST_34_10_2001)
- EC_KEY(GOST_3410_PrivateKey, "gost_256A");
- EC_KEY(GOST_3410_PrivateKey, "secp112r1");
- EC_KEY(GOST_3410_PrivateKey, "secp128r1");
- EC_KEY(GOST_3410_PrivateKey, "secp160r1");
- EC_KEY(GOST_3410_PrivateKey, "secp192r1");
- EC_KEY(GOST_3410_PrivateKey, "secp224r1");
- EC_KEY(GOST_3410_PrivateKey, "secp256r1");
- EC_KEY(GOST_3410_PrivateKey, "secp384r1");
- EC_KEY(GOST_3410_PrivateKey, "secp521r1");
-#endif
+ const std::string passphrase = Test::random_password();
+ const std::string enc_priv_pem = Botan::PKCS8::PEM_encode(key, Test::rng(), passphrase,
+ std::chrono::milliseconds(10));
+ try
+ {
+ Botan::DataSource_Memory input_priv(priv_pem);
+ std::unique_ptr<Botan::Private_Key> restored_priv(
+ Botan::PKCS8::load_key(input_priv, Test::rng(), passphrase));
- test_report("PK keygen", tests, fails);
+ result.test_eq("recovered private key from encrypted blob", restored_priv.get(), true);
+ result.test_eq("reloaded key has same type", restored_priv->algo_name(), key.algo_name());
+ result.test_eq("private key passes checks", restored_priv->check_key(Test::rng(), false), true);
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure("roundtrip private key", e.what());
+ }
- return fails;
+ return result;
}
-#else
-
-SKIP_TEST(pk_keygen);
+}
-#endif // BOTAN_HAS_PUBLIC_KEY_CRYPTO
+#endif
diff --git a/src/tests/test_pubkey.h b/src/tests/test_pubkey.h
index e1197a61b..a5a1c2799 100644
--- a/src/tests/test_pubkey.h
+++ b/src/tests/test_pubkey.h
@@ -7,40 +7,111 @@
#ifndef BOTAN_TEST_PUBKEY_H__
#define BOTAN_TEST_PUBKEY_H__
+#include "tests.h"
+
+#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO)
+
#include <botan/pubkey.h>
-using namespace Botan;
-
-size_t validate_encryption(Botan::PK_Encryptor& e, Botan::PK_Decryptor& d,
- const std::string& algo,
- const std::string& input,
- const std::string& random,
- const std::string& expected);
-
-size_t validate_signature(PK_Verifier& v, PK_Signer& s,
- const std::string& algo,
- const std::string& input,
- RandomNumberGenerator& signer_rng,
- RandomNumberGenerator& test_rng,
- const std::string& exp);
-
-size_t validate_signature(PK_Verifier& v, PK_Signer& s,
- const std::string& algo,
- const std::string& input,
- RandomNumberGenerator& rng,
- const std::string& exp);
-
-size_t validate_signature(PK_Verifier& v, PK_Signer& s,
- const std::string& algo,
- const std::string& input,
- RandomNumberGenerator& rng,
- const std::string& random,
- const std::string& exp);
-
-size_t validate_kas(PK_Key_Agreement& kas,
- const std::string& algo,
- const std::vector<byte>& pubkey,
- const std::string& output,
- size_t keylen);
+namespace Botan_Tests {
+
+class PK_Signature_Generation_Test : public Text_Based_Test
+ {
+ public:
+ PK_Signature_Generation_Test(const std::string& algo,
+ const std::string& test_src,
+ const std::vector<std::string>& required_keys,
+ const std::vector<std::string>& optional_keys = {}) :
+ Text_Based_Test(algo, test_src, required_keys, optional_keys) {}
+
+ virtual std::string default_padding(const VarMap&) const
+ {
+ throw std::runtime_error("No default padding scheme set for " + algo_name());
+ }
+
+ virtual std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) = 0;
+ private:
+ Test::Result run_one_test(const std::string&, const VarMap& vars) override;
+ };
+
+class PK_Signature_Verification_Test : public Text_Based_Test
+ {
+ public:
+ PK_Signature_Verification_Test(const std::string& algo,
+ const std::string& test_src,
+ const std::vector<std::string>& required_keys,
+ const std::vector<std::string>& optional_keys = {}) :
+ Text_Based_Test(algo, test_src, required_keys, optional_keys) {}
+
+ virtual std::string default_padding(const VarMap&) const
+ {
+ throw std::runtime_error("No default padding scheme set for " + algo_name());
+ }
+
+ virtual std::unique_ptr<Botan::Public_Key> load_public_key(const VarMap& vars) = 0;
+ private:
+ Test::Result run_one_test(const std::string& header, const VarMap& vars) override;
+ };
+
+class PK_Encryption_Decryption_Test : public Text_Based_Test
+ {
+ public:
+ PK_Encryption_Decryption_Test(const std::string& algo,
+ const std::string& test_src,
+ const std::vector<std::string>& required_keys,
+ const std::vector<std::string>& optional_keys = {}) :
+ Text_Based_Test(algo, test_src, required_keys, optional_keys) {}
+
+ virtual std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) = 0;
+
+ virtual std::string default_padding(const VarMap&) const { return "Raw"; }
+ private:
+ Test::Result run_one_test(const std::string& header, const VarMap& vars) override;
+};
+
+class PK_Key_Agreement_Test : public Text_Based_Test
+ {
+ public:
+ PK_Key_Agreement_Test(const std::string& algo,
+ const std::string& test_src,
+ const std::vector<std::string>& required_keys,
+ const std::vector<std::string>& optional_keys = {}) :
+ Text_Based_Test(algo, test_src, required_keys, optional_keys) {}
+
+ virtual std::unique_ptr<Botan::Private_Key> load_our_key(const VarMap& vars) = 0;
+ virtual std::vector<uint8_t> load_their_key(const VarMap& vars) = 0;
+
+ virtual std::string default_kdf(const VarMap&) const { return "Raw"; }
+
+ private:
+ Test::Result run_one_test(const std::string& header, const VarMap& vars) override;
+ };
+
+class PK_Key_Generation_Test : public Test
+ {
+ protected:
+ std::vector<Test::Result> run() override;
+
+ virtual std::vector<std::string> keygen_params() const = 0;
+
+ virtual std::unique_ptr<Botan::Private_Key> make_key(Botan::RandomNumberGenerator& rng,
+ const std::string& param) const = 0;
+ private:
+ Test::Result test_key(const std::string& algo, const Botan::Private_Key& key);
+ };
+
+void check_invalid_signatures(Test::Result& result,
+ Botan::PK_Verifier& verifier,
+ const std::vector<uint8_t>& message,
+ const std::vector<uint8_t>& signature);
+
+void check_invalid_ciphertexts(Test::Result& result,
+ Botan::PK_Decryptor& decryptor,
+ const std::vector<uint8_t>& plaintext,
+ const std::vector<uint8_t>& ciphertext);
+
+}
+
+#endif
#endif
diff --git a/src/tests/test_rfc6979.cpp b/src/tests/test_rfc6979.cpp
index 772a492c3..59d44f5b9 100644
--- a/src/tests/test_rfc6979.cpp
+++ b/src/tests/test_rfc6979.cpp
@@ -11,95 +11,42 @@
#include <botan/hex.h>
#endif
-#include <iostream>
+namespace Botan_Tests {
namespace {
-size_t rfc6979_testcase(const std::string& q_str,
- const std::string& x_str,
- const std::string& h_str,
- const std::string& exp_k_str,
- const std::string& hash,
- size_t testcase)
- {
- size_t fails = 0;
-
#if defined(BOTAN_HAS_RFC6979_GENERATOR)
- using namespace Botan;
-
- const BigInt q(q_str);
- const BigInt x(x_str);
- const BigInt h(h_str);
- const BigInt exp_k(exp_k_str);
+class RFC6979_KAT_Tests : public Text_Based_Test
+ {
+ public:
+ RFC6979_KAT_Tests() : Text_Based_Test(Test::data_file("rfc6979.vec"),
+ {"Q", "X", "H", "K"}) {}
- const BigInt gen_k = generate_rfc6979_nonce(x, q, h, hash);
+ Test::Result run_one_test(const std::string& hash, const VarMap& vars)
+ {
+ const BigInt Q = get_req_bn(vars, "Q");
+ const BigInt X = get_req_bn(vars, "X");
+ const BigInt H = get_req_bn(vars, "H");
+ const BigInt K = get_req_bn(vars, "K");
- if(gen_k != exp_k)
- {
- std::cout << "RFC 6979 test #" << testcase << " failed; generated k="
- << std::hex << gen_k << std::endl;
- ++fails;
- }
+ Test::Result result("RFC 6979 nonce generation");
+ result.test_eq("vector matches", Botan::generate_rfc6979_nonce(X, Q, H, hash), K);
- RFC6979_Nonce_Generator gen(hash, q, x);
+ Botan::RFC6979_Nonce_Generator gen(hash, Q, X);
- const BigInt gen_0 = gen.nonce_for(h);
- if(gen_0 != exp_k)
- {
- std::cout << "RFC 6979 test #" << testcase << " failed; generated k="
- << std::hex << gen_0 << " (gen_0)" << std::endl;
- ++fails;
- }
+ result.test_eq("vector matches", gen.nonce_for(H), K);
+ result.test_ne("vector matches", gen.nonce_for(H+1), K);
+ result.test_eq("vector matches", gen.nonce_for(H), K);
- const BigInt gen_1 = gen.nonce_for(h+1);
- if(gen_1 == exp_k)
- {
- std::cout << "RFC 6979 test #" << testcase << " failed; generated k="
- << std::hex << gen_1 << " (gen_1)" << std::endl;
- ++fails;
- }
+ return result;
+ }
+ };
- const BigInt gen_2 = gen.nonce_for(h);
- if(gen_2 != exp_k)
- {
- std::cout << "RFC 6979 test #" << testcase << " failed; generated k="
- << std::hex << gen_2 << " (gen_2)" << std::endl;
- ++fails;
- }
+BOTAN_REGISTER_TEST("rfc6979", RFC6979_KAT_Tests);
#endif
- return fails;
- }
-
}
-size_t test_rfc6979()
- {
- using namespace Botan;
-
- size_t fails = 0;
-
-#if defined(BOTAN_HAS_RFC6979_GENERATOR)
-
- // From RFC 6979 A.1.1
- fails += rfc6979_testcase("0x4000000000000000000020108A2E0CC0D99F8A5EF",
- "0x09A4D6792295A7F730FC3F2B49CBC0F62E862272F",
- "0x01795EDF0D54DB760F156D0DAC04C0322B3A204224",
- "0x23AF4074C90A02B3FE61D286D5C87F425E6BDD81B",
- "SHA-256", 1);
-
- // DSA 1024 bits test #1
- fails += rfc6979_testcase("0x996F967F6C8E388D9E28D01E205FBA957A5698B1",
- "0x411602CB19A6CCC34494D79D98EF1E7ED5AF25F7",
- "0x8151325DCDBAE9E0FF95F9F9658432DBEDFDB209",
- "0x7BDB6B0FF756E1BB5D53583EF979082F9AD5BD5B",
- "SHA-1", 2);
-
-#endif
-
- test_report("RFC 6979", 2, fails);
-
- return fails;
- }
+}
diff --git a/src/tests/test_rng.cpp b/src/tests/test_rng.cpp
index 2eb8328ee..626fe85b5 100644
--- a/src/tests/test_rng.cpp
+++ b/src/tests/test_rng.cpp
@@ -4,12 +4,8 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
-#include "test_rng.h"
#include "tests.h"
-
-#include <botan/hex.h>
-#include <iostream>
-#include <fstream>
+#include "test_rng.h"
#if defined(BOTAN_HAS_HMAC_DRBG)
#include <botan/hmac_drbg.h>
@@ -19,11 +15,11 @@
#include <botan/x931_rng.h>
#endif
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-RandomNumberGenerator* get_rng(const std::string& algo_str, const std::string& ikm_hex)
+Botan::RandomNumberGenerator* get_rng(const std::string& algo_str, const std::vector<byte>& ikm)
{
class AllOnce_RNG : public Fixed_Output_RNG
{
@@ -38,102 +34,95 @@ RandomNumberGenerator* get_rng(const std::string& algo_str, const std::string& i
}
};
- const auto ikm = hex_decode(ikm_hex);
-
- const auto algo_name = parse_algorithm_name(algo_str);
+ const std::vector<std::string> algo_name = Botan::parse_algorithm_name(algo_str);
const std::string rng_name = algo_name[0];
#if defined(BOTAN_HAS_HMAC_DRBG)
if(rng_name == "HMAC_DRBG")
- return new HMAC_DRBG(MessageAuthenticationCode::create("HMAC(" + algo_name[1] + ")").release(),
- new AllOnce_RNG(ikm));
+ return new Botan::HMAC_DRBG(
+ Botan::MessageAuthenticationCode::create("HMAC(" + algo_name[1] + ")").release(),
+ new AllOnce_RNG(ikm));
#endif
#if defined(BOTAN_HAS_X931_RNG)
if(rng_name == "X9.31-RNG")
- return new ANSI_X931_RNG(BlockCipher::create(algo_name[1]).release(),
- new Fixed_Output_RNG(ikm));
+ return new Botan::ANSI_X931_RNG(Botan::BlockCipher::create(algo_name[1]).release(),
+ new Fixed_Output_RNG(ikm));
#endif
return nullptr;
}
-size_t x931_test(const std::string& algo,
- const std::string& ikm,
- const std::string& out,
- size_t L)
+#if defined(BOTAN_HAS_X931_RNG)
+class X931_RNG_Tests : public Text_Based_Test
{
- std::unique_ptr<RandomNumberGenerator> rng(get_rng(algo, ikm));
+ public:
+ X931_RNG_Tests() : Text_Based_Test(Test::data_file("x931.vec"), {"IKM", "L", "Out"}) {}
- if(!rng)
- {
- std::cout << "Unknown RNG " + algo + " skipping test\n";
- return 0;
- }
+ Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
+ {
+ const std::vector<uint8_t> ikm = get_req_bin(vars, "IKM");
+ const std::vector<uint8_t> expected = get_req_bin(vars, "Out");
- const std::string got = hex_encode(rng->random_vec(L));
+ const size_t L = get_req_sz(vars, "L");
- if(got != out)
- {
- std::cout << "X9.31 " << got << " != " << out << std::endl;
- return 1;
- }
+ Test::Result result(algo);
- return 0;
- }
+ result.test_eq("length", L, expected.size());
-size_t hmac_drbg_test(std::map<std::string, std::string> m)
- {
- const std::string algo = m["RNG"];
- const std::string ikm = m["EntropyInput"];
+ std::unique_ptr<Botan::RandomNumberGenerator> rng(get_rng(algo, ikm));
- std::unique_ptr<RandomNumberGenerator> rng(get_rng(algo, ikm));
- if(!rng)
- {
- std::cout << "Unknown RNG " + algo + " skipping test\n";
- return 0;
- }
+ result.test_eq("rng", rng->random_vec(L), expected);
+
+ return result;
+ }
+
+ };
+
+BOTAN_REGISTER_TEST("x931_rng", X931_RNG_Tests);
+#endif
- rng->reseed(0); // force initialization
+#if defined(BOTAN_HAS_HMAC_DRBG)
- // now reseed
- const auto reseed_input = hex_decode(m["EntropyInputReseed"]);
- rng->add_entropy(reseed_input.data(), reseed_input.size());
+class HMAC_DRBG_Tests : public Text_Based_Test
+ {
+ public:
+ HMAC_DRBG_Tests() : Text_Based_Test(Test::data_file("hmac_drbg.vec"),
+ {"EntropyInput", "EntropyInputReseed", "Out"}) {}
- const std::string out = m["Out"];
+ Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
+ {
+ const std::vector<byte> seed_input = get_req_bin(vars, "EntropyInput");
+ const std::vector<byte> reseed_input = get_req_bin(vars, "EntropyInputReseed");
+ const std::vector<byte> expected = get_req_bin(vars, "Out");
- const size_t out_len = out.size() / 2;
+ Test::Result result(algo);
- rng->random_vec(out_len); // gen 1st block (discarded)
+ std::unique_ptr<Botan::RandomNumberGenerator> rng(get_rng(algo, seed_input));
+ if(!rng)
+ {
+ result.note_missing("RNG " + algo);
+ return result;
+ }
- const std::string got = hex_encode(rng->random_vec(out_len));
+ rng->reseed(0); // force initialization
- if(got != out)
- {
- std::cout << algo << " " << got << " != " << out << std::endl;
- return 1;
- }
+ // now reseed
+ rng->add_entropy(reseed_input.data(), reseed_input.size());
- return 0;
- }
+ rng->random_vec(expected.size()); // discard 1st block
-}
+ result.test_eq("rng", rng->random_vec(expected.size()), expected);
+ return result;
+ }
-size_t test_rngs()
- {
- std::ifstream hmac_drbg_vec(TEST_DATA_DIR "/hmac_drbg.vec");
- std::ifstream x931_vec(TEST_DATA_DIR "/x931.vec");
+ };
- size_t fails = 0;
+BOTAN_REGISTER_TEST("hmac_drbg", HMAC_DRBG_Tests);
- fails += run_tests_bb(hmac_drbg_vec, "RNG", "Out", true, hmac_drbg_test);
+#endif
- fails += run_tests_bb(x931_vec, "RNG", "Out", true,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return x931_test(m["RNG"], m["IKM"], m["Out"], to_u32bit(m["L"]));
- });
+}
- return fails;
- }
+}
diff --git a/src/tests/test_rsa.cpp b/src/tests/test_rsa.cpp
index dcc741bd2..5a9a14945 100644
--- a/src/tests/test_rsa.cpp
+++ b/src/tests/test_rsa.cpp
@@ -7,122 +7,103 @@
#include "tests.h"
#if defined(BOTAN_HAS_RSA)
+ #include <botan/rsa.h>
+ #include "test_pubkey.h"
+#endif
-#include "test_pubkey.h"
-
-#include <botan/pubkey.h>
-#include <botan/rsa.h>
-#include <botan/hex.h>
-#include <iostream>
-#include <fstream>
-
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-size_t rsaes_kat(const std::string& e,
- const std::string& p,
- const std::string& q,
- const std::string& msg,
- std::string padding,
- const std::string& nonce,
- const std::string& output)
- {
- auto& rng = test_rng();
-
- RSA_PrivateKey privkey(rng, BigInt(p), BigInt(q), BigInt(e));
-
- RSA_PublicKey pubkey = privkey;
-
- if(padding == "")
- padding = "Raw";
-
- PK_Encryptor_EME enc(pubkey, padding, "base");
- PK_Decryptor_EME dec(privkey, padding);
-
- return validate_encryption(enc, dec, "RSAES/" + padding, msg, nonce, output);
- }
+#if defined(BOTAN_HAS_RSA)
-size_t rsa_sig_kat(const std::string& e,
- const std::string& p,
- const std::string& q,
- const std::string& msg,
- std::string padding,
- const std::string& nonce,
- const std::string& output)
+class RSA_ES_KAT_Tests : public PK_Encryption_Decryption_Test
{
- auto& rng = test_rng();
-
- RSA_PrivateKey privkey(rng, BigInt(p), BigInt(q), BigInt(e));
-
- RSA_PublicKey pubkey = privkey;
-
- if(padding == "")
- padding = "Raw";
-
- PK_Verifier verify(pubkey, padding);
- PK_Signer sign(privkey, padding, IEEE_1363, "base");
-
- return validate_signature(verify, sign, "RSA/" + padding, msg, rng, nonce, output);
- }
-
-size_t rsa_sig_verify(const std::string& e,
- const std::string& n,
- const std::string& msg,
- std::string padding,
- const std::string& signature)
+ public:
+ RSA_ES_KAT_Tests() : PK_Encryption_Decryption_Test(
+ "RSA",
+ Test::data_file("pubkey/rsaes.vec"),
+ {"E", "P", "Q", "Msg", "Ciphertext"},
+ {"Padding", "Nonce"})
+ {}
+
+ std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override
+ {
+ const BigInt p = get_req_bn(vars, "P");
+ const BigInt q = get_req_bn(vars, "Q");
+ const BigInt e = get_req_bn(vars, "E");
+
+ std::unique_ptr<Botan::Private_Key> key(new Botan::RSA_PrivateKey(Test::rng(), p, q, e));
+ return key;
+ }
+ };
+
+class RSA_Signature_KAT_Tests : public PK_Signature_Generation_Test
{
- BigInt e_bn(e);
- BigInt n_bn(n);
-
- RSA_PublicKey key(n_bn, e_bn);
-
- if(padding == "")
- padding = "Raw";
-
- PK_Verifier verify(key, padding);
-
- if(!verify.verify_message(hex_decode(msg), hex_decode(signature)))
- return 1;
- return 0;
- }
-
-}
-
-size_t test_rsa()
+ public:
+ RSA_Signature_KAT_Tests() : PK_Signature_Generation_Test(
+ "RSA",
+ Test::data_file("pubkey/rsa_sig.vec"),
+ {"E", "P", "Q", "Msg", "Signature"},
+ {"Padding", "Nonce"})
+ {}
+
+ std::string default_padding(const VarMap&) const override { return "Raw"; }
+
+ std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override
+ {
+ const BigInt p = get_req_bn(vars, "P");
+ const BigInt q = get_req_bn(vars, "Q");
+ const BigInt e = get_req_bn(vars, "E");
+
+ std::unique_ptr<Botan::Private_Key> key(new Botan::RSA_PrivateKey(Test::rng(), p, q, e));
+ return key;
+ }
+ };
+
+class RSA_Signature_Verify_Tests : public PK_Signature_Verification_Test
{
- std::ifstream rsa_enc(TEST_DATA_DIR_PK "/rsaes.vec");
- std::ifstream rsa_sig(TEST_DATA_DIR_PK "/rsa_sig.vec");
- std::ifstream rsa_verify(TEST_DATA_DIR_PK "/rsa_verify.vec");
-
- size_t fails = 0;
-
- fails += run_tests_bb(rsa_enc, "RSA Encryption", "Ciphertext", true,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return rsaes_kat(m["E"], m["P"], m["Q"], m["Msg"],
- m["Padding"], m["Nonce"], m["Ciphertext"]);
- });
-
- fails += run_tests_bb(rsa_sig, "RSA Signature", "Signature", true,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return rsa_sig_kat(m["E"], m["P"], m["Q"], m["Msg"],
- m["Padding"], m["Nonce"], m["Signature"]);
- });
+ public:
+ RSA_Signature_Verify_Tests() : PK_Signature_Verification_Test(
+ "RSA",
+ Test::data_file("pubkey/rsa_verify.vec"),
+ {"E", "N", "Msg", "Signature"},
+ {"Padding"})
+ {}
+
+ std::string default_padding(const VarMap&) const override { return "Raw"; }
+
+ std::unique_ptr<Botan::Public_Key> load_public_key(const VarMap& vars) override
+ {
+ const BigInt n = get_req_bn(vars, "N");
+ const BigInt e = get_req_bn(vars, "E");
+
+ std::unique_ptr<Botan::Public_Key> key(new Botan::RSA_PublicKey(n, e));
+ return key;
+ }
+ };
+
+class RSA_Keygen_Tests : public PK_Key_Generation_Test
+ {
+ public:
+ std::vector<std::string> keygen_params() const override { return { "1024", "1280" }; }
- fails += run_tests_bb(rsa_verify, "RSA Verify", "Signature", true,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return rsa_sig_verify(m["E"], m["N"], m["Msg"],
- m["Padding"], m["Signature"]);
- });
+ std::unique_ptr<Botan::Private_Key> make_key(Botan::RandomNumberGenerator& rng,
+ const std::string& param) const override
+ {
+ size_t bits = Botan::to_u32bit(param);
+ std::unique_ptr<Botan::Private_Key> key(new Botan::RSA_PrivateKey(rng, bits));
+ return key;
+ }
+ };
- return fails;
- }
+BOTAN_REGISTER_TEST("rsa_encrypt", RSA_ES_KAT_Tests);
+BOTAN_REGISTER_TEST("rsa_sign", RSA_Signature_KAT_Tests);
+BOTAN_REGISTER_TEST("rsa_verify", RSA_Signature_Verify_Tests);
+BOTAN_REGISTER_TEST("rsa_keygen", RSA_Keygen_Tests);
-#else
+#endif
-SKIP_TEST(rsa);
+}
-#endif // BOTAN_HAS_RSA
+}
diff --git a/src/tests/test_rw.cpp b/src/tests/test_rw.cpp
index 286bcacdf..47cb11706 100644
--- a/src/tests/test_rw.cpp
+++ b/src/tests/test_rw.cpp
@@ -7,82 +7,68 @@
#include "tests.h"
#if defined(BOTAN_HAS_RW)
+ #include <botan/rw.h>
+ #include <botan/pubkey.h>
+ #include "test_pubkey.h"
+#endif
-#include "test_pubkey.h"
-
-#include <botan/hex.h>
-#include <iostream>
-#include <fstream>
-#include <botan/pubkey.h>
-#include <botan/rw.h>
-
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-const std::string padding = "EMSA2(SHA-1)";
+#if defined(BOTAN_HAS_RW)
-size_t rw_sig_kat(const std::string& e,
- const std::string& p,
- const std::string& q,
- const std::string& msg,
- const std::string& signature)
+class RW_KAT_Tests : public PK_Signature_Generation_Test
{
- auto& rng = test_rng();
+ public:
+ RW_KAT_Tests() : PK_Signature_Generation_Test(
+ "Rabin-Williams",
+ Test::data_file("pubkey/rw_sig.vec"),
+ {"E", "P", "Q", "Msg", "Signature"},
+ {"Padding"})
+ {}
- RW_PrivateKey privkey(rng, BigInt(p), BigInt(q), BigInt(e));
+ std::string default_padding(const VarMap&) const override { return "EMSA2(SHA-1)"; }
- RW_PublicKey pubkey = privkey;
+ std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override
+ {
+ const BigInt p = get_req_bn(vars, "P");
+ const BigInt q = get_req_bn(vars, "Q");
+ const BigInt e = get_req_bn(vars, "E");
- PK_Verifier verify(pubkey, padding);
- PK_Signer sign(privkey, padding);
+ std::unique_ptr<Botan::Private_Key> key(new Botan::RW_PrivateKey(Test::rng(), p, q, e));
+ return key;
+ }
- return validate_signature(verify, sign, "RW/" + padding, msg, rng, signature);
- }
+ };
-size_t rw_sig_verify(const std::string& e,
- const std::string& n,
- const std::string& msg,
- const std::string& signature)
+class RW_Verify_Tests : public PK_Signature_Verification_Test
{
- BigInt e_bn(e);
- BigInt n_bn(n);
+ public:
+ RW_Verify_Tests() : PK_Signature_Verification_Test(
+ "Rabin-Williams",
+ Test::data_file("pubkey/rw_verify.vec"),
+ {"E", "N", "Msg", "Signature"})
+ {}
- RW_PublicKey key(n_bn, e_bn);
+ std::string default_padding(const VarMap&) const override { return "EMSA2(SHA-1)"; }
- PK_Verifier verify(key, padding);
+ std::unique_ptr<Botan::Public_Key> load_public_key(const VarMap& vars) override
+ {
+ const BigInt n = get_req_bn(vars, "N");
+ const BigInt e = get_req_bn(vars, "E");
- if(!verify.verify_message(hex_decode(msg), hex_decode(signature)))
- return 1;
- return 0;
- }
+ std::unique_ptr<Botan::Public_Key> key(new Botan::RW_PublicKey(n, e));
+ return key;
+ }
-}
-
-size_t test_rw()
- {
- size_t fails = 0;
+ };
- std::ifstream rw_sig(TEST_DATA_DIR_PK "/rw_sig.vec");
- std::ifstream rw_verify(TEST_DATA_DIR_PK "/rw_verify.vec");
+BOTAN_REGISTER_TEST("rw_kat", RW_KAT_Tests);
+BOTAN_REGISTER_TEST("rw_verify", RW_Verify_Tests);
- fails += run_tests_bb(rw_sig, "RW Signature", "Signature", true,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return rw_sig_kat(m["E"], m["P"], m["Q"], m["Msg"], m["Signature"]);
- });
+#endif
- fails += run_tests_bb(rw_verify, "RW Verify", "Signature", true,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return rw_sig_verify(m["E"], m["N"], m["Msg"], m["Signature"]);
- });
-
- return fails;
- }
-
-#else
-
-SKIP_TEST(rw);
+}
-#endif // BOTAN_HAS_RW
+}
diff --git a/src/tests/test_srp6.cpp b/src/tests/test_srp6.cpp
index dd05d02a5..f03c1edf5 100644
--- a/src/tests/test_srp6.cpp
+++ b/src/tests/test_srp6.cpp
@@ -1,48 +1,55 @@
+/*
+* (C) 2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
#include "tests.h"
#if defined(BOTAN_HAS_SRP6)
+ #include <botan/srp6.h>
+#endif
-#include <botan/srp6.h>
-#include <iostream>
-
-size_t test_srp6()
- {
- using namespace Botan;
-
- size_t fails = 0;
+namespace Botan_Tests {
- const std::string username = "user";
- const std::string password = "Awellchosen1_to_be_sure_";
- const std::string group_id = "modp/srp/1024";
- const std::string hash_id = "SHA-256";
- auto& rng = test_rng();
+namespace {
- const auto salt = unlock(rng.random_vec(16));
+#if defined(BOTAN_HAS_SRP6)
+class SRP6_Unit_Tests : public Test
+ {
+ public:
+ std::vector<Test::Result> run() override
+ {
+ std::vector<Test::Result> results;
+ Test::Result result("SRP6");
- const BigInt verifier = generate_srp6_verifier(username, password, salt, group_id, hash_id);
+ const std::string username = "user";
+ const std::string password = "Awellchosen1_to_be_sure_";
+ const std::string group_id = "modp/srp/1024";
+ const std::string hash_id = "SHA-256";
- SRP6_Server_Session server;
+ const std::vector<byte> salt = unlock(Test::rng().random_vec(16));
- const BigInt B = server.step1(verifier, group_id, hash_id, rng);
+ const Botan::BigInt verifier = Botan::generate_srp6_verifier(username, password, salt, group_id, hash_id);
- auto client = srp6_client_agree(username, password, group_id, hash_id, salt, B, rng);
+ Botan::SRP6_Server_Session server;
- const SymmetricKey server_K = server.step2(client.first);
+ const Botan::BigInt B = server.step1(verifier, group_id, hash_id, Test::rng());
- if(client.second != server_K)
- {
- std::cout << "SRP6 computed different keys" << std::endl;
- ++fails;
- }
+ auto client = srp6_client_agree(username, password, group_id, hash_id, salt, B, Test::rng());
- test_report("SRP6", 1, fails);
+ const Botan::SymmetricKey server_K = server.step2(client.first);
- return fails;
+ result.test_eq("computed same keys", client.second.bits_of(), server_K.bits_of());
+ results.push_back(result);
- }
+ return results;
+ }
+ };
-#else
+BOTAN_REGISTER_TEST("srp6", SRP6_Unit_Tests);
+#endif
-SKIP_TEST(srp6);
+}
-#endif // BOTAN_HAS_SRP6
+}
diff --git a/src/tests/test_stream.cpp b/src/tests/test_stream.cpp
index d91d28d9b..ed86b3d84 100644
--- a/src/tests/test_stream.cpp
+++ b/src/tests/test_stream.cpp
@@ -7,86 +7,63 @@
#include "tests.h"
#if defined(BOTAN_HAS_STREAM_CIPHER)
-
#include <botan/stream_cipher.h>
-#include <botan/hex.h>
-#include <iostream>
-#include <fstream>
+#endif
-using namespace Botan;
+namespace Botan_Tests {
-namespace {
+#if defined(BOTAN_HAS_STREAM_CIPHER)
-size_t stream_test(const std::string& algo,
- const std::string& key_hex,
- const std::string& in_hex,
- const std::string& out_hex,
- const std::string& nonce_hex)
+class Stream_Cipher_Tests : public Text_Based_Test
{
- const secure_vector<byte> key = hex_decode_locked(key_hex);
- const secure_vector<byte> pt = hex_decode_locked(in_hex);
- const secure_vector<byte> ct = hex_decode_locked(out_hex);
- const secure_vector<byte> nonce = hex_decode_locked(nonce_hex);
-
- const std::vector<std::string> providers = StreamCipher::providers(algo);
- size_t fails = 0;
+ public:
+ Stream_Cipher_Tests(): Text_Based_Test(Test::data_dir("stream"), {"Key", "In", "Out"}, {"Nonce"}) {}
- if(providers.empty())
- {
- std::cout << "Unknown stream cipher " << algo << std::endl;
- return 0;
- }
-
- for(auto provider: providers)
- {
- std::unique_ptr<StreamCipher> cipher(StreamCipher::create(algo, provider));
-
- if(!cipher)
+ Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
{
- std::cout << "Unable to get " << algo << " from " << provider << std::endl;
- ++fails;
- continue;
- }
+ const std::vector<uint8_t> key = get_req_bin(vars, "Key");
+ const std::vector<uint8_t> input = get_req_bin(vars, "In");
+ const std::vector<uint8_t> expected = get_req_bin(vars, "Out");
+ const std::vector<uint8_t> nonce = get_opt_bin(vars, "Nonce");
- cipher->set_key(key);
+ Test::Result result(algo);
- if(nonce.size())
- cipher->set_iv(nonce.data(), nonce.size());
+ const std::vector<std::string> providers = Botan::StreamCipher::providers(algo);
- secure_vector<byte> buf = pt;
+ if(providers.empty())
+ {
+ result.note_missing("block cipher " + algo);
+ return result;
+ }
- cipher->encrypt(buf);
+ for(auto&& provider: providers)
+ {
+ std::unique_ptr<Botan::StreamCipher> cipher(Botan::StreamCipher::create(algo, provider));
- if(buf != ct)
- {
- std::cout << algo << " " << provider << " enc " << hex_encode(buf) << " != " << out_hex << std::endl;
- ++fails;
- }
- }
+ if(!cipher)
+ {
+ result.note_missing(algo + " from " + provider);
+ continue;
+ }
- return fails;
- }
+ result.test_eq(provider.c_str(), cipher->name(), algo);
+ cipher->set_key(key);
-}
+ if(nonce.size())
+ cipher->set_iv(nonce.data(), nonce.size());
-size_t test_stream()
- {
- auto test = [](const std::string& input)
- {
- std::ifstream vec(input);
+ std::vector<uint8_t> buf = input;
+ cipher->encrypt(buf);
- return run_tests_bb(vec, "StreamCipher", "Out", true,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return stream_test(m["StreamCipher"], m["Key"], m["In"], m["Out"], m["Nonce"]);
- });
- };
+ result.test_eq(provider, "encrypt", buf, expected);
+ }
- return run_tests_in_dir(TEST_DATA_DIR "/stream", test);
- }
+ return result;
+ }
+ };
-#else
+BOTAN_REGISTER_TEST("stream", Stream_Cipher_Tests);
-SKIP_TEST(stream);
+#endif
-#endif // BOTAN_HAS_STREAM_CIPHER
+}
diff --git a/src/tests/test_transform.cpp b/src/tests/test_transform.cpp
deleted file mode 100644
index a4a26b0a7..000000000
--- a/src/tests/test_transform.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-* (C) 2014,2015 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include "tests.h"
-
-#include <botan/transform.h>
-#include <botan/hex.h>
-#include <iostream>
-#include <fstream>
-
-using namespace Botan;
-
-namespace {
-
-secure_vector<byte> transform_test(const std::string& algo,
- const secure_vector<byte>& nonce,
- const secure_vector<byte>& key,
- const secure_vector<byte>& in)
- {
- std::unique_ptr<Transform> t(get_transform(algo));
-
- if(Keyed_Transform* keyed = dynamic_cast<Keyed_Transform*>(t.get()))
- keyed->set_key(key);
-
- secure_vector<byte> out = in;
-
- t->start(nonce);
- t->finish(out);
- return out;
- }
-
-}
-
-size_t test_transform()
- {
- std::ifstream vec(TEST_DATA_DIR "/transform.vec");
-
- return run_tests(vec, "Transform", "Output", true,
- [](std::map<std::string, std::string> m)
- {
- return hex_encode(transform_test(m["Transform"],
- hex_decode_locked(m["Nonce"]),
- hex_decode_locked(m["Key"]),
- hex_decode_locked(m["Input"])));
- });
- }
diff --git a/src/tests/test_tss.cpp b/src/tests/test_tss.cpp
index c5440634b..96e3fa9ee 100644
--- a/src/tests/test_tss.cpp
+++ b/src/tests/test_tss.cpp
@@ -7,53 +7,46 @@
#include "tests.h"
#if defined(BOTAN_HAS_THRESHOLD_SECRET_SHARING)
+ #include <botan/tss.h>
+ #include <botan/hex.h>
+#endif
-#include <iostream>
-#include <botan/hex.h>
-#include <botan/tss.h>
+namespace Botan_Tests {
-size_t test_tss()
- {
- using namespace Botan;
-
- auto& rng = test_rng();
-
- size_t fails = 0;
-
- byte id[16];
- for(int i = 0; i != 16; ++i)
- id[i] = i;
-
- const secure_vector<byte> S = hex_decode_locked("7465737400");
+namespace {
- std::vector<RTSS_Share> shares =
- RTSS_Share::split(2, 4, S.data(), S.size(), id, rng);
+#if defined(BOTAN_HAS_THRESHOLD_SECRET_SHARING)
- auto back = RTSS_Share::reconstruct(shares);
+class TSS_Tests : public Test
+ {
+ public:
+ std::vector<Test::Result> run() override
+ {
+ std::vector<Test::Result> results;
- if(S != back)
- {
- std::cout << "TSS-0: " << hex_encode(S) << " != " << hex_encode(back) << std::endl;
- ++fails;
- }
+ Test::Result result("TSS");
+ byte id[16];
+ for(int i = 0; i != 16; ++i)
+ id[i] = i;
- shares.resize(shares.size()-1);
+ const std::vector<byte> S = Botan::hex_decode("7465737400");
- back = RTSS_Share::reconstruct(shares);
+ std::vector<Botan::RTSS_Share> shares =
+ Botan::RTSS_Share::split(2, 4, S.data(), S.size(), id, Test::rng());
- if(S != back)
- {
- std::cout << "TSS-1: " << hex_encode(S) << " != " << hex_encode(back) << std::endl;
- ++fails;
- }
+ result.test_eq("reconstruction", Botan::RTSS_Share::reconstruct(shares), S);
+ shares.resize(shares.size()-1);
+ result.test_eq("reconstruction after removal", Botan::RTSS_Share::reconstruct(shares), S);
- test_report("TSS", 2, fails);
+ results.push_back(result);
+ return results;
+ }
+ };
- return fails;
- }
+BOTAN_REGISTER_TEST("tss", TSS_Tests);
-#else
+#endif // BOTAN_HAS_THRESHOLD_SECRET_SHARING
-SKIP_TEST(tss);
+}
-#endif // BOTAN_HAS_THRESHOLD_SECRET_SHARING
+}
diff --git a/src/tests/test_utils.cpp b/src/tests/test_utils.cpp
new file mode 100644
index 000000000..dfe0b19d3
--- /dev/null
+++ b/src/tests/test_utils.cpp
@@ -0,0 +1,331 @@
+/*
+* (C) 2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "tests.h"
+#include <functional>
+#include <botan/loadstor.h>
+#include <botan/calendar.h>
+#include <botan/internal/rounding.h>
+
+#if defined(BOTAN_HAS_BASE64_CODEC)
+ #include <botan/base64.h>
+#endif
+
+namespace Botan_Tests {
+
+namespace {
+
+class Utility_Function_Tests : public Text_Based_Test
+ {
+ public:
+ Utility_Function_Tests() : Text_Based_Test(Test::data_file("util.vec"),
+ {"In1","In2","Out"})
+ {}
+
+ Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
+ {
+ Test::Result result("Util " + algo);
+
+ if(algo == "round_up")
+ {
+ const size_t x = get_req_sz(vars, "In1");
+ const size_t to = get_req_sz(vars, "In2");
+
+ result.test_eq(algo.c_str(), Botan::round_up(x, to), get_req_sz(vars, "Out"));
+
+ try
+ {
+ Botan::round_up(x, 0);
+ result.test_failure("round_up did not reject invalid input");
+ }
+ catch(std::exception) {}
+ }
+ else if(algo == "round_down")
+ {
+ const size_t x = get_req_sz(vars, "In1");
+ const size_t to = get_req_sz(vars, "In2");
+
+ result.test_eq(algo.c_str(), Botan::round_down<size_t>(x, to), get_req_sz(vars, "Out"));
+ result.test_eq(algo.c_str(), Botan::round_down<size_t>(x, 0), x);
+ }
+
+ return result;
+ }
+
+ std::vector<Test::Result> run_final_tests() override
+ {
+ std::vector<Test::Result> results;
+
+ results.push_back(test_loadstore());
+
+ return results;
+ }
+
+ Test::Result test_loadstore()
+ {
+ Test::Result result("Util load/store");
+
+ const std::vector<uint8_t> membuf =
+ Botan::hex_decode("00112233445566778899AABBCCDDEEFF");
+ const uint8_t* mem = membuf.data();
+
+ const uint16_t in16 = 0x1234;
+ const uint32_t in32 = 0xA0B0C0D0;
+ const uint64_t in64 = 0xABCDEF0123456789;
+
+ result.test_is_eq<uint8_t>(Botan::get_byte(0, in32), 0xA0);
+ result.test_is_eq<uint8_t>(Botan::get_byte(1, in32), 0xB0);
+ result.test_is_eq<uint8_t>(Botan::get_byte(2, in32), 0xC0);
+ result.test_is_eq<uint8_t>(Botan::get_byte(3, in32), 0xD0);
+
+ result.test_is_eq<uint16_t>(Botan::make_u16bit(0xAA, 0xBB), 0xAABB);
+ result.test_is_eq<uint32_t>(Botan::make_u32bit(0x01, 0x02, 0x03, 0x04), 0x01020304);
+
+ result.test_is_eq<uint16_t>(Botan::load_be<uint16_t>(mem, 0), 0x0011);
+ result.test_is_eq<uint16_t>(Botan::load_be<uint16_t>(mem, 1), 0x2233);
+ result.test_is_eq<uint16_t>(Botan::load_be<uint16_t>(mem, 2), 0x4455);
+ result.test_is_eq<uint16_t>(Botan::load_be<uint16_t>(mem, 3), 0x6677);
+
+ result.test_is_eq<uint16_t>(Botan::load_le<uint16_t>(mem, 0), 0x1100);
+ result.test_is_eq<uint16_t>(Botan::load_le<uint16_t>(mem, 1), 0x3322);
+ result.test_is_eq<uint16_t>(Botan::load_le<uint16_t>(mem, 2), 0x5544);
+ result.test_is_eq<uint16_t>(Botan::load_le<uint16_t>(mem, 3), 0x7766);
+
+ result.test_is_eq<uint32_t>(Botan::load_be<uint32_t>(mem, 0), 0x00112233);
+ result.test_is_eq<uint32_t>(Botan::load_be<uint32_t>(mem, 1), 0x44556677);
+ result.test_is_eq<uint32_t>(Botan::load_be<uint32_t>(mem, 2), 0x8899AABB);
+ result.test_is_eq<uint32_t>(Botan::load_be<uint32_t>(mem, 3), 0xCCDDEEFF);
+
+ result.test_is_eq<uint32_t>(Botan::load_le<uint32_t>(mem, 0), 0x33221100);
+ result.test_is_eq<uint32_t>(Botan::load_le<uint32_t>(mem, 1), 0x77665544);
+ result.test_is_eq<uint32_t>(Botan::load_le<uint32_t>(mem, 2), 0xBBAA9988);
+ result.test_is_eq<uint32_t>(Botan::load_le<uint32_t>(mem, 3), 0xFFEEDDCC);
+
+ result.test_is_eq<uint64_t>(Botan::load_be<uint64_t>(mem, 0), 0x0011223344556677);
+ result.test_is_eq<uint64_t>(Botan::load_be<uint64_t>(mem, 1), 0x8899AABBCCDDEEFF);
+
+ result.test_is_eq<uint64_t>(Botan::load_le<uint64_t>(mem, 0), 0x7766554433221100);
+ result.test_is_eq<uint64_t>(Botan::load_le<uint64_t>(mem, 1), 0xFFEEDDCCBBAA9988);
+
+ // Check misaligned loads:
+ result.test_is_eq<uint16_t>(Botan::load_be<uint16_t>(mem + 1, 0), 0x1122);
+ result.test_is_eq<uint16_t>(Botan::load_le<uint16_t>(mem + 3, 0), 0x4433);
+
+ result.test_is_eq<uint32_t>(Botan::load_be<uint32_t>(mem + 1, 1), 0x55667788);
+ result.test_is_eq<uint32_t>(Botan::load_le<uint32_t>(mem + 3, 1), 0xAA998877);
+
+ result.test_is_eq<uint64_t>(Botan::load_be<uint64_t>(mem + 1, 0), 0x1122334455667788);
+ result.test_is_eq<uint64_t>(Botan::load_le<uint64_t>(mem + 7, 0), 0xEEDDCCBBAA998877);
+ result.test_is_eq<uint64_t>(Botan::load_le<uint64_t>(mem + 5, 0), 0xCCBBAA9988776655);
+
+ byte outbuf[16] = { 0 };
+
+ for(size_t offset = 0; offset != 7; ++offset)
+ {
+ byte* out = outbuf + offset;
+
+ Botan::store_be(in16, out);
+ result.test_is_eq<uint8_t>(out[0], 0x12);
+ result.test_is_eq<uint8_t>(out[1], 0x34);
+
+ Botan::store_le(in16, out);
+ result.test_is_eq<uint8_t>(out[0], 0x34);
+ result.test_is_eq<uint8_t>(out[1], 0x12);
+
+ Botan::store_be(in32, out);
+ result.test_is_eq<uint8_t>(out[0], 0xA0);
+ result.test_is_eq<uint8_t>(out[1], 0xB0);
+ result.test_is_eq<uint8_t>(out[2], 0xC0);
+ result.test_is_eq<uint8_t>(out[3], 0xD0);
+
+ Botan::store_le(in32, out);
+ result.test_is_eq<uint8_t>(out[0], 0xD0);
+ result.test_is_eq<uint8_t>(out[1], 0xC0);
+ result.test_is_eq<uint8_t>(out[2], 0xB0);
+ result.test_is_eq<uint8_t>(out[3], 0xA0);
+
+ Botan::store_be(in64, out);
+ result.test_is_eq<uint8_t>(out[0], 0xAB);
+ result.test_is_eq<uint8_t>(out[1], 0xCD);
+ result.test_is_eq<uint8_t>(out[2], 0xEF);
+ result.test_is_eq<uint8_t>(out[3], 0x01);
+ result.test_is_eq<uint8_t>(out[4], 0x23);
+ result.test_is_eq<uint8_t>(out[5], 0x45);
+ result.test_is_eq<uint8_t>(out[6], 0x67);
+ result.test_is_eq<uint8_t>(out[7], 0x89);
+
+ Botan::store_le(in64, out);
+ result.test_is_eq<uint8_t>(out[0], 0x89);
+ result.test_is_eq<uint8_t>(out[1], 0x67);
+ result.test_is_eq<uint8_t>(out[2], 0x45);
+ result.test_is_eq<uint8_t>(out[3], 0x23);
+ result.test_is_eq<uint8_t>(out[4], 0x01);
+ result.test_is_eq<uint8_t>(out[5], 0xEF);
+ result.test_is_eq<uint8_t>(out[6], 0xCD);
+ result.test_is_eq<uint8_t>(out[7], 0xAB);
+ }
+
+ return result;
+ }
+ };
+
+BOTAN_REGISTER_TEST("util", Utility_Function_Tests);
+
+class Date_Format_Tests : public Text_Based_Test
+ {
+ public:
+ Date_Format_Tests() : Text_Based_Test(Test::data_file("dates.vec"),
+ std::vector<std::string>{"Date"})
+ {}
+
+ std::vector<uint32_t> parse_date(const std::string& s)
+ {
+ const std::vector<std::string> parts = Botan::split_on(s, ',');
+ if(parts.size() != 6)
+ throw std::runtime_error("Bad date format '" + s + "'");
+
+ std::vector<uint32_t> u32s;
+ for(auto&& sub : parts)
+ {
+ u32s.push_back(Botan::to_u32bit(sub));
+ }
+ return u32s;
+ }
+
+ Test::Result run_one_test(const std::string& type, const VarMap& vars) override
+ {
+ Test::Result result("Date parsing");
+
+ const std::vector<uint32_t> d = parse_date(get_req_str(vars, "Date"));
+
+ if(type == "valid" || type == "valid.not_std")
+ {
+ Botan::calendar_point c(d[0], d[1], d[2], d[3], d[4], d[5]);
+ result.test_is_eq("year", c.year, d[0]);
+ result.test_is_eq("month", c.month, d[1]);
+ result.test_is_eq("day", c.day, d[2]);
+ result.test_is_eq("hour", c.hour, d[3]);
+ result.test_is_eq("minute", c.minutes, d[4]);
+ result.test_is_eq("second", c.seconds, d[5]);
+
+ if(type == "valid.not_std")
+ {
+ result.test_throws("valid but out of std::timepoint range", [c]() { c.to_std_timepoint(); });
+ }
+ else
+ {
+ Botan::calendar_point c2 = Botan::calendar_value(c.to_std_timepoint());
+ result.test_is_eq("year", c2.year, d[0]);
+ result.test_is_eq("month", c2.month, d[1]);
+ result.test_is_eq("day", c2.day, d[2]);
+ result.test_is_eq("hour", c2.hour, d[3]);
+ result.test_is_eq("minute", c2.minutes, d[4]);
+ result.test_is_eq("second", c2.seconds, d[5]);
+ }
+ }
+ else if(type == "invalid")
+ {
+ result.test_throws("invalid date",
+ [d]() { Botan::calendar_point c(d[0], d[1], d[2], d[3], d[4], d[5]); });
+ }
+ else
+ {
+ throw std::runtime_error("Unexpected header '" + type + "' in date format tests");
+ }
+
+ return result;
+ }
+
+ };
+
+BOTAN_REGISTER_TEST("util_dates", Date_Format_Tests);
+
+#if defined(BOTAN_HAS_BASE64_CODEC)
+
+class Base64_Tests : public Text_Based_Test
+ {
+ public:
+ Base64_Tests() : Text_Based_Test(Test::data_file("base64.vec"),
+ std::vector<std::string>({"Base64"}),
+ {"Binary"})
+ {}
+
+ Test::Result run_one_test(const std::string& type, const VarMap& vars) override
+ {
+ Test::Result result("Base64");
+
+ const bool is_valid = (type == "valid");
+ const std::string base64 = get_req_str(vars, "Base64");
+
+ try
+ {
+ if(is_valid)
+ {
+ const std::vector<byte> binary = get_req_bin(vars, "Binary");
+ result.test_eq("base64 decoding", Botan::base64_decode(base64), binary);
+ result.test_eq("base64 encoding", Botan::base64_encode(binary), base64);
+ }
+ else
+ {
+ auto res = Botan::base64_decode(base64);
+ result.test_failure("decoded invalid base64 to " + Botan::hex_encode(res));
+ }
+ }
+ catch(std::exception& e)
+ {
+ if(is_valid)
+ {
+ result.test_failure("rejected valid base64", e.what());
+ }
+ else
+ {
+ result.test_note("rejected invalid base64");
+ }
+ }
+
+ return result;
+ }
+
+ std::vector<Test::Result> run_final_tests() override
+ {
+ Test::Result result("Base64");
+ const std::string valid_b64 = "Zg==";
+
+ for(char ws_char : { ' ', '\t', '\r', '\n' })
+ {
+ for(size_t i = 0; i <= valid_b64.size(); ++i)
+ {
+ std::string b64_ws = valid_b64;
+ b64_ws.insert(i, 1, ws_char);
+
+ try
+ {
+ result.test_failure("decoded whitespace base64", Botan::base64_decode(b64_ws, false));
+ }
+ catch(std::exception& e) {}
+
+ try
+ {
+ result.test_eq("base64 decoding with whitespace", Botan::base64_decode(b64_ws, true), "66");
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure(b64_ws.c_str(), e.what());
+ }
+ }
+ }
+
+ return {result};
+ }
+ };
+
+BOTAN_REGISTER_TEST("base64", Base64_Tests);
+
+#endif
+
+}
+
+}
diff --git a/src/tests/nist_x509.cpp b/src/tests/test_x509_path.cpp
index 65e154293..62051d021 100644
--- a/src/tests/nist_x509.cpp
+++ b/src/tests/test_x509_path.cpp
@@ -7,12 +7,11 @@
#include "tests.h"
#if defined(BOTAN_HAS_X509_CERTIFICATES)
-
-#include <botan/x509path.h>
-#include <botan/internal/filesystem.h>
+ #include <botan/x509path.h>
+ #include <botan/internal/filesystem.h>
+#endif
#include <algorithm>
-#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
@@ -20,231 +19,111 @@
#include <map>
#include <cstdlib>
-using namespace Botan;
-
-std::map<size_t, Path_Validation_Result::Code> get_expected();
+namespace Botan_Tests {
namespace {
-std::vector<X509_Certificate> load_cert_file(const std::string& filename)
- {
- DataSource_Stream in(filename);
-
- std::vector<X509_Certificate> certs;
- while(!in.end_of_data())
- {
- try {
- certs.emplace_back(in);
- }
- catch(Decoding_Error) {}
- }
-
- return certs;
- }
-
-std::map<std::string, std::string> read_results(const std::string& results_file)
- {
- std::ifstream in(results_file);
- if(!in.good())
- throw std::runtime_error("Failed reading " + results_file);
-
- std::map<std::string, std::string> m;
- std::string line;
- while(in.good())
- {
- std::getline(in, line);
- if(line == "")
- continue;
- if(line[0] == '#')
- continue;
-
- std::vector<std::string> parts = split_on(line, ':');
-
- if(parts.size() != 2)
- throw std::runtime_error("Invalid line " + line);
-
- m[parts[0]] = parts[1];
- }
-
- return m;
- }
-
-}
+#if defined(BOTAN_HAS_X509_CERTIFICATES)
-size_t test_x509_x509test()
+class X509test_Path_Validation_Tests : public Test
{
- // Test certs generated by https://github.com/yymax/x509test
- const std::string test_dir = "src/tests/data/x509test";
-
- std::map<std::string, std::string> results = read_results(test_dir + "/expected.txt");
-
- const Path_Validation_Restrictions default_restrictions;
-
- size_t fail = 0;
-
- X509_Certificate root(test_dir + "/root.pem");
- Certificate_Store_In_Memory trusted;
- trusted.add_certificate(root);
-
- for(auto i = results.begin(); i != results.end(); ++i)
- {
- const std::string fsname = i->first;
- const std::string expected = i->second;
-
- std::vector<X509_Certificate> certs = load_cert_file(test_dir + "/" + fsname);
-
- if(certs.empty())
- throw std::runtime_error("Failed to read certs from " + fsname);
-
- Path_Validation_Result result = x509_path_validate(certs, default_restrictions, trusted,
- "www.tls.test", Usage_Type::TLS_SERVER_AUTH);
-
- if(result.successful_validation() && result.trust_root() != root)
- result = Path_Validation_Result(Certificate_Status_Code::CANNOT_ESTABLISH_TRUST);
-
- if(result.result_string() != expected)
+ public:
+ std::vector<Test::Result> run() override
{
- std::cout << "FAIL " << fsname << " expected '" << expected << "' got '" << result.result_string() << "'\n";
- ++fail;
- }
- }
+ std::vector<Test::Result> results;
- test_report("X.509 (x509test)", results.size(), fail);
+ // Test certs generated by https://github.com/yymax/x509test
+ const std::string test_dir = "src/tests/data/x509test";
- return fail;
- }
+ std::map<std::string, std::string> expected = read_results(test_dir + "/expected.txt");
-size_t test_nist_x509()
- {
- /**
- * Code to run the X.509v3 processing tests described in "Conformance
- * Testing of Relying Party Client Certificate Path Proccessing Logic",
- * which is available on NIST's web site.
- *
- * Known Failures/Problems:
- * - Policy extensions are not implemented, so we skip tests #34-#53.
- * - Tests #75 and #76 are skipped as they make use of relatively
- * obscure CRL extensions which are not supported.
- */
- const std::string root_test_dir = "src/tests/data/nist_x509/";
- const size_t total_tests = 76;
- try
- {
- // Do nothing, just test filesystem access
- get_files_recursive(root_test_dir);
- }
- catch(No_Filesystem_Access)
- {
- std::cout << "Warning: No filesystem access, skipping NIST X.509 validation tests" << std::endl;
- return 0;
- }
+ const Botan::Path_Validation_Restrictions default_restrictions;
- size_t unexp_failure = 0;
- size_t unexp_success = 0;
- size_t wrong_error = 0;
- size_t skipped = 0;
- size_t ran = 0;
+ Botan::X509_Certificate root(test_dir + "/root.pem");
+ Botan::Certificate_Store_In_Memory trusted;
+ trusted.add_certificate(root);
- auto expected_results = get_expected();
+ for(auto i = expected.begin(); i != expected.end(); ++i)
+ {
+ Test::Result result("X509test path validation");
+ const std::string fsname = i->first;
+ const std::string expected = i->second;
- try {
+ std::vector<Botan::X509_Certificate> certs = load_cert_file(test_dir + "/" + fsname);
- for(size_t test_no = 1; test_no <= total_tests; ++test_no)
- {
- const std::string test_dir = root_test_dir + "/test" + (test_no <= 9 ? "0" : "") + std::to_string(test_no);
+ if(certs.empty())
+ throw std::runtime_error("Failed to read certs from " + fsname);
- const std::vector<std::string> all_files = get_files_recursive(test_dir);
- if (all_files.empty())
- std::cout << "Warning: No test files found in '" << test_dir << "'" << std::endl;
+ Botan::Path_Validation_Result path_result = Botan::x509_path_validate(
+ certs, default_restrictions, trusted,
+ "www.tls.test", Botan::Usage_Type::TLS_SERVER_AUTH);
- std::vector<std::string> certs, crls;
- std::string root_cert, to_verify;
+ if(path_result.successful_validation() && path_result.trust_root() != root)
+ path_result = Botan::Path_Validation_Result(Botan::Certificate_Status_Code::CANNOT_ESTABLISH_TRUST);
- for(const auto &current : all_files)
- {
- if(current.find("int") != std::string::npos && current.find(".crt") != std::string::npos)
- certs.push_back(current);
- else if(current.find("root.crt") != std::string::npos)
- root_cert = current;
- else if(current.find("end.crt") != std::string::npos)
- to_verify = current;
- else if(current.find(".crl") != std::string::npos)
- crls.push_back(current);
- }
+ result.test_eq("validation result", path_result.result_string(), expected);
+ results.push_back(result);
+ }
- if(expected_results.find(test_no) == expected_results.end())
- {
- //printf("Skipping %d\n", test_no);
- skipped++;
- continue;
+ return results;
}
- ++ran;
-
- Certificate_Store_In_Memory store;
+ private:
- store.add_certificate(X509_Certificate(root_cert));
-
- X509_Certificate end_user(to_verify);
-
- for(size_t i = 0; i != certs.size(); i++)
- store.add_certificate(X509_Certificate(certs[i]));
-
- for(size_t i = 0; i != crls.size(); i++)
+ std::vector<Botan::X509_Certificate> load_cert_file(const std::string& filename)
{
- DataSource_Stream in(crls[i], true);
- X509_CRL crl(in);
- store.add_crl(crl);
- }
+ Botan::DataSource_Stream in(filename);
- Path_Validation_Restrictions restrictions(true);
+ std::vector<Botan::X509_Certificate> certs;
+ while(!in.end_of_data())
+ {
+ try {
+ certs.emplace_back(in);
+ }
+ catch(Botan::Decoding_Error&) {}
+ }
- Path_Validation_Result validation_result =
- x509_path_validate(end_user,
- restrictions,
- store);
+ return certs;
+ }
- auto expected = expected_results[test_no];
+ std::map<std::string, std::string> read_results(const std::string& results_file)
+ {
+ std::ifstream in(results_file);
+ if(!in.good())
+ throw std::runtime_error("Failed reading " + results_file);
- Path_Validation_Result::Code result = validation_result.result();
+ std::map<std::string, std::string> m;
+ std::string line;
+ while(in.good())
+ {
+ std::getline(in, line);
+ if(line == "")
+ continue;
+ if(line[0] == '#')
+ continue;
- if(result != expected)
- {
- std::cout << "NIST X.509 test #" << test_no << ": ";
+ std::vector<std::string> parts = Botan::split_on(line, ':');
- const std::string result_str = Path_Validation_Result::status_string(result);
- const std::string exp_str = Path_Validation_Result::status_string(expected);
+ if(parts.size() != 2)
+ throw std::runtime_error("Invalid line " + line);
- if(expected == Certificate_Status_Code::VERIFIED)
- {
- std::cout << "unexpected failure: " << result_str << std::endl;
- unexp_failure++;
- }
- else if(result == Certificate_Status_Code::VERIFIED)
- {
- std::cout << "unexpected success, expected " << exp_str << std::endl;
- unexp_success++;
- }
- else
- {
- std::cout << "wrong error, got '" << result_str << "' expected '" << exp_str << "'" << std::endl;
- wrong_error++;
+ m[parts[0]] = parts[1];
}
+
+ return m;
}
- }
- }
- catch(std::exception& e)
- {
- std::cout << e.what() << std::endl;
- ++unexp_failure;
- }
+ };
- const size_t all_failures = unexp_failure + unexp_success + wrong_error;
+BOTAN_REGISTER_TEST("x509_path_x509test", X509test_Path_Validation_Tests);
- test_report("NIST X.509 path validation", ran, all_failures);
+class NIST_Path_Validation_Tests : public Test
+ {
+ public:
+ std::vector<Test::Result> run() override;
- return all_failures;
- }
+ private:
+ std::map<size_t, Botan::Path_Validation_Result::Code> get_expected();
+ };
/*
The expected results are essentially the error codes that best coorespond
@@ -255,11 +134,14 @@ size_t test_nist_x509()
what they "should" be: these changes are marked as such, and have comments
explaining the problem at hand.
*/
-std::map<size_t, Path_Validation_Result::Code> get_expected()
+std::map<size_t, Botan::Path_Validation_Result::Code> NIST_Path_Validation_Tests::get_expected()
{
+ using namespace Botan;
+
std::map<size_t, Path_Validation_Result::Code> expected_results;
- /* OK, not a super great way of doing this... */
+
+ // TODO read from a file
expected_results[1] = Certificate_Status_Code::VERIFIED;
expected_results[2] = Certificate_Status_Code::SIGNATURE_ERROR;
expected_results[3] = Certificate_Status_Code::SIGNATURE_ERROR;
@@ -374,9 +256,116 @@ std::map<size_t, Path_Validation_Result::Code> get_expected()
return expected_results;
}
-#else
+std::vector<Test::Result> NIST_Path_Validation_Tests::run()
+ {
+ std::vector<Test::Result> results;
-size_t test_x509_x509test() { return 0; }
-size_t test_nist_x509() { return 0; }
+ /**
+ * Code to run the X.509v3 processing tests described in "Conformance
+ * Testing of Relying Party Client Certificate Path Proccessing Logic",
+ * which is available on NIST's web site.
+ *
+ * Known Failures/Problems:
+ * - Policy extensions are not implemented, so we skip tests #34-#53.
+ * - Tests #75 and #76 are skipped as they make use of relatively
+ * obscure CRL extensions which are not supported.
+ */
+ const std::string root_test_dir = "src/tests/data/nist_x509/";
+
+ try
+ {
+ // Do nothing, just test filesystem access
+ Botan::get_files_recursive(root_test_dir);
+ }
+ catch(Botan::No_Filesystem_Access)
+ {
+ Test::Result result("NIST path validation");
+ result.test_note("Skipping due to missing filesystem access");
+ results.push_back(result);
+ return results;
+ }
+
+ const size_t total_tests = 76;
+ std::map<size_t, Botan::Path_Validation_Result::Code> expected_results = get_expected();
+
+ for(size_t test_no = 1; test_no <= total_tests; ++test_no)
+ {
+ try
+ {
+ Test::Result result("NIST path validation");
+ const std::string test_dir = root_test_dir + "/test" + (test_no <= 9 ? "0" : "") + std::to_string(test_no);
+
+ const std::vector<std::string> all_files = Botan::get_files_recursive(test_dir);
+ if (all_files.empty())
+ {
+ result.test_failure("No test files found in " + test_dir);
+ continue;
+ }
+
+ std::vector<std::string> certs, crls;
+ std::string root_cert, to_verify;
+
+ for(const auto &current : all_files)
+ {
+ if(current.find("int") != std::string::npos && current.find(".crt") != std::string::npos)
+ certs.push_back(current);
+ else if(current.find("root.crt") != std::string::npos)
+ root_cert = current;
+ else if(current.find("end.crt") != std::string::npos)
+ to_verify = current;
+ else if(current.find(".crl") != std::string::npos)
+ crls.push_back(current);
+ }
+
+ if(expected_results.find(test_no) == expected_results.end())
+ {
+ result.test_note("Skipping test");
+ continue;
+ }
+
+ Botan::Certificate_Store_In_Memory store;
+
+ store.add_certificate(Botan::X509_Certificate(root_cert));
+
+ Botan::X509_Certificate end_user(to_verify);
+
+ for(size_t i = 0; i != certs.size(); i++)
+ store.add_certificate(Botan::X509_Certificate(certs[i]));
+
+ for(size_t i = 0; i != crls.size(); i++)
+ {
+ Botan::DataSource_Stream in(crls[i], true);
+ Botan::X509_CRL crl(in);
+ store.add_crl(crl);
+ }
+
+ Botan::Path_Validation_Restrictions restrictions(true);
+
+ Botan::Path_Validation_Result validation_result =
+ Botan::x509_path_validate(end_user,
+ restrictions,
+ store);
+
+ auto expected = expected_results[test_no];
+
+ result.test_eq("path validation result",
+ validation_result.result_string(),
+ Botan::Path_Validation_Result::status_string(expected));
+
+ results.push_back(result);
+ }
+ catch(std::exception& e)
+ {
+ results.push_back(Test::Result::Failure("NIST X509 " + std::to_string(test_no), e.what()));
+ }
+ }
+ return results;
+ }
+
+BOTAN_REGISTER_TEST("x509_path_nist", NIST_Path_Validation_Tests);
#endif
+
+}
+
+}
diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp
index 61378b1a2..e421d245c 100644
--- a/src/tests/tests.cpp
+++ b/src/tests/tests.cpp
@@ -5,324 +5,757 @@
*/
#include "tests.h"
-#include <iostream>
-#include <fstream>
-#include <botan/auto_rng.h>
+
+#include <sstream>
+#include <iomanip>
+#include <botan/hex.h>
#include <botan/internal/filesystem.h>
+#include <botan/internal/bit_ops.h>
-#define CATCH_CONFIG_RUNNER
-#define CATCH_CONFIG_CONSOLE_WIDTH 60
-#define CATCH_CONFIG_COLOUR_NONE
-#include "catchy/catch.hpp"
+namespace Botan_Tests {
-#if defined(BOTAN_HAS_SYSTEM_RNG)
- #include <botan/system_rng.h>
-#endif
+#define TEST_DATA_DIR "src/tests/data"
+#define TEST_OUTDATA_DIR "src/tests/outdata"
-using namespace Botan;
+Test::Registration::Registration(const std::string& name, Test* test)
+ {
+ if(Test::global_registry().count(name) == 0)
+ {
+ Test::global_registry().insert(std::make_pair(name, std::unique_ptr<Test>(test)));
+ }
+ else
+ {
+ throw std::runtime_error("Duplicate registration of test '" + name + "'");
+ }
+ }
-Botan::RandomNumberGenerator& test_rng()
+void Test::Result::merge(const Result& other)
{
-#if defined(BOTAN_HAS_SYSTEM_RNG)
- return Botan::system_rng();
-#else
- static Botan::AutoSeeded_RNG rng;
- return rng;
-#endif
+ if(who() != other.who())
+ throw std::runtime_error("Merging tests from different sources");
+
+ m_ns_taken += other.m_ns_taken;
+ m_tests_passed += other.m_tests_passed;
+ m_fail_log.insert(m_fail_log.end(), other.m_fail_log.begin(), other.m_fail_log.end());
+ m_log.insert(m_log.end(), other.m_log.begin(), other.m_log.end());
}
-size_t run_tests_in_dir(const std::string& dir, std::function<size_t (const std::string&)> fn)
+void Test::Result::start_timer()
{
- size_t fails = 0;
+ if(m_started == 0)
+ {
+ m_started = Test::timestamp();
+ }
+ }
- try
+void Test::Result::end_timer()
+ {
+ if(m_started > 0)
{
- auto files = get_files_recursive(dir);
+ m_ns_taken += Test::timestamp() - m_started;
+ m_started = 0;
+ }
+ }
- if (files.empty())
- std::cout << "Warning: No test files found in '" << dir << "'" << std::endl;
+void Test::Result::test_note(const std::string& note, const char* extra)
+ {
+ if(note != "")
+ {
+ std::ostringstream out;
+ out << who() << " " << note;
+ if(extra)
+ out << ": " << extra;
+ m_log.push_back(out.str());
+ }
+ }
- for(const auto file: files)
- fails += fn(file);
+void Test::Result::note_missing(const std::string& whatever)
+ {
+ static std::set<std::string> s_already_seen;
+
+ if(s_already_seen.count(whatever) == 0)
+ {
+ test_note("Skipping tests due to missing " + whatever);
+ s_already_seen.insert(whatever);
}
- catch(No_Filesystem_Access)
+ }
+
+bool Test::Result::test_throws(const std::string& what, std::function<void ()> fn)
+ {
+ try {
+ fn();
+ return test_failure(what + " failed to throw expected exception");
+ }
+ catch(std::exception& e)
{
- std::cout << "Warning: No filesystem access available to read test files in '" << dir << "'" << std::endl;
+ return test_success(what + " threw exception " + e.what());
}
+ catch(...)
+ {
+ return test_success(what + " threw unknown exception");
+ }
+ }
+
+bool Test::Result::test_success(const std::string& note)
+ {
+ if(Test::log_success())
+ {
+ test_note(note);
+ }
+ ++m_tests_passed;
+ return true;
+ }
+
+bool Test::Result::test_failure(const char* what, const char* error)
+ {
+ return test_failure(who() + " " + what + " with error " + error);
+ }
+
+void Test::Result::test_failure(const char* what, const uint8_t buf[], size_t buf_len)
+ {
+ test_failure(who() + ": " + what +
+ " buf len " + std::to_string(buf_len) +
+ " value " + Botan::hex_encode(buf, buf_len));
+ }
+
+bool Test::Result::test_failure(const std::string& err)
+ {
+ m_fail_log.push_back(err);
+ return false;
+ }
- return fails;
+bool Test::Result::test_ne(const char* what,
+ const uint8_t produced[], size_t produced_len,
+ const uint8_t expected[], size_t expected_len)
+ {
+ if(produced_len == expected_len && Botan::same_mem(produced, expected, expected_len))
+ return test_failure(who() + ":" + what + " produced matching");
+ return test_success();
}
-size_t run_tests(const std::vector<std::pair<std::string, test_fn>>& tests)
+bool Test::Result::test_eq(const char* producer, const char* what,
+ const uint8_t produced[], size_t produced_size,
+ const uint8_t expected[], size_t expected_size)
{
- size_t fails = 0;
+ if(produced_size == expected_size && Botan::same_mem(produced, expected, expected_size))
+ return test_success();
+
+ std::ostringstream err;
+
+ err << who();
- for(const auto& row : tests)
+ if(producer)
{
- auto name = row.first;
- auto test = row.second;
- try
- {
- fails += test();
- }
- catch(std::exception& e)
- {
- std::cout << name << ": Exception escaped test: " << e.what() << std::endl;
- ++fails;
- }
- catch(...)
- {
- std::cout << name << ": Exception escaped test" << std::endl;
- ++fails;
- }
+ err << " producer '" << producer << "'";
}
- // Summary for test suite
- std::cout << "===============" << std::endl;
- test_report("Tests", 0, fails);
+ err << " unexpected result";
- return fails;
+ if(what)
+ {
+ err << " for " << what;
+ }
+
+ if(produced_size != expected_size)
+ {
+ err << " produced " << produced_size << " bytes expected " << expected_size;
+ }
+
+ std::vector<uint8_t> xor_diff(std::min(produced_size, expected_size));
+ size_t bits_different = 0;
+
+ for(size_t i = 0; i != xor_diff.size(); ++i)
+ {
+ xor_diff[i] = produced[i] ^ expected[i];
+ bits_different += Botan::hamming_weight(xor_diff[i]);
+ }
+
+ err << "\nProduced: " << Botan::hex_encode(produced, produced_size)
+ << "\nExpected: " << Botan::hex_encode(expected, expected_size);
+
+ if(bits_different > 0)
+ {
+ err << "\nXOR Diff: " << Botan::hex_encode(xor_diff)
+ << " (" << bits_different << " bits different)";
+ }
+
+ return test_failure(err.str());
}
-void test_report(const std::string& name, size_t ran, size_t failed)
+bool Test::Result::test_eq(const char* what, const std::string& produced, const std::string& expected)
{
- std::cout << name;
+ return test_is_eq(what, produced, expected);
+ }
- if(ran > 0)
- std::cout << " " << ran << " tests";
+bool Test::Result::test_eq(const char* what, const char* produced, const char* expected)
+ {
+ return test_is_eq(what, std::string(produced), std::string(expected));
+ }
- if(failed)
- std::cout << " " << failed << " FAILs" << std::endl;
- else
- std::cout << " all ok" << std::endl;
+bool Test::Result::test_eq(const char* what, size_t produced, size_t expected)
+ {
+ return test_is_eq(what, produced, expected);
+ }
+
+bool Test::Result::test_lt(const char* what, size_t produced, size_t expected)
+ {
+ if(produced >= expected)
+ {
+ std::ostringstream err;
+ err << m_who;
+ if(what)
+ err << " " << what;
+ err << " unexpected result " << produced << " >= " << expected;
+ return test_failure(err.str());
+ }
+
+ return test_success();
}
-size_t run_tests_bb(std::istream& src,
- const std::string& name_key,
- const std::string& output_key,
- bool clear_between_cb,
- std::function<size_t (std::map<std::string, std::string>)> cb)
+bool Test::Result::test_gte(const char* what, size_t produced, size_t expected)
{
- if(!src.good())
+ if(produced < expected)
{
- std::cout << "Could not open input file for " << name_key << std::endl;
- return 1;
+ std::ostringstream err;
+ err << m_who;
+ if(what)
+ err << " " << what;
+ err << " unexpected result " << produced << " < " << expected;
+ return test_failure(err.str());
}
- std::map<std::string, std::string> vars;
- size_t test_fails = 0, algo_fail = 0;
- size_t test_count = 0, algo_count = 0;
+ return test_success();
+ }
+
+#if defined(BOTAN_HAS_BIGINT)
+bool Test::Result::test_eq(const char* what, const BigInt& produced, const BigInt& expected)
+ {
+ return test_is_eq(what, produced, expected);
+ }
+
+bool Test::Result::test_ne(const char* what, const BigInt& produced, const BigInt& expected)
+ {
+ if(produced != expected)
+ return test_success();
+
+ std::ostringstream err;
+ err << who() << " " << what << " produced " << produced << " prohibited value";
+ return test_failure(err.str());
+ }
+#endif
+
+#if defined(BOTAN_HAS_EC_CURVE_GFP)
+bool Test::Result::test_eq(const char* what, const Botan::PointGFp& a, const Botan::PointGFp& b)
+ {
+ //return test_is_eq(what, a, b);
+ if(a == b)
+ return test_success();
+
+ std::ostringstream err;
+ err << who() << " " << what << " a=(" << a.get_affine_x() << "," << a.get_affine_y() << ")"
+ << " b=(" << b.get_affine_x() << "," << b.get_affine_y();
+ return test_failure(err.str());
+ }
+#endif
- std::string fixed_name;
+bool Test::Result::test_eq(const char* what, bool produced, bool expected)
+ {
+ return test_is_eq(what, produced, expected);
+ }
- while(src.good())
+bool Test::Result::test_rc_ok(const char* what, int rc)
+ {
+ if(rc != 0)
{
- std::string line;
- std::getline(src, line);
+ std::ostringstream err;
+ err << m_who;
+ if(what)
+ err << " " << what;
+ err << " unexpectedly failed with error code " << rc;
+ return test_failure(err.str());
+ }
- if(line == "")
- continue;
+ return test_success();
+ }
- if(line[0] == '#')
- continue;
+bool Test::Result::test_rc_fail(const char* func, const char* why, int rc)
+ {
+ if(rc == 0)
+ {
+ std::ostringstream err;
+ err << m_who;
+ if(func)
+ err << " call to " << func << " unexpectedly succeeded";
+ if(why)
+ err << " expecting failure because " << why;
+ return test_failure(err.str());
+ }
- if(line[0] == '[' && line[line.size()-1] == ']')
+ return test_success();
+ }
+
+namespace {
+
+std::string format_time(uint64_t ns)
+ {
+ std::ostringstream o;
+
+ if(ns > 1000000000)
+ {
+ o << std::setprecision(2) << std::fixed << ns/1000000000.0 << " sec";
+ }
+ else
+ {
+ o << std::setprecision(2) << std::fixed << ns/1000000.0 << " msec";
+ }
+
+ return o.str();
+ }
+
+}
+
+std::string Test::Result::result_string() const
+ {
+ std::ostringstream report;
+ report << who() << " ran ";
+
+ if(tests_run() == 0)
+ {
+ report << "ZERO";
+ }
+ else
+ {
+ report << tests_run();
+ }
+ report << " tests";
+
+ if(m_ns_taken > 0)
+ {
+ report << " in " << format_time(m_ns_taken);
+ }
+
+ if(tests_failed())
+ {
+ report << " " << tests_failed() << " FAILED";
+ }
+ else
+ {
+ report << " all ok";
+ }
+
+ report << "\n";
+
+ for(size_t i = 0; i != m_fail_log.size(); ++i)
+ {
+ report << "Failure " << (i+1) << ": " << m_fail_log[i] << "\n";
+ }
+
+ if(m_fail_log.size() > 0 || tests_run() == 0)
+ {
+ for(size_t i = 0; i != m_log.size(); ++i)
{
- if(fixed_name != "")
- test_report(fixed_name, algo_count, algo_fail);
-
- test_count += algo_count;
- test_fails += algo_fail;
- algo_count = 0;
- algo_fail = 0;
- fixed_name = line.substr(1, line.size() - 2);
- vars[name_key] = fixed_name;
- continue;
+ report << "Note " << (i+1) << ": " << m_log[i] << "\n";
}
+ }
- const std::string key = line.substr(0, line.find_first_of(' '));
- const std::string val = line.substr(line.find_last_of(' ') + 1, std::string::npos);
+ return report.str();
+ }
- vars[key] = val;
+// static Test:: functions
+//static
+std::map<std::string, std::unique_ptr<Test>>& Test::global_registry()
+ {
+ static std::map<std::string, std::unique_ptr<Test>> g_test_registry;
+ return g_test_registry;
+ }
+
+namespace {
+
+template<typename K, typename V>
+std::set<K> map_keys_as_set(const std::map<K, V>& kv)
+ {
+ std::set<K> s;
+ for(auto&& i : kv)
+ {
+ s.insert(i.first);
+ }
+ return s;
+ }
+
+}
+
+//static
+uint64_t Test::timestamp()
+ {
+ auto now = std::chrono::high_resolution_clock::now().time_since_epoch();
+ return std::chrono::duration_cast<std::chrono::nanoseconds>(now).count();
+ }
+
+//static
+std::set<std::string> Test::registered_tests()
+ {
+ return map_keys_as_set(Test::global_registry());
+ }
+
+//static
+Test* Test::get_test(const std::string& test_name)
+ {
+ auto i = Test::global_registry().find(test_name);
+ if(i != Test::global_registry().end())
+ return i->second.get();
+ return nullptr;
+ }
- if(key == name_key)
- fixed_name.clear();
+//static
+std::vector<Test::Result> Test::run_test(const std::string& test_name, bool fail_if_missing)
+ {
+ std::vector<Test::Result> results;
- if(key == output_key)
+ try
+ {
+ if(Test* test = get_test(test_name))
{
- //std::cout << vars[name_key] << " " << algo_count << std::endl;
- ++algo_count;
- try
- {
- const size_t fails = cb(vars);
+ std::vector<Test::Result> test_results = test->run();
+ results.insert(results.end(), test_results.begin(), test_results.end());
+ }
+ else
+ {
+ Test::Result result(test_name);
+ if(fail_if_missing)
+ result.test_failure("Test missing or unavailable");
+ else
+ result.test_note("Test missing or unavailable");
+ results.push_back(result);
+ }
+ }
+ catch(std::exception& e)
+ {
+ results.push_back(Test::Result::Failure(test_name, e.what()));
+ }
+ catch(...)
+ {
+ results.push_back(Test::Result::Failure(test_name, "unknown exception"));
+ }
- if(fails)
- {
- std::cout << vars[name_key] << " test " << algo_count << ": " << fails << " failure" << std::endl;
- algo_fail += fails;
- }
- }
- catch(std::exception& e)
- {
- std::cout << vars[name_key] << " test " << algo_count << " failed: " << e.what() << std::endl;
- ++algo_fail;
- }
+ return results;
+ }
- if(clear_between_cb)
- {
- vars.clear();
- vars[name_key] = fixed_name;
- }
+//static
+std::string Test::data_dir(const std::string& what)
+ {
+ return std::string(TEST_DATA_DIR) + "/" + what;
+ }
+
+//static
+std::string Test::data_file(const std::string& what)
+ {
+ return std::string(TEST_DATA_DIR) + "/" + what;
+ }
+
+//static
+std::string Test::full_path_for_output_file(const std::string& base)
+ {
+ return std::string(TEST_OUTDATA_DIR) + "/" + base;
+ }
+
+// static member variables of Test
+Botan::RandomNumberGenerator* Test::m_test_rng = nullptr;
+size_t Test::m_soak_level = 0;
+bool Test::m_log_success = false;
+
+//static
+void Test::setup_tests(size_t soak, bool log_success, Botan::RandomNumberGenerator* rng)
+ {
+ m_soak_level = soak;
+ m_log_success = log_success;
+ m_test_rng = rng;
+ }
+
+//static
+size_t Test::soak_level()
+ {
+ return m_soak_level;
+ }
+
+//static
+bool Test::log_success()
+ {
+ return m_log_success;
+ }
+
+//static
+Botan::RandomNumberGenerator& Test::rng()
+ {
+ if(!m_test_rng)
+ throw std::runtime_error("Test RNG not initialized");
+ return *m_test_rng;
+ }
+
+std::string Test::random_password()
+ {
+ const size_t len = 1 + Test::rng().next_byte() % 32;
+ return Botan::hex_encode(Test::rng().random_vec(len));
+ }
+
+Text_Based_Test::Text_Based_Test(const std::string& data_src,
+ const std::vector<std::string>& required_keys,
+ const std::vector<std::string>& optional_keys) :
+ m_data_src(data_src)
+ {
+ if(required_keys.empty())
+ throw std::runtime_error("Invalid test spec");
+
+ m_required_keys.insert(required_keys.begin(), required_keys.end());
+ m_optional_keys.insert(optional_keys.begin(), optional_keys.end());
+ m_output_key = required_keys.at(required_keys.size() - 1);
+ }
+
+Text_Based_Test::Text_Based_Test(const std::string& algo,
+ const std::string& data_src,
+ const std::vector<std::string>& required_keys,
+ const std::vector<std::string>& optional_keys) :
+ m_algo(algo),
+ m_data_src(data_src)
+ {
+ if(required_keys.empty())
+ throw std::runtime_error("Invalid test spec");
+
+ m_required_keys.insert(required_keys.begin(), required_keys.end());
+ m_optional_keys.insert(optional_keys.begin(), optional_keys.end());
+ m_output_key = required_keys.at(required_keys.size() - 1);
+ }
+
+std::vector<uint8_t> Text_Based_Test::get_req_bin(const VarMap& vars,
+ const std::string& key) const
+ {
+ auto i = vars.find(key);
+ if(i == vars.end())
+ throw std::runtime_error("Test missing variable " + key);
+
+ try
+ {
+ return Botan::hex_decode(i->second);
+ }
+ catch(std::exception& e)
+ {
+ throw std::runtime_error("Test invalid hex input '" + i->second + "'" +
+ + " for key " + key);
}
}
- test_count += algo_count;
- test_fails += algo_fail;
+std::string Text_Based_Test::get_opt_str(const VarMap& vars,
+ const std::string& key, const std::string& def_value) const
- if(fixed_name != "" && (algo_count > 0 || algo_fail > 0))
- test_report(fixed_name, algo_count, algo_fail);
- else
- test_report(name_key, test_count, test_fails);
+ {
+ auto i = vars.find(key);
+ if(i == vars.end())
+ return def_value;
+ return i->second;
+ }
- return test_fails;
+size_t Text_Based_Test::get_req_sz(const VarMap& vars, const std::string& key) const
+ {
+ auto i = vars.find(key);
+ if(i == vars.end())
+ throw std::runtime_error("Test missing variable " + key);
+ return Botan::to_u32bit(i->second);
}
-size_t run_tests(const std::string& filename,
- const std::string& name_key,
- const std::string& output_key,
- bool clear_between_cb,
- std::function<std::string (std::map<std::string, std::string>)> cb)
+size_t Text_Based_Test::get_opt_sz(const VarMap& vars, const std::string& key, const size_t def_value) const
{
- std::ifstream vec(filename);
+ auto i = vars.find(key);
+ if(i == vars.end())
+ return def_value;
+ return Botan::to_u32bit(i->second);
+ }
- if(!vec)
+std::vector<uint8_t> Text_Based_Test::get_opt_bin(const VarMap& vars,
+ const std::string& key) const
+ {
+ auto i = vars.find(key);
+ if(i == vars.end())
+ return std::vector<uint8_t>();
+
+ try
{
- std::cout << "Failure opening " << filename << std::endl;
- return 1;
+ return Botan::hex_decode(i->second);
}
+ catch(std::exception& e)
+ {
+ throw std::runtime_error("Test invalid hex input '" + i->second + "'" +
+ + " for key " + key);
+ }
+ }
- return run_tests(vec, name_key, output_key, clear_between_cb, cb);
+std::string Text_Based_Test::get_req_str(const VarMap& vars, const std::string& key) const
+ {
+ auto i = vars.find(key);
+ if(i == vars.end())
+ throw std::runtime_error("Test missing variable " + key);
+ return i->second;
}
-size_t run_tests(std::istream& src,
- const std::string& name_key,
- const std::string& output_key,
- bool clear_between_cb,
- std::function<std::string (std::map<std::string, std::string>)> cb)
+#if defined(BOTAN_HAS_BIGINT)
+Botan::BigInt Text_Based_Test::get_req_bn(const VarMap& vars,
+ const std::string& key) const
{
- return run_tests_bb(src, name_key, output_key, clear_between_cb,
- [name_key,output_key,cb](std::map<std::string, std::string> vars)
- {
- const std::string got = cb(vars);
- if(got != vars[output_key])
- {
- std::cout << name_key << ' ' << vars[name_key] << " got " << got
- << " expected " << vars[output_key] << std::endl;
- return 1;
- }
- return 0;
- });
+ auto i = vars.find(key);
+ if(i == vars.end())
+ throw std::runtime_error("Test missing variable " + key);
+
+ try
+ {
+ return Botan::BigInt(i->second);
+ }
+ catch(std::exception& e)
+ {
+ throw std::runtime_error("Test invalid bigint input '" + i->second + "' for key " + key);
+ }
+ }
+#endif
+
+std::string Text_Based_Test::get_next_line()
+ {
+ while(true)
+ {
+ if(m_cur == nullptr || m_cur->good() == false)
+ {
+ if(m_srcs.empty())
+ {
+ if(m_first)
+ {
+ if(m_data_src.find(".vec") != std::string::npos)
+ {
+ m_srcs.push_back(m_data_src);
+ }
+ else
+ {
+ const auto fs = Botan::get_files_recursive(m_data_src);
+ m_srcs.assign(fs.begin(), fs.end());
+ if(m_srcs.empty())
+ throw std::runtime_error("Error reading test data dir " + m_data_src);
+ }
+
+ m_first = false;
+ }
+ else
+ {
+ return ""; // done
+ }
+ }
+
+ m_cur.reset(new std::ifstream(m_srcs[0]));
+
+ if(!m_cur->good())
+ throw std::runtime_error("Could not open input file '" + m_srcs[0]);
+
+ m_srcs.pop_front();
+ }
+
+ while(m_cur->good())
+ {
+ std::string line;
+ std::getline(*m_cur, line);
+
+ if(line == "")
+ continue;
+
+ if(line[0] == '#')
+ continue;
+
+ return line;
+ }
+ }
}
namespace {
-int help(char* argv0)
+// strips leading and trailing but not internal whitespace
+std::string strip_ws(const std::string& in)
{
- std::cout << "Usage: " << argv0 << " [suite]" << std::endl;
- std::cout << "Suites: all (default), block, hash, bigint, rsa, ecdsa, ..." << std::endl;
- return 1;
+ const char* whitespace = " ";
+
+ const auto first_c = in.find_first_not_of(whitespace);
+ if(first_c == std::string::npos)
+ return "";
+
+ const auto last_c = in.find_last_not_of(whitespace);
+
+ return in.substr(first_c, last_c - first_c + 1);
}
-int test_catchy()
+}
+
+std::vector<Test::Result> Text_Based_Test::run()
{
- // drop arc and arv for now
- int catchy_result = Catch::Session().run();
- if (catchy_result != 0)
+ std::vector<Test::Result> results;
+
+ std::string who;
+ VarMap vars;
+ size_t test_cnt = 0;
+
+ while(true)
{
- std::exit(EXIT_FAILURE);
+ const std::string line = get_next_line();
+ if(line == "") // EOF
+ break;
+
+ if(line[0] == '[' && line[line.size()-1] == ']')
+ {
+ who = line.substr(1, line.size() - 2);
+ test_cnt = 0;
+ continue;
+ }
+
+ const std::string test_id = "test " + std::to_string(test_cnt);
+
+ auto equal_i = line.find_first_of('=');
+
+ if(equal_i == std::string::npos)
+ {
+ results.push_back(Test::Result::Failure(who, "invalid input '" + line + "'"));
+ continue;
+ }
+
+ std::string key = strip_ws(std::string(line.begin(), line.begin() + equal_i - 1));
+ std::string val = strip_ws(std::string(line.begin() + equal_i + 1, line.end()));
+
+ if(m_required_keys.count(key) == 0 && m_optional_keys.count(key) == 0)
+ results.push_back(Test::Result::Failure(who, test_id + " failed unknown key " + key));
+
+ vars[key] = val;
+
+ if(key == m_output_key)
+ {
+ try
+ {
+ ++test_cnt;
+
+ uint64_t start = Test::timestamp();
+ Test::Result result = run_one_test(who, vars);
+ result.set_ns_consumed(Test::timestamp() - start);
+
+ if(result.tests_failed())
+ result.test_note("Test #" + std::to_string(test_cnt) + " failed");
+ results.push_back(result);
+ }
+ catch(std::exception& e)
+ {
+ results.push_back(Test::Result::Failure(who, "test " + std::to_string(test_cnt) + " failed with exception '" + e.what() + "'"));
+ }
+
+ if(clear_between_callbacks())
+ {
+ vars.clear();
+ }
+ }
}
- return 0;
+
+ std::vector<Test::Result> final_tests = run_final_tests();
+ results.insert(results.end(), final_tests.begin(), final_tests.end());
+
+ return results;
}
}
-int main(int argc, char* argv[])
- {
- if(argc != 1 && argc != 2)
- return help(argv[0]);
-
- std::string target = "all";
-
- if(argc == 2)
- target = argv[1];
-
- if(target == "-h" || target == "--help" || target == "help")
- return help(argv[0]);
-
- std::vector<std::pair<std::string, test_fn>> tests;
-
-#define DEF_TEST(test) do { if(target == "all" || target == #test) \
- tests.push_back(std::make_pair(#test, test_ ## test)); \
- } while(0)
-
- // unittesting framework in sub-folder tests/catchy
- DEF_TEST(catchy);
-
- DEF_TEST(block);
- DEF_TEST(modes);
- DEF_TEST(aead);
- DEF_TEST(ocb);
-
- DEF_TEST(stream);
- DEF_TEST(hash);
- DEF_TEST(mac);
- DEF_TEST(pbkdf);
- DEF_TEST(kdf);
- DEF_TEST(keywrap);
- DEF_TEST(transform);
- DEF_TEST(rngs);
- DEF_TEST(passhash9);
- DEF_TEST(bcrypt);
- DEF_TEST(cryptobox);
- DEF_TEST(tss);
- DEF_TEST(rfc6979);
- DEF_TEST(srp6);
-
- DEF_TEST(bigint);
-
- DEF_TEST(rsa);
- DEF_TEST(rw);
- DEF_TEST(dsa);
- DEF_TEST(nr);
- DEF_TEST(dh);
- DEF_TEST(dlies);
- DEF_TEST(elgamal);
- DEF_TEST(ecc_pointmul);
- DEF_TEST(ecdsa);
- DEF_TEST(gost_3410);
- DEF_TEST(curve25519);
- DEF_TEST(gf2m);
- DEF_TEST(mceliece);
- DEF_TEST(mce);
-
- DEF_TEST(ecc_unit);
- DEF_TEST(ecc_randomized);
- DEF_TEST(ecdsa_unit);
- DEF_TEST(ecdh_unit);
- DEF_TEST(pk_keygen);
- DEF_TEST(cvc);
- DEF_TEST(x509);
- DEF_TEST(x509_x509test);
- DEF_TEST(nist_x509);
- DEF_TEST(tls);
- DEF_TEST(compression);
- DEF_TEST(fuzzer);
-
- if(tests.empty())
- {
- std::cout << "No tests selected by target '" << target << "'" << std::endl;
- return 1;
- }
-
- return run_tests(tests);
- }
diff --git a/src/tests/tests.h b/src/tests/tests.h
index 1e496ccb2..9f511c4fb 100644
--- a/src/tests/tests.h
+++ b/src/tests/tests.h
@@ -1,3 +1,4 @@
+
/*
* (C) 2014,2015 Jack Lloyd
* (C) 2015 Simon Warta (Kullo GmbH)
@@ -10,198 +11,368 @@
#include <botan/build.h>
#include <botan/rng.h>
+#include <botan/hex.h>
+
+#if defined(BOTAN_HAS_BIGINT)
+ #include <botan/bigint.h>
+#endif
+
+#if defined(BOTAN_HAS_EC_CURVE_GFP)
+ #include <botan/point_gfp.h>
+#endif
+
+#include <fstream>
#include <functional>
-#include <istream>
#include <map>
+#include <memory>
+#include <set>
+#include <sstream>
#include <string>
+#include <unordered_map>
#include <vector>
-#include <iostream>
-#include <sstream>
-Botan::RandomNumberGenerator& test_rng();
+namespace Botan_Tests {
+
+using Botan::byte;
+
+#if defined(BOTAN_HAS_BIGINT)
+using Botan::BigInt;
+#endif
+
+/*
+* A generic test which retuns a set of results when run.
+* The tests may not all have the same type (for example test
+* "block" returns results for "AES-128" and "AES-256").
+*
+* For most test cases you want Text_Based_Test derived below
+*/
+class Test
+ {
+ public:
+
+ /*
+ * Some number of test results, all associated with who()
+ */
+ class Result
+ {
+ public:
+ Result(const std::string& who = "") : m_who(who) {}
+
+ size_t tests_passed() const { return m_tests_passed; }
+ size_t tests_failed() const { return m_fail_log.size(); }
+ size_t tests_run() const { return tests_passed() + tests_failed(); }
+ bool any_results() const { return tests_run() > 0; }
+
+ const std::string& who() const { return m_who; }
+ std::string result_string() const;
+
+ static Result Failure(const std::string& who,
+ const std::string& what)
+ {
+ Result r(who);
+ r.test_failure(what);
+ return r;
+ }
+
+ static Result Note(const std::string& who,
+ const std::string& what)
+ {
+ Result r(who);
+ r.test_note(what);
+ return r;
+ }
+
+ static Result OfExpectedFailure(bool expecting_failure,
+ const Test::Result& result)
+ {
+ if(!expecting_failure)
+ {
+ return result;
+ }
+
+ if(result.tests_failed() == 0)
+ {
+ Result r = result;
+ r.test_failure("Expected this test to fail, but it did not");
+ return r;
+ }
+ else
+ {
+ Result r(result.who());
+ r.test_note("Got expected failure " + result.result_string());
+ return r;
+ }
+ }
+
+ void merge(const Result& other);
+
+ void test_note(const std::string& note, const char* extra = nullptr);
+
+ void note_missing(const std::string& thing);
+
+ bool test_success(const std::string& note = "");
+
+ bool test_failure(const std::string& err);
+
+ bool test_failure(const char* what, const char* error);
+
+ void test_failure(const char* what, const uint8_t buf[], size_t buf_len);
+
+ template<typename Alloc>
+ void test_failure(const char* what, const std::vector<uint8_t, Alloc>& buf)
+ {
+ test_failure(what, buf.data(), buf.size());
+ }
+
+ bool confirm(const char* what, bool expr)
+ {
+ return test_eq(what, expr, true);
+ }
+
+ template<typename T>
+ bool test_is_eq(const T& produced, const T& expected)
+ {
+ return test_is_eq(nullptr, produced, expected);
+ }
+
+ template<typename T>
+ bool test_is_eq(const char* what, const T& produced, const T& expected)
+ {
+ std::ostringstream out;
+ out << m_who;
+ if(what)
+ {
+ out << " " << what;
+ }
+
+ if(produced == expected)
+ {
+ out << " produced expected result " << produced;
+ return test_success(out.str());
+ }
+ else
+ {
+ out << " produced unexpected result " << produced << " expected " << expected;
+ return test_failure(out.str());
+ }
+ }
+
+ bool test_eq(const char* what, const char* produced, const char* expected);
+ bool test_eq(const char* what, const std::string& produced, const std::string& expected);
+ bool test_eq(const char* what, bool produced, bool expected);
+
+ bool test_eq(const char* what, size_t produced, size_t expected);
+ bool test_lt(const char* what, size_t produced, size_t expected);
+ bool test_gte(const char* what, size_t produced, size_t expected);
+
+ bool test_rc_ok(const char* func, int rc);
+ bool test_rc_fail(const char* func, const char* why, int rc);
+
+#if defined(BOTAN_HAS_BIGINT)
+ bool test_eq(const char* what, const BigInt& produced, const BigInt& expected);
+ bool test_ne(const char* what, const BigInt& produced, const BigInt& expected);
+#endif
-size_t run_tests_bb(std::istream& src,
- const std::string& name_key,
- const std::string& output_key,
- bool clear_between_cb,
- std::function<size_t (std::map<std::string, std::string>)> cb);
+#if defined(BOTAN_HAS_EC_CURVE_GFP)
+ bool test_eq(const char* what, const Botan::PointGFp& a, const Botan::PointGFp& b);
+#endif
-size_t run_tests(std::istream& src,
- const std::string& name_key,
- const std::string& output_key,
- bool clear_between_cb,
- std::function<std::string (std::map<std::string, std::string>)> cb);
+ bool test_eq(const char* producer, const char* what,
+ const uint8_t produced[], size_t produced_len,
+ const uint8_t expected[], size_t expected_len);
+
+ bool test_ne(const char* what,
+ const uint8_t produced[], size_t produced_len,
+ const uint8_t expected[], size_t expected_len);
+
+ template<typename Alloc1, typename Alloc2>
+ bool test_eq(const char* what,
+ const std::vector<uint8_t, Alloc1>& produced,
+ const std::vector<uint8_t, Alloc2>& expected)
+ {
+ return test_eq(nullptr, what,
+ produced.data(), produced.size(),
+ expected.data(), expected.size());
+ }
+
+ template<typename Alloc1, typename Alloc2>
+ bool test_eq(const std::string& producer, const char* what,
+ const std::vector<uint8_t, Alloc1>& produced,
+ const std::vector<uint8_t, Alloc2>& expected)
+ {
+ return test_eq(producer.c_str(), what,
+ produced.data(), produced.size(),
+ expected.data(), expected.size());
+ }
+
+ template<typename Alloc>
+ bool test_eq(const char* what,
+ const std::vector<uint8_t, Alloc>& produced,
+ const char* expected_hex)
+ {
+ const std::vector<byte> expected = Botan::hex_decode(expected_hex);
+ return test_eq(nullptr, what,
+ produced.data(), produced.size(),
+ expected.data(), expected.size());
+ }
+
+ template<typename Alloc1, typename Alloc2>
+ bool test_ne(const char* what,
+ const std::vector<uint8_t, Alloc1>& produced,
+ const std::vector<uint8_t, Alloc2>& expected)
+ {
+ return test_ne(what,
+ produced.data(), produced.size(),
+ expected.data(), expected.size());
+ }
+
+ bool test_throws(const std::string& what, std::function<void ()> fn);
+
+ void set_ns_consumed(uint64_t ns) { m_ns_taken = ns; }
+
+ void start_timer();
+ void end_timer();
+
+ private:
+ std::string m_who;
+ uint64_t m_started = 0;
+ uint64_t m_ns_taken = 0;
+ size_t m_tests_passed = 0;
+ std::vector<std::string> m_fail_log;
+ std::vector<std::string> m_log;
+ };
+
+ class Registration
+ {
+ public:
+ Registration(const std::string& name, Test* test);
+ };
-size_t run_tests(const std::string& filename,
- const std::string& name_key,
- const std::string& output_key,
- bool clear_between_cb,
- std::function<std::string (std::map<std::string, std::string>)> cb);
+ virtual std::vector<Test::Result> run() = 0;
+ virtual ~Test() {}
-size_t run_tests_in_dir(const std::string& dir, std::function<size_t (const std::string&)> fn);
+ static std::vector<Test::Result> run_test(const std::string& what, bool fail_if_missing);
-// Run a list of tests
-typedef std::function<size_t ()> test_fn;
+ static std::map<std::string, std::unique_ptr<Test>>& global_registry();
-size_t run_tests(const std::vector<std::pair<std::string, test_fn>>& tests);
-void test_report(const std::string& name, size_t ran, size_t failed);
+ static std::set<std::string> registered_tests();
-class Test_State
- {
- public:
- void started(const std::string& /*msg*/) { m_tests_run++; }
+ static Test* get_test(const std::string& test_name);
- void test_ran(const char* msg);
+ static std::string data_dir(const std::string& what);
+ static std::string data_file(const std::string& what);
+ static std::string full_path_for_output_file(const std::string& base);
- void failure(const char* test, const std::string& what_failed)
+ template<typename Alloc>
+ static std::vector<uint8_t, Alloc> mutate_vec(const std::vector<uint8_t, Alloc>& v, bool maybe_resize = false)
{
- std::cout << "FAIL " << test << " " << what_failed << "\n";
- m_tests_failed++;
+ auto& rng = Test::rng();
+
+ std::vector<uint8_t, Alloc> r = v;
+
+ if(maybe_resize && (r.empty() || rng.next_byte() < 32))
+ {
+ // TODO: occasionally truncate, insert at random index
+ const size_t add = 1 + (rng.next_byte() % 16);
+ r.resize(r.size() + add);
+ rng.randomize(&r[r.size() - add], add);
+ }
+
+ if(r.size() > 0)
+ {
+ const size_t offset = rng.get_random<uint16_t>() % r.size();
+ r[offset] ^= rng.next_nonzero_byte();
+ }
+
+ return r;
}
- size_t ran() const { return m_tests_run; }
- size_t failed() const { return m_tests_failed; }
+ static void setup_tests(size_t soak, bool log_succcss, Botan::RandomNumberGenerator* rng);
+
+ static size_t soak_level();
+ static bool log_success();
+
+ static Botan::RandomNumberGenerator& rng();
+ static std::string random_password();
+ static uint64_t timestamp(); // nanoseconds arbitrary epoch
+
private:
- size_t m_tests_run = 0, m_tests_failed = 0;
+ static Botan::RandomNumberGenerator* m_test_rng;
+ static size_t m_soak_level;
+ static bool m_log_success;
};
-#define BOTAN_CONFIRM_NOTHROW(block) do { \
- try { block } \
- catch(std::exception& e) { \
- _test.failure(BOTAN_CURRENT_FUNCTION, e.what()); \
- } } while(0) \
-
-#define BOTAN_TEST(lhs, rhs, msg) do { \
- _test.started(msg); \
- BOTAN_CONFIRM_NOTHROW({ \
- const auto lhs_val = lhs; \
- const auto rhs_val = rhs; \
- const bool cmp = lhs_val == rhs_val; \
- if(!cmp) \
- { \
- std::ostringstream fmt; \
- fmt << "expr '" << #lhs << " == " << #rhs << "' false, " \
- << "actually " << lhs_val << " " << rhs_val \
- << " (" << msg << ")"; \
- _test.failure(BOTAN_CURRENT_FUNCTION, fmt.str()); \
- } \
- }); \
- } while(0)
-
-#define BOTAN_CONFIRM(expr, msg) do { \
- _test.started(msg); \
- BOTAN_CONFIRM_NOTHROW({ \
- const bool expr_val = expr; \
- if(!expr_val) \
- { \
- std::ostringstream fmt; \
- fmt << "expr '" << #expr << " false (" << msg << ")"; \
- _test.failure(BOTAN_CURRENT_FUNCTION, fmt.str()); \
- } \
- }); \
- } while(0)
-
-#define BOTAN_TEST_CASE(name, descr, block) size_t test_ ## name() { \
- Test_State _test; \
- BOTAN_CONFIRM_NOTHROW(block); \
- test_report(descr, _test.ran(), _test.failed()); \
- return _test.failed(); \
- }
-
-//#define TEST(expr, msg) do { if(!(expr)) { ++fails; std::cout << msg; } while(0)
-
-#define TEST_DATA_DIR "src/tests/data"
-#define TEST_DATA_DIR_PK "src/tests/data/pubkey"
-#define TEST_DATA_DIR_ECC "src/tests/data/ecc"
-
-#define TEST_OUTDATA_DIR "src/tests/outdata"
-
-int test_main(int argc, char* argv[]);
-
-// Tests using reader framework above
-size_t test_block();
-size_t test_stream();
-size_t test_hash();
-size_t test_mac();
-size_t test_modes();
-size_t test_rngs();
-size_t test_pbkdf();
-size_t test_kdf();
-size_t test_aead();
-size_t test_transform();
-
-size_t test_rsa();
-size_t test_rw();
-size_t test_dsa();
-size_t test_nr();
-size_t test_dh();
-size_t test_dlies();
-size_t test_elgamal();
-size_t test_ecc_pointmul();
-size_t test_ecc_random();
-size_t test_ecdsa();
-size_t test_gost_3410();
-size_t test_curve25519();
-size_t test_gf2m();
-size_t test_mceliece();
-size_t test_mce();
-
-// One off tests
-size_t test_ocb();
-size_t test_keywrap();
-size_t test_bcrypt();
-size_t test_passhash9();
-size_t test_cryptobox();
-size_t test_tss();
-size_t test_rfc6979();
-
-size_t test_pk_keygen();
-
-size_t test_bigint();
-
-size_t test_ecc_unit();
-size_t test_ecc_randomized();
-size_t test_ecdsa_unit();
-size_t test_ecdh_unit();
-
-size_t test_x509();
-size_t test_x509_x509test();
-size_t test_cvc();
-
-size_t test_tls();
-
-size_t test_nist_x509();
-
-size_t test_srp6();
-size_t test_compression();
-
-size_t test_fuzzer();
-
-#define SKIP_TEST(testname) \
- size_t test_ ## testname() { \
- std::cout << "Skipping tests: " << # testname << std::endl; \
- return 0; \
- } \
+/*
+* Register the test with the runner
+*/
+#define BOTAN_REGISTER_TEST(type, Test_Class) namespace { Test::Registration reg_ ## Test_Class ## _tests(type, new Test_Class); }
/*
- * Warn if a test requires loading more modules than necessary to build
- * the lib. E.g.
- * $ ./configure.py --no-autoload --enable-modules='ocb'
- * $ make
- * $ ./botan-test ocb
- * warns the user whereas
- * $ ./configure.py --no-autoload --enable-modules='ocb,aes'
- * $ make
- * $ ./botan-test ocb
- * runs the test.
- */
-#define UNTESTED_WARNING(testname) \
- size_t test_ ## testname() { \
- std::cout << "Skipping tests: " << # testname << std::endl; \
- std::cout << "WARNING: " << # testname << " has been compiled " \
- << "but is not tested due to other missing modules." \
- << std::endl; \
- return 0; \
- } \
+* A test based on reading an input file which contains key/value pairs
+* Special note: the last value in required_key (there must be at least
+* one), is the output key. This triggers the callback.
+*
+* Calls run_one_test with the variables set. If an ini-style [header]
+* is used in the file, then header will be set to that value. This allows
+* splitting up tests between [valid] and [invalid] tests, or different
+* related algorithms tested in the same file. Use the protected get_XXX
+* functions to retrieve formatted values from the VarMap
+*
+* If most of your tests are text-based but you find yourself with a few
+* odds-and-ends tests that you want to do, override run_final_tests which
+* can test whatever it likes and returns a vector of Results.
+*/
+class Text_Based_Test : public Test
+ {
+ public:
+ Text_Based_Test(const std::string& input_file,
+ const std::vector<std::string>& required_keys,
+ const std::vector<std::string>& optional_keys = {});
+
+ Text_Based_Test(const std::string& algo,
+ const std::string& input_file,
+ const std::vector<std::string>& required_keys,
+ const std::vector<std::string>& optional_keys = {});
+
+ virtual bool clear_between_callbacks() const { return true; }
+
+ std::vector<Test::Result> run() override;
+ protected:
+ typedef std::unordered_map<std::string, std::string> VarMap;
+ std::string get_next_line();
+
+ virtual Test::Result run_one_test(const std::string& header,
+ const VarMap& vars) = 0;
+
+ virtual std::vector<Test::Result> run_final_tests() { return std::vector<Test::Result>(); }
+
+ std::vector<uint8_t> get_req_bin(const VarMap& vars, const std::string& key) const;
+ std::vector<uint8_t> get_opt_bin(const VarMap& vars, const std::string& key) const;
+
+#if defined(BOTAN_HAS_BIGINT)
+ Botan::BigInt get_req_bn(const VarMap& vars, const std::string& key) const;
+#endif
+
+ std::string get_req_str(const VarMap& vars, const std::string& key) const;
+ std::string get_opt_str(const VarMap& vars, const std::string& key, const std::string& def_value) const;
+
+ size_t get_req_sz(const VarMap& vars, const std::string& key) const;
+ size_t get_opt_sz(const VarMap& vars, const std::string& key, const size_t def_value) const;
+
+ std::string algo_name() const { return m_algo; }
+ private:
+ std::string m_algo;
+ std::string m_data_src;
+ std::set<std::string> m_required_keys;
+ std::set<std::string> m_optional_keys;
+ std::string m_output_key;
+ bool m_clear_between_cb = false;
+
+ bool m_first = true;
+ std::unique_ptr<std::ifstream> m_cur;
+ std::deque<std::string> m_srcs;
+ };
+
+}
#endif
diff --git a/src/tests/unit_ecc.cpp b/src/tests/unit_ecc.cpp
index bd813b37e..65187a428 100644
--- a/src/tests/unit_ecc.cpp
+++ b/src/tests/unit_ecc.cpp
@@ -1,5 +1,5 @@
/*
-* (C) 2009 Jack Lloyd
+* (C) 2009,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -7,152 +7,265 @@
#include "tests.h"
#if defined(BOTAN_HAS_ECC_GROUP)
+ #include <botan/bigint.h>
+ #include <botan/numthry.h>
+ #include <botan/curve_gfp.h>
+ #include <botan/curve_nistp.h>
+ #include <botan/point_gfp.h>
+ #include <botan/ec_group.h>
+ #include <botan/reducer.h>
+ #include <botan/oids.h>
+ #include <botan/hex.h>
+#endif
+
+namespace Botan_Tests {
-#include <iostream>
-#include <memory>
-#include <botan/bigint.h>
-#include <botan/hex.h>
-#include <botan/numthry.h>
-#include <botan/curve_gfp.h>
-#include <botan/point_gfp.h>
-#include <botan/ec_group.h>
-#include <botan/reducer.h>
-#include <botan/oids.h>
-
-using namespace Botan;
+namespace {
-#define CHECK_MESSAGE(expr, print) try { if(!(expr)) { ++fails; std::cout << "FAILURE: " << print << std::endl; }} catch(std::exception& e) { std::cout << __FUNCTION__ << ": " << e.what() << std::endl; }
-#define CHECK(expr) try { if(!(expr)) { ++fails; std::cout << "FAILURE: " << #expr << std::endl; } } catch(std::exception& e) { std::cout << __FUNCTION__ << ": " << e.what() << std::endl; }
+#if defined(BOTAN_HAS_ECC_GROUP)
-namespace {
+const std::vector<std::string> ec_groups = {
+ "brainpool160r1",
+ "brainpool192r1",
+ "brainpool224r1",
+ "brainpool256r1",
+ "brainpool320r1",
+ "brainpool384r1",
+ "brainpool512r1",
+ "gost_256A",
+ "secp112r1",
+ "secp112r2",
+ "secp128r1",
+ "secp128r2",
+ "secp160k1",
+ "secp160r1",
+ "secp160r2",
+ "secp192k1",
+ "secp192r1",
+ "secp224k1",
+ "secp224r1",
+ "secp256k1",
+ "secp256r1",
+ "secp384r1",
+ "secp521r1",
+ "x962_p192v2",
+ "x962_p192v3",
+ "x962_p239v1",
+ "x962_p239v2",
+ "x962_p239v3"
+ };
-std::ostream& operator<<(std::ostream& out, const PointGFp& point)
+Botan::BigInt test_integer(Botan::RandomNumberGenerator& rng, size_t bits, BigInt max)
{
- out << "(" << point.get_affine_x() << " " << point.get_affine_y() << ")";
- return out;
+ /*
+ Produces integers with long runs of ones and zeros, for testing for
+ carry handling problems.
+ */
+ Botan::BigInt x = 0;
+
+ auto flip_prob = [](size_t i) {
+ if(i % 64 == 0)
+ return .5;
+ if(i % 32 == 0)
+ return .4;
+ if(i % 8 == 0)
+ return .05;
+ return .01;
+ };
+
+ bool active = rng.next_byte() % 2;
+ for(size_t i = 0; i != bits; ++i)
+ {
+ x <<= 1;
+ x += static_cast<int>(active);
+
+ const double prob = flip_prob(i);
+ const double sample = double(rng.next_byte() % 100) / 100.0; // biased
+
+ if(sample < prob)
+ active = !active;
+ }
+
+ if(max > 0)
+ {
+ while(x >= max)
+ {
+ const size_t b = x.bits() - 1;
+ BOTAN_ASSERT(x.get_bit(b) == true, "Set");
+ x.clear_bit(b);
+ }
+ }
+
+ return x;
}
-PointGFp create_random_point(RandomNumberGenerator& rng,
- const CurveGFp& curve)
+Botan::PointGFp create_random_point(Botan::RandomNumberGenerator& rng,
+ const Botan::CurveGFp& curve)
{
- const BigInt& p = curve.get_p();
+ const Botan::BigInt& p = curve.get_p();
- Modular_Reducer mod_p(p);
+ Botan::Modular_Reducer mod_p(p);
while(true)
{
- const BigInt x = BigInt::random_integer(rng, 1, p);
- const BigInt x3 = mod_p.multiply(x, mod_p.square(x));
- const BigInt ax = mod_p.multiply(curve.get_a(), x);
- const BigInt y = mod_p.reduce(x3 + ax + curve.get_b());
- const BigInt sqrt_y = ressol(y, p);
+ const Botan::BigInt x = Botan::BigInt::random_integer(rng, 1, p);
+ const Botan::BigInt x3 = mod_p.multiply(x, mod_p.square(x));
+ const Botan::BigInt ax = mod_p.multiply(curve.get_a(), x);
+ const Botan::BigInt y = mod_p.reduce(x3 + ax + curve.get_b());
+ const Botan::BigInt sqrt_y = ressol(y, p);
if(sqrt_y > 1)
{
BOTAN_ASSERT_EQUAL(mod_p.square(sqrt_y), y, "Square root is correct");
- PointGFp point(curve, x, sqrt_y);
+ Botan::PointGFp point(curve, x, sqrt_y);
return point;
}
}
}
-size_t test_point_turn_on_sp_red_mul()
+class ECC_Randomized_Tests : public Test
{
- size_t fails = 0;
-
- // setting up expected values
- BigInt exp_Qx(std::string("466448783855397898016055842232266600516272889280"));
- BigInt exp_Qy(std::string("1110706324081757720403272427311003102474457754220"));
- BigInt exp_Qz(1);
-
- // performing calculation to test
- std::string p_secp = "ffffffffffffffffffffffffffffffff7fffffff";
- std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
- std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_p_secp = hex_decode(p_secp);
- std::vector<byte> sv_a_secp = hex_decode(a_secp);
- std::vector<byte> sv_b_secp = hex_decode(b_secp);
- std::vector<byte> sv_G_secp_comp = hex_decode(G_secp_comp);
- BigInt bi_p_secp = BigInt::decode(sv_p_secp.data(), sv_p_secp.size());
- BigInt bi_a_secp = BigInt::decode(sv_a_secp.data(), sv_a_secp.size());
- BigInt bi_b_secp = BigInt::decode(sv_b_secp.data(), sv_b_secp.size());
- CurveGFp secp160r1(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP(sv_G_secp_comp, secp160r1);
-
- BigInt d("459183204582304");
-
- PointGFp r1 = d * p_G;
- CHECK(r1.get_affine_x() != 0);
-
- PointGFp p_G2(p_G);
-
- PointGFp r2 = d * p_G2;
- CHECK_MESSAGE(r1 == r2, "error with point mul after extra turn on sp red mul");
- CHECK(r1.get_affine_x() != 0);
-
- PointGFp p_r1 = r1;
- PointGFp p_r2 = r2;
-
- p_r1 *= 2;
- p_r2 *= 2;
- CHECK_MESSAGE(p_r1.get_affine_x() == p_r2.get_affine_x(), "error with mult2 after extra turn on sp red mul");
- CHECK(p_r1.get_affine_x() != 0);
- CHECK(p_r2.get_affine_x() != 0);
- r1 *= 2;
-
- r2 *= 2;
-
- CHECK_MESSAGE(r1 == r2, "error with mult2 after extra turn on sp red mul");
- CHECK_MESSAGE(r1.get_affine_x() == r2.get_affine_x(), "error with mult2 after extra turn on sp red mul");
- CHECK(r1.get_affine_x() != 0);
- r1 += p_G;
- r2 += p_G2;
-
- CHECK_MESSAGE(r1 == r2, "error with op+= after extra turn on sp red mul");
-
- r1 += p_G;
- r2 += p_G2;
-
- CHECK_MESSAGE(r1 == r2, "error with op+= after extra turn on sp red mul for both operands");
- r1 += p_G;
- r2 += p_G2;
-
- CHECK_MESSAGE(r1 == r2, "error with op+= after extra turn on sp red mul for both operands");
- return fails;
+ public:
+ std::vector<Test::Result> run() override;
+ };
+
+std::vector<Test::Result> ECC_Randomized_Tests::run()
+ {
+ std::vector<Test::Result> results;
+ for(auto&& group_name : ec_groups)
+ {
+ Test::Result result("ECC randomized " + group_name);
+
+ Botan::EC_Group group(group_name);
+
+ const Botan::PointGFp& base_point = group.get_base_point();
+ const Botan::BigInt& group_order = group.get_order();
+
+ const Botan::PointGFp inf = base_point * group_order;
+ result.test_eq("infinite order correct", inf.is_zero(), true);
+ result.test_eq("infinity on the curve", inf.on_the_curve(), true);
+
+ try
+ {
+ for(size_t i = 0; i <= Test::soak_level(); ++i)
+ {
+ const size_t h = 1 + (Test::rng().next_byte() % 8);
+ Botan::Blinded_Point_Multiply blind(base_point, group_order, h);
+
+ const Botan::BigInt a = Botan::BigInt::random_integer(Test::rng(), 2, group_order);
+ const Botan::BigInt b = Botan::BigInt::random_integer(Test::rng(), 2, group_order);
+ const Botan::BigInt c = a + b;
+
+ const Botan::PointGFp P = base_point * a;
+ const Botan::PointGFp Q = base_point * b;
+ const Botan::PointGFp R = base_point * c;
+
+ const Botan::PointGFp P1 = blind.blinded_multiply(a, Test::rng());
+ const Botan::PointGFp Q1 = blind.blinded_multiply(b, Test::rng());
+ const Botan::PointGFp R1 = blind.blinded_multiply(c, Test::rng());
+
+ const Botan::PointGFp A1 = P + Q;
+ const Botan::PointGFp A2 = Q + P;
+
+ result.test_eq("p + q", A1, R);
+ result.test_eq("q + p", A2, R);
+
+ result.test_eq("p on the curve", P.on_the_curve(), true);
+ result.test_eq("q on the curve", Q.on_the_curve(), true);
+ result.test_eq("r on the curve", R.on_the_curve(), true);
+ result.test_eq("a1 on the curve", A1.on_the_curve(), true);
+ result.test_eq("a2 on the curve", A2.on_the_curve(), true);
+
+ result.test_eq("P1", P1, P);
+ result.test_eq("Q1", Q1, Q);
+ result.test_eq("R1", R1, R);
+ }
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure(group_name.c_str(), e.what());
+ }
+ results.push_back(result);
+ }
+
+ return results;
}
-size_t test_coordinates()
+BOTAN_REGISTER_TEST("ecc_randomized", ECC_Randomized_Tests);
+
+class NIST_Curve_Reduction_Tests : public Test
{
- size_t fails = 0;
+ public:
+ typedef std::function<void (Botan::BigInt&, Botan::secure_vector<Botan::word>&)> reducer_fn;
+ std::vector<Test::Result> run()
+ {
+ std::vector<Test::Result> results;
+
+#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32)
+ results.push_back(random_redc_test("P-192", Botan::prime_p192(), Botan::redc_p192));
+ results.push_back(random_redc_test("P-224", Botan::prime_p224(), Botan::redc_p224));
+ results.push_back(random_redc_test("P-256", Botan::prime_p256(), Botan::redc_p256));
+ results.push_back(random_redc_test("P-384", Botan::prime_p384(), Botan::redc_p384));
+#endif
+ results.push_back(random_redc_test("P-521", Botan::prime_p521(), Botan::redc_p521));
+ return results;
+ }
+
+ Test::Result random_redc_test(const std::string& prime_name,
+ const Botan::BigInt& p,
+ reducer_fn redc_fn)
+ {
+ const Botan::BigInt p2 = p*p;
+ const size_t p_bits = p.bits();
+
+ Botan::Modular_Reducer p_redc(p);
+ Botan::secure_vector<Botan::word> ws;
+
+ Test::Result result("NIST " + prime_name + " reduction");
+
+ for(size_t i = 0; i <= 10 * Test::soak_level(); ++i)
+ {
+ const Botan::BigInt x = test_integer(Test::rng(), 2*p_bits, p2);
+
+ // TODO: time and report all three approaches
+ const Botan::BigInt v1 = x % p;
+ const Botan::BigInt v2 = p_redc.reduce(x);
- BigInt exp_affine_x(std::string("16984103820118642236896513183038186009872590470"));
- BigInt exp_affine_y(std::string("1373093393927139016463695321221277758035357890939"));
+ Botan::BigInt v3 = x;
+ redc_fn(v3, ws);
+
+ if(!result.test_eq("reference redc", v1, v2) ||
+ !result.test_eq("specialized redc", v2, v3))
+ {
+ result.test_note("failing input" + Botan::hex_encode(Botan::BigInt::encode(x)));
+ }
+ }
+
+ return result;
+ }
+ };
+
+BOTAN_REGISTER_TEST("nist_redc", NIST_Curve_Reduction_Tests);
+
+Test::Result test_coordinates()
+ {
+ Test::Result result("ECC Unit");
+
+ const Botan::BigInt exp_affine_x("16984103820118642236896513183038186009872590470");
+ const Botan::BigInt exp_affine_y("1373093393927139016463695321221277758035357890939");
// precalculation
- std::string p_secp = "ffffffffffffffffffffffffffffffff7fffffff";
- std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
- std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
-
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- CurveGFp secp160r1 (bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_secp_comp, secp160r1 );
- PointGFp p0 = p_G;
- PointGFp p1 = p_G * 2;
- PointGFp point_exp(secp160r1, exp_affine_x, exp_affine_y);
- if(!point_exp.on_the_curve())
- throw Internal_Error("Point not on the curve");
-
- CHECK_MESSAGE(p1.get_affine_x() == exp_affine_x, "p1_x = " << p1.get_affine_x() << "\n" << "exp_x = " << exp_affine_x);
- CHECK_MESSAGE(p1.get_affine_y() == exp_affine_y, "p1_y = " << p1.get_affine_y() << "\n" << "exp_y = " << exp_affine_y);
- return fails;
+ const Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
+ const Botan::PointGFp& p_G = secp160r1.get_base_point();
+ const Botan::PointGFp p0 = p_G;
+ const Botan::PointGFp p1 = p_G * 2;
+ const Botan::PointGFp point_exp(curve, exp_affine_x, exp_affine_y);
+ result.confirm("Point is on the curve", point_exp.on_the_curve());
+
+ result.test_eq("Point affine x", p1.get_affine_x(), exp_affine_x);
+ result.test_eq("Point affine y", p1.get_affine_y(), exp_affine_y);
+ return result;
}
@@ -167,353 +280,247 @@ Version 0.3;
Section 2.1.2
--------
*/
-
-size_t test_point_transformation ()
+Test::Result test_point_transformation ()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
- // get a vailid point
- EC_Group dom_pars(OID("1.3.132.0.8"));
- PointGFp p = dom_pars.get_base_point();
+ // get a valid point
+ Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8"));
+ Botan::PointGFp p = dom_pars.get_base_point() * Test::rng().next_nonzero_byte();
// get a copy
- PointGFp q = p;
+ Botan::PointGFp q = p;
- CHECK_MESSAGE( p.get_affine_x() == q.get_affine_x(), "affine_x changed during copy");
- CHECK_MESSAGE( p.get_affine_y() == q.get_affine_y(), "affine_y changed during copy");
- return fails;
+ result.test_eq("affine x after copy", p.get_affine_x(), q.get_affine_x());
+ result.test_eq("affine y after copy", p.get_affine_y(), q.get_affine_y());
+ return result;
}
-size_t test_point_mult ()
+Test::Result test_point_mult ()
{
- size_t fails = 0;
-
- EC_Group secp160r1(OIDS::lookup("secp160r1"));
+ Test::Result result("ECC Unit");
- const CurveGFp& curve = secp160r1.get_curve();
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::PointGFp& p_G = secp160r1.get_base_point();
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_G_secp_comp = hex_decode(G_secp_comp);
- PointGFp p_G = OS2ECP(sv_G_secp_comp, curve);
+ Botan::BigInt d_U("0xaa374ffc3ce144e6b073307972cb6d57b2a4e982");
+ Botan::PointGFp Q_U = d_U * p_G;
- BigInt d_U("0xaa374ffc3ce144e6b073307972cb6d57b2a4e982");
- PointGFp Q_U = d_U * p_G;
-
- CHECK(Q_U.get_affine_x() == BigInt("466448783855397898016055842232266600516272889280"));
- CHECK(Q_U.get_affine_y() == BigInt("1110706324081757720403272427311003102474457754220"));
- return fails;
+ result.test_eq("affine x", Q_U.get_affine_x(), Botan::BigInt("466448783855397898016055842232266600516272889280"));
+ result.test_eq("affine y", Q_U.get_affine_y(), Botan::BigInt("1110706324081757720403272427311003102474457754220"));
+ return result;
}
-size_t test_point_negative()
+Test::Result test_point_negative()
{
- size_t fails = 0;
-
- // performing calculation to test
- std::string p_secp = "ffffffffffffffffffffffffffffffff7fffffff";
- std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
- std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- CurveGFp secp160r1(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_secp_comp, secp160r1 );
-
- PointGFp p1 = p_G *= 2;
-
- CHECK(p1.get_affine_x() == BigInt("16984103820118642236896513183038186009872590470"));
- CHECK(p1.get_affine_y() == BigInt("1373093393927139016463695321221277758035357890939"));
-
- PointGFp p1_neg = p1.negate();
-
- CHECK(p1_neg.get_affine_x() == BigInt("16984103820118642236896513183038186009872590470"));
- CHECK(p1_neg.get_affine_y() == BigInt("88408243403763901739989511495005261618427168388"));
- return fails;
+ Test::Result result("ECC Unit");
+
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::PointGFp& p_G = secp160r1.get_base_point();
+
+ const Botan::PointGFp p1 = p_G * 2;
+
+ result.test_eq("affine x", p1.get_affine_x(), Botan::BigInt("16984103820118642236896513183038186009872590470"));
+ result.test_eq("affine y", p1.get_affine_y(), Botan::BigInt("1373093393927139016463695321221277758035357890939"));
+
+ const Botan::PointGFp p1_neg = -p1;
+
+ result.test_eq("affine x", p1_neg.get_affine_x(), p1.get_affine_x());
+ result.test_eq("affine y", p1_neg.get_affine_y(), Botan::BigInt("88408243403763901739989511495005261618427168388"));
+ return result;
}
-size_t test_zeropoint()
+Test::Result test_zeropoint()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
- BigInt bi_p_secp("0xffffffffffffffffffffffffffffffff7fffffff");
- BigInt bi_a_secp("0xffffffffffffffffffffffffffffffff7ffffffc");
- BigInt bi_b_secp("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45");
- CurveGFp secp160r1(bi_p_secp, bi_a_secp, bi_b_secp);
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
- PointGFp p1(secp160r1,
- BigInt("16984103820118642236896513183038186009872590470"),
- BigInt("1373093393927139016463695321221277758035357890939"));
+ Botan::PointGFp p1(curve,
+ Botan::BigInt("16984103820118642236896513183038186009872590470"),
+ Botan::BigInt("1373093393927139016463695321221277758035357890939"));
- if(!p1.on_the_curve())
- throw Internal_Error("Point not on the curve");
+ result.confirm("point is on the curve", p1.on_the_curve());
p1 -= p1;
- CHECK_MESSAGE( p1.is_zero(), "p - q with q = p is not zero!");
- return fails;
+ result.confirm("p - q with q = p results in zero", p1.is_zero());
+ return result;
}
-size_t test_zeropoint_enc_dec()
+Test::Result test_zeropoint_enc_dec()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
- BigInt bi_p_secp("0xffffffffffffffffffffffffffffffff7fffffff");
- BigInt bi_a_secp("0xffffffffffffffffffffffffffffffff7ffffffc");
- BigInt bi_b_secp("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45");
- CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
- PointGFp p(curve);
- CHECK_MESSAGE( p.is_zero(), "by constructor created zeropoint is no zeropoint!");
+ Botan::PointGFp p(curve);
+ result.confirm("zero point is zero", p.is_zero());
+ std::vector<byte> sv_p = unlock(EC2OSP(p, Botan::PointGFp::UNCOMPRESSED));
+ result.test_eq("encoded/decode rt works", OS2ECP(sv_p, curve), p);
- std::vector<byte> sv_p = unlock(EC2OSP(p, PointGFp::UNCOMPRESSED));
- PointGFp p_encdec = OS2ECP(sv_p, curve);
- CHECK_MESSAGE( p == p_encdec, "encoded-decoded (uncompressed) point is not equal the original!");
+ sv_p = unlock(EC2OSP(p, Botan::PointGFp::COMPRESSED));
+ result.test_eq("encoded/decode compressed rt works", OS2ECP(sv_p, curve), p);
- sv_p = unlock(EC2OSP(p, PointGFp::UNCOMPRESSED));
- p_encdec = OS2ECP(sv_p, curve);
- CHECK_MESSAGE( p == p_encdec, "encoded-decoded (compressed) point is not equal the original!");
-
- sv_p = unlock(EC2OSP(p, PointGFp::HYBRID));
- p_encdec = OS2ECP(sv_p, curve);
- CHECK_MESSAGE( p == p_encdec, "encoded-decoded (hybrid) point is not equal the original!");
- return fails;
+ sv_p = unlock(EC2OSP(p, Botan::PointGFp::HYBRID));
+ result.test_eq("encoded/decode hybrid rt works", OS2ECP(sv_p, curve), p);
+ return result;
}
-size_t test_calc_with_zeropoint()
+Test::Result test_calc_with_zeropoint()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
- BigInt bi_p_secp("0xffffffffffffffffffffffffffffffff7fffffff");
- BigInt bi_a_secp("0xffffffffffffffffffffffffffffffff7ffffffc");
- BigInt bi_b_secp("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45");
- CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
- PointGFp p(curve,
- BigInt("16984103820118642236896513183038186009872590470"),
- BigInt("1373093393927139016463695321221277758035357890939"));
+ Botan::PointGFp p(curve,
+ Botan::BigInt("16984103820118642236896513183038186009872590470"),
+ Botan::BigInt("1373093393927139016463695321221277758035357890939"));
- if(!p.on_the_curve())
- throw Internal_Error("Point not on the curve");
- CHECK_MESSAGE( !p.is_zero(), "created is zeropoint, shouldn't be!");
+ result.confirm("point is on the curve", p.on_the_curve());
+ result.confirm("point is not zero", !p.is_zero());
- PointGFp zero(curve);
- CHECK_MESSAGE( zero.is_zero(), "by constructor created zeropoint is no zeropoint!");
+ Botan::PointGFp zero(curve);
+ result.confirm("zero point is zero", zero.is_zero());
- PointGFp res = p + zero;
- CHECK_MESSAGE( res == p, "point + zeropoint is not equal the point");
+ Botan::PointGFp res = p + zero;
+ result.test_eq("point + 0 equals the point", p, res);
res = p - zero;
- CHECK_MESSAGE( res == p, "point - zeropoint is not equal the point");
+ result.test_eq("point - 0 equals the point", p, res);
res = zero * 32432243;
- CHECK_MESSAGE( res.is_zero(), "zeropoint * skalar is not a zero-point!");
- return fails;
+ result.confirm("point * 0 is the zero point", res.is_zero());
+ return result;
}
-size_t test_add_point()
+Test::Result test_add_point()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// precalculation
- std::string p_secp = "ffffffffffffffffffffffffffffffff7fffffff";
- std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
- std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- CurveGFp secp160r1(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_secp_comp, secp160r1 );
-
- PointGFp p0 = p_G;
- PointGFp p1 = p_G *= 2;
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
+ const Botan::PointGFp& p_G = secp160r1.get_base_point();
+
+ Botan::PointGFp p0 = p_G;
+ Botan::PointGFp p1 = p_G * 2;
p1 += p0;
- PointGFp expected(secp160r1,
- BigInt("704859595002530890444080436569091156047721708633"),
- BigInt("1147993098458695153857594941635310323215433166682"));
+ Botan::PointGFp expected(curve,
+ Botan::BigInt("704859595002530890444080436569091156047721708633"),
+ Botan::BigInt("1147993098458695153857594941635310323215433166682"));
- CHECK(p1 == expected);
- return fails;
+ result.test_eq("point addition", p1, expected);
+ return result;
}
-size_t test_sub_point()
+Test::Result test_sub_point()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
- //Setting up expected values
- BigInt exp_sub_x(std::string("112913490230515010376958384252467223283065196552"));
- BigInt exp_sub_y(std::string("143464803917389475471159193867377888720776527730"));
- BigInt exp_sub_z(std::string("562006223742588575209908669014372619804457947208"));
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
+ const Botan::PointGFp& p_G = secp160r1.get_base_point();
- // precalculation
- std::string p_secp = "ffffffffffffffffffffffffffffffff7fffffff";
- std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
- std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- CurveGFp secp160r1(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_secp_comp, secp160r1 );
-
- PointGFp p0 = p_G;
- PointGFp p1 = p_G *= 2;
+ Botan::PointGFp p0 = p_G;
+ Botan::PointGFp p1 = p_G * 2;
p1 -= p0;
- PointGFp expected(secp160r1,
- BigInt("425826231723888350446541592701409065913635568770"),
- BigInt("203520114162904107873991457957346892027982641970"));
+ Botan::PointGFp expected(curve,
+ Botan::BigInt("425826231723888350446541592701409065913635568770"),
+ Botan::BigInt("203520114162904107873991457957346892027982641970"));
- CHECK(p1 == expected);
- return fails;
+ result.test_eq("point subtraction", p1, expected);
+ return result;
}
-size_t test_mult_point()
+Test::Result test_mult_point()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
- //Setting up expected values
- BigInt exp_mult_x(std::string("967697346845926834906555988570157345422864716250"));
- BigInt exp_mult_y(std::string("512319768365374654866290830075237814703869061656"));
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
+ const Botan::PointGFp& p_G = secp160r1.get_base_point();
- // precalculation
- std::string p_secp = "ffffffffffffffffffffffffffffffff7fffffff";
- std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
- std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- CurveGFp secp160r1(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_secp_comp, secp160r1 );
-
- PointGFp p0 = p_G;
- PointGFp p1 = p_G *= 2;
+ Botan::PointGFp p0 = p_G;
+ Botan::PointGFp p1 = p_G * 2;
p1 *= p0.get_affine_x();
- PointGFp expected(secp160r1, exp_mult_x, exp_mult_y);
+ const Botan::BigInt exp_mult_x(std::string("967697346845926834906555988570157345422864716250"));
+ const Botan::BigInt exp_mult_y(std::string("512319768365374654866290830075237814703869061656"));
+ Botan::PointGFp expected(curve, exp_mult_x, exp_mult_y);
- CHECK(p1 == expected);
- return fails;
+ result.test_eq("point mult", p1, expected);
+ return result;
}
-size_t test_basic_operations()
+Test::Result test_basic_operations()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// precalculation
- std::string p_secp = "ffffffffffffffffffffffffffffffff7fffffff";
- std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
- std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- CurveGFp secp160r1(bi_p_secp, bi_a_secp, bi_b_secp);
-
- PointGFp p_G = OS2ECP ( sv_G_secp_comp, secp160r1 );
-
- PointGFp p0 = p_G;
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
+ const Botan::PointGFp& p_G = secp160r1.get_base_point();
- PointGFp expected(secp160r1,
- BigInt("425826231723888350446541592701409065913635568770"),
- BigInt("203520114162904107873991457957346892027982641970"));
+ const Botan::PointGFp p0 = p_G;
+ const Botan::PointGFp p1 = p_G * 2;
- CHECK(p0 == expected);
+ result.test_eq("p1 affine x", p1.get_affine_x(), Botan::BigInt("16984103820118642236896513183038186009872590470"));
+ result.test_eq("p1 affine y", p1.get_affine_y(), Botan::BigInt("1373093393927139016463695321221277758035357890939"));
- PointGFp p1 = p_G *= 2;
+ const Botan::PointGFp simplePlus = p1 + p0;
+ const Botan::PointGFp exp_simplePlus(curve,
+ Botan::BigInt("704859595002530890444080436569091156047721708633"),
+ Botan::BigInt("1147993098458695153857594941635310323215433166682"));
- CHECK(p1.get_affine_x() == BigInt("16984103820118642236896513183038186009872590470"));
- CHECK(p1.get_affine_y() == BigInt("1373093393927139016463695321221277758035357890939"));
+ result.test_eq("point addition", simplePlus, exp_simplePlus);
- PointGFp simplePlus= p1 + p0;
- PointGFp exp_simplePlus(secp160r1,
- BigInt("704859595002530890444080436569091156047721708633"),
- BigInt("1147993098458695153857594941635310323215433166682"));
- if(simplePlus != exp_simplePlus)
- std::cout << simplePlus << " != " << exp_simplePlus << std::endl;
+ const Botan::PointGFp simpleMinus = p1 - p0;
+ const Botan::PointGFp exp_simpleMinus(curve,
+ Botan::BigInt("425826231723888350446541592701409065913635568770"),
+ Botan::BigInt("203520114162904107873991457957346892027982641970"));
- PointGFp simpleMinus= p1 - p0;
- PointGFp exp_simpleMinus(secp160r1,
- BigInt("425826231723888350446541592701409065913635568770"),
- BigInt("203520114162904107873991457957346892027982641970"));
+ result.test_eq("point subtraction", simpleMinus, exp_simpleMinus);
- CHECK(simpleMinus == exp_simpleMinus);
+ const Botan::PointGFp simpleMult = p1 * 123456789;
- PointGFp simpleMult= p1 * 123456789;
+ result.test_eq("point mult affine x", simpleMult.get_affine_x(),
+ Botan::BigInt("43638877777452195295055270548491599621118743290"));
+ result.test_eq("point mult affine y", simpleMult.get_affine_y(),
+ Botan::BigInt("56841378500012376527163928510402662349220202981"));
- CHECK(simpleMult.get_affine_x() == BigInt("43638877777452195295055270548491599621118743290"));
- CHECK(simpleMult.get_affine_y() == BigInt("56841378500012376527163928510402662349220202981"));
-
- // check that all initial points hasn't changed
- CHECK(p1.get_affine_x() == BigInt("16984103820118642236896513183038186009872590470"));
- CHECK(p1.get_affine_y() == BigInt("1373093393927139016463695321221277758035357890939"));
-
- CHECK(p0.get_affine_x() == BigInt("425826231723888350446541592701409065913635568770"));
- CHECK(p0.get_affine_y() == BigInt("203520114162904107873991457957346892027982641970"));
- return fails;
+ return result;
}
-size_t test_enc_dec_compressed_160()
+Test::Result test_enc_dec_compressed_160()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// Test for compressed conversion (02/03) 160bit
- std::string p_secp = "ffffffffffffffffffffffffffffffff7fffffff";
- std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffC";
- std::string b_secp = "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45";
- std::string G_secp_comp = "024A96B5688EF573284664698968C38BB913CBFC82";
- std::string G_order_secp_comp = "0100000000000000000001F4C8F927AED3CA752257";
-
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
+ const std::vector<byte> G_comp = Botan::hex_decode("024A96B5688EF573284664698968C38BB913CBFC82");
- CurveGFp secp160r1(bi_p_secp, bi_a_secp, bi_b_secp);
+ const Botan::PointGFp p = Botan::OS2ECP(G_comp, curve);
- PointGFp p_G = OS2ECP ( sv_G_secp_comp, secp160r1 );
- std::vector<byte> sv_result = unlock(EC2OSP(p_G, PointGFp::COMPRESSED));
+ std::vector<byte> sv_result = unlock(Botan::EC2OSP(p, Botan::PointGFp::COMPRESSED));
- CHECK( sv_result == sv_G_secp_comp);
- return fails;
+ result.test_eq("result", sv_result, G_comp);
+ return result;
}
-size_t test_enc_dec_compressed_256()
+Test::Result test_enc_dec_compressed_256()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// Test for compressed conversion (02/03) 256bit
std::string p_secp = "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff";
@@ -522,28 +529,28 @@ size_t test_enc_dec_compressed_256()
std::string G_secp_comp = "036B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296";
std::string G_order_secp_comp = "ffffffff00000000ffffffffffffffffBCE6FAADA7179E84F3B9CAC2FC632551";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
+ std::vector<byte> sv_p_secp = Botan::hex_decode ( p_secp );
+ std::vector<byte> sv_a_secp = Botan::hex_decode ( a_secp );
+ std::vector<byte> sv_b_secp = Botan::hex_decode ( b_secp );
+ std::vector<byte> sv_G_secp_comp = Botan::hex_decode ( G_secp_comp );
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
+ Botan::BigInt bi_p_secp = Botan::BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
+ Botan::BigInt bi_a_secp = Botan::BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
+ Botan::BigInt bi_b_secp = Botan::BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
+ Botan::CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_secp_comp, curve );
- std::vector<byte> sv_result = unlock(EC2OSP(p_G, PointGFp::COMPRESSED));
+ Botan::PointGFp p_G = OS2ECP ( sv_G_secp_comp, curve );
+ std::vector<byte> sv_result = unlock(EC2OSP(p_G, Botan::PointGFp::COMPRESSED));
- CHECK( sv_result == sv_G_secp_comp);
- return fails;
+ result.test_eq("compressed_256", sv_result, sv_G_secp_comp);
+ return result;
}
-size_t test_enc_dec_uncompressed_112()
+Test::Result test_enc_dec_uncompressed_112()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// Test for uncompressed conversion (04) 112bit
@@ -553,27 +560,27 @@ size_t test_enc_dec_uncompressed_112()
std::string G_secp_uncomp = "044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97";
std::string G_order_secp_uncomp = "36DF0AAFD8B8D7597CA10520D04B";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_uncomp = hex_decode ( G_secp_uncomp );
+ std::vector<byte> sv_p_secp = Botan::hex_decode ( p_secp );
+ std::vector<byte> sv_a_secp = Botan::hex_decode ( a_secp );
+ std::vector<byte> sv_b_secp = Botan::hex_decode ( b_secp );
+ std::vector<byte> sv_G_secp_uncomp = Botan::hex_decode ( G_secp_uncomp );
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
+ Botan::BigInt bi_p_secp = Botan::BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
+ Botan::BigInt bi_a_secp = Botan::BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
+ Botan::BigInt bi_b_secp = Botan::BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
+ Botan::CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_secp_uncomp, curve );
- std::vector<byte> sv_result = unlock(EC2OSP(p_G, PointGFp::UNCOMPRESSED));
+ Botan::PointGFp p_G = OS2ECP ( sv_G_secp_uncomp, curve );
+ std::vector<byte> sv_result = unlock(EC2OSP(p_G, Botan::PointGFp::UNCOMPRESSED));
- CHECK( sv_result == sv_G_secp_uncomp);
- return fails;
+ result.test_eq("uncompressed_112", sv_result, sv_G_secp_uncomp);
+ return result;
}
-size_t test_enc_dec_uncompressed_521()
+Test::Result test_enc_dec_uncompressed_521()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// Test for uncompressed conversion(04) with big values(521 bit)
std::string p_secp = "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
@@ -582,30 +589,28 @@ size_t test_enc_dec_uncompressed_521()
std::string G_secp_uncomp = "0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2ffA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650";
std::string G_order_secp_uncomp = "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_uncomp = hex_decode ( G_secp_uncomp );
+ std::vector<byte> sv_p_secp = Botan::hex_decode ( p_secp );
+ std::vector<byte> sv_a_secp = Botan::hex_decode ( a_secp );
+ std::vector<byte> sv_b_secp = Botan::hex_decode ( b_secp );
+ std::vector<byte> sv_G_secp_uncomp = Botan::hex_decode ( G_secp_uncomp );
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
+ Botan::BigInt bi_p_secp = Botan::BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
+ Botan::BigInt bi_a_secp = Botan::BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
+ Botan::BigInt bi_b_secp = Botan::BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
+ Botan::CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_secp_uncomp, curve );
+ Botan::PointGFp p_G = Botan::OS2ECP ( sv_G_secp_uncomp, curve );
- std::vector<byte> sv_result = unlock(EC2OSP(p_G, PointGFp::UNCOMPRESSED));
- std::string result = hex_encode(sv_result.data(), sv_result.size());
- std::string exp_result = hex_encode(sv_G_secp_uncomp.data(), sv_G_secp_uncomp.size());
+ std::vector<byte> sv_result = unlock(EC2OSP(p_G, Botan::PointGFp::UNCOMPRESSED));
- CHECK_MESSAGE(sv_result == sv_G_secp_uncomp, "calc. result = " << result << "\nexp. result = " << exp_result);
- return fails;
+ result.test_eq("expected", sv_result, sv_G_secp_uncomp);
+ return result;
}
-size_t test_enc_dec_uncompressed_521_prime_too_large()
+Test::Result test_enc_dec_uncompressed_521_prime_too_large()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// Test for uncompressed conversion(04) with big values(521 bit)
std::string p_secp = "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; // length increased by "ff"
@@ -614,344 +619,221 @@ size_t test_enc_dec_uncompressed_521_prime_too_large()
std::string G_secp_uncomp = "0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2ffA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650";
std::string G_order_secp_uncomp = "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_uncomp = hex_decode ( G_secp_uncomp );
+ std::vector<byte> sv_p_secp = Botan::hex_decode ( p_secp );
+ std::vector<byte> sv_a_secp = Botan::hex_decode ( a_secp );
+ std::vector<byte> sv_b_secp = Botan::hex_decode ( b_secp );
+ std::vector<byte> sv_G_secp_uncomp = Botan::hex_decode ( G_secp_uncomp );
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
+ Botan::BigInt bi_p_secp = Botan::BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
+ Botan::BigInt bi_a_secp = Botan::BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
+ Botan::BigInt bi_b_secp = Botan::BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
+
+ Botan::CurveGFp secp521r1 (bi_p_secp, bi_a_secp, bi_b_secp);
+ std::unique_ptr<Botan::PointGFp> p_G;
- CurveGFp secp521r1 (bi_p_secp, bi_a_secp, bi_b_secp);
- std::unique_ptr<PointGFp> p_G;
- bool exc = false;
try
{
- p_G = std::unique_ptr<PointGFp>(new PointGFp(OS2ECP ( sv_G_secp_uncomp, secp521r1)));
- if(!p_G->on_the_curve())
- throw Internal_Error("Point not on the curve");
+ p_G = std::unique_ptr<Botan::PointGFp>(new Botan::PointGFp(Botan::OS2ECP ( sv_G_secp_uncomp, secp521r1)));
+ result.test_failure("point decoding with too large value accepted");
}
- catch (std::exception e)
+ catch(std::exception& e)
{
- exc = true;
+ result.test_note("rejected invalid point");
}
- CHECK_MESSAGE(exc, "attempt of creation of point on curve with too high prime did not throw an exception");
- return fails;
+ return result;
}
-size_t test_gfp_store_restore()
+Test::Result test_gfp_store_restore()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// generate point
- //EC_Group dom_pars = global_config().get_ec_dompar("1.3.132.0.8");
- //EC_Group dom_pars("1.3.132.0.8");
- EC_Group dom_pars(OID("1.3.132.0.8"));
- PointGFp p = dom_pars.get_base_point();
+ Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8"));
+ Botan::PointGFp p = dom_pars.get_base_point();
- //store point (to std::string)
- std::vector<byte> sv_mes = unlock(EC2OSP(p, PointGFp::COMPRESSED));
- PointGFp new_p = OS2ECP(sv_mes, dom_pars.get_curve());
+ std::vector<byte> sv_mes = unlock(EC2OSP(p, Botan::PointGFp::COMPRESSED));
+ Botan::PointGFp new_p = Botan::OS2ECP(sv_mes, dom_pars.get_curve());
- CHECK_MESSAGE( p == new_p, "original and restored point are different!");
- return fails;
+ result.test_eq("original and restored points are same", p, new_p);
+ return result;
}
// maybe move this test
-size_t test_cdc_curve_33()
+Test::Result test_cdc_curve_33()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
std::string G_secp_uncomp = "04081523d03d4f12cd02879dea4bf6a4f3a7df26ed888f10c5b2235a1274c386a2f218300dee6ed217841164533bcdc903f07a096f9fbf4ee95bac098a111f296f5830fe5c35b3e344d5df3a2256985f64fbe6d0edcc4c61d18bef681dd399df3d0194c5a4315e012e0245ecea56365baa9e8be1f7";
- std::vector<byte> sv_G_uncomp = hex_decode ( G_secp_uncomp );
+ std::vector<byte> sv_G_uncomp = Botan::hex_decode ( G_secp_uncomp );
- BigInt bi_p_secp = BigInt("2117607112719756483104013348936480976596328609518055062007450442679169492999007105354629105748524349829824407773719892437896937279095106809");
- BigInt bi_a_secp("0xa377dede6b523333d36c78e9b0eaa3bf48ce93041f6d4fc34014d08f6833807498deedd4290101c5866e8dfb589485d13357b9e78c2d7fbe9fe");
- BigInt bi_b_secp("0xa9acf8c8ba617777e248509bcb4717d4db346202bf9e352cd5633731dd92a51b72a4dc3b3d17c823fcc8fbda4da08f25dea89046087342595a7");
+ Botan::BigInt bi_p_secp = Botan::BigInt("2117607112719756483104013348936480976596328609518055062007450442679169492999007105354629105748524349829824407773719892437896937279095106809");
+ Botan::BigInt bi_a_secp("0xa377dede6b523333d36c78e9b0eaa3bf48ce93041f6d4fc34014d08f6833807498deedd4290101c5866e8dfb589485d13357b9e78c2d7fbe9fe");
+ Botan::BigInt bi_b_secp("0xa9acf8c8ba617777e248509bcb4717d4db346202bf9e352cd5633731dd92a51b72a4dc3b3d17c823fcc8fbda4da08f25dea89046087342595a7");
- CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_uncomp, curve);
- bool exc = false;
- try
- {
- if(!p_G.on_the_curve())
- throw Internal_Error("Point not on the curve");
- }
- catch (std::exception)
- {
- exc = true;
- }
- CHECK(!exc);
- return fails;
+ Botan::CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
+ Botan::PointGFp p_G = Botan::OS2ECP ( sv_G_uncomp, curve);
+ result.confirm("point is on the curve", p_G.on_the_curve());
+ return result;
}
-size_t test_more_zeropoint()
+Test::Result test_more_zeropoint()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// by Falko
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
+
std::string G = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_G_secp_comp = hex_decode ( G );
- BigInt bi_p("0xffffffffffffffffffffffffffffffff7fffffff");
- BigInt bi_a("0xffffffffffffffffffffffffffffffff7ffffffc");
- BigInt bi_b("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45");
- CurveGFp curve(bi_p, bi_a, bi_b);
-
- PointGFp p1(curve,
- BigInt("16984103820118642236896513183038186009872590470"),
- BigInt("1373093393927139016463695321221277758035357890939"));
-
- if(!p1.on_the_curve())
- throw Internal_Error("Point not on the curve");
- PointGFp minus_p1 = -p1;
- if(!minus_p1.on_the_curve())
- throw Internal_Error("Point not on the curve");
- PointGFp shouldBeZero = p1 + minus_p1;
- if(!shouldBeZero.on_the_curve())
- throw Internal_Error("Point not on the curve");
-
- BigInt y1 = p1.get_affine_y();
+ std::vector<byte> sv_G_secp_comp = Botan::hex_decode ( G );
+
+ Botan::PointGFp p1(curve,
+ Botan::BigInt("16984103820118642236896513183038186009872590470"),
+ Botan::BigInt("1373093393927139016463695321221277758035357890939"));
+
+ result.confirm("point is on the curve", p1.on_the_curve());
+ Botan::PointGFp minus_p1 = -p1;
+ result.confirm("point is on the curve", minus_p1.on_the_curve());
+ Botan::PointGFp shouldBeZero = p1 + minus_p1;
+ result.confirm("point is on the curve", shouldBeZero.on_the_curve());
+ result.confirm("point is zero", shouldBeZero.is_zero());
+
+ Botan::BigInt y1 = p1.get_affine_y();
y1 = curve.get_p() - y1;
- CHECK_MESSAGE(p1.get_affine_x() == minus_p1.get_affine_x(),
- "problem with minus_p1 : x");
- CHECK_MESSAGE(minus_p1.get_affine_y() == y1,
- "problem with minus_p1 : y");
+ result.test_eq("minus point x", minus_p1.get_affine_x(), p1.get_affine_x());
+ result.test_eq("minus point y", minus_p1.get_affine_y(), y1);
- PointGFp zero(curve);
- if(!zero.on_the_curve())
- throw Internal_Error("Point not on the curve");
- CHECK_MESSAGE(p1 + zero == p1, "addition of zero modified point");
+ Botan::PointGFp zero(curve);
+ result.confirm("zero point is on the curve", zero.on_the_curve());
+ result.test_eq("addition of zero does nothing", p1, p1 + zero);
- CHECK_MESSAGE( shouldBeZero.is_zero(), "p - q with q = p is not zero!");
- return fails;
+ return result;
}
-size_t test_mult_by_order()
+Test::Result test_mult_by_order()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// generate point
- EC_Group dom_pars(OID("1.3.132.0.8"));
- PointGFp p = dom_pars.get_base_point();
- PointGFp shouldBeZero = p * dom_pars.get_order();
+ Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8"));
+ Botan::PointGFp p = dom_pars.get_base_point();
+ Botan::PointGFp shouldBeZero = p * dom_pars.get_order();
- CHECK_MESSAGE(shouldBeZero.is_zero(), "G * order != O");
- return fails;
+ result.confirm("G * order = 0", shouldBeZero.is_zero());
+ return result;
}
-size_t test_point_swap()
+Test::Result test_point_swap()
{
- size_t fails = 0;
-
- EC_Group dom_pars(OID("1.3.132.0.8"));
+ Test::Result result("ECC Unit");
- auto& rng = test_rng();
+ Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8"));
- PointGFp a(create_random_point(rng, dom_pars.get_curve()));
- PointGFp b(create_random_point(rng, dom_pars.get_curve()));
- b *= BigInt(rng, 20);
+ Botan::PointGFp a(create_random_point(Test::rng(), dom_pars.get_curve()));
+ Botan::PointGFp b(create_random_point(Test::rng(), dom_pars.get_curve()));
+ b *= Botan::BigInt(Test::rng(), 20);
- PointGFp c(a);
- PointGFp d(b);
+ Botan::PointGFp c(a);
+ Botan::PointGFp d(b);
d.swap(c);
- CHECK(a == d);
- CHECK(b == c);
+ result.test_eq("swap correct", a, d);
+ result.test_eq("swap correct", b, c);
- return fails;
+ return result;
}
/**
* This test verifies that the side channel attack resistant multiplication function
* yields the same result as the normal (insecure) multiplication via operator*=
*/
-size_t test_mult_sec_mass()
+Test::Result test_mult_sec_mass()
{
- size_t fails = 0;
-
- auto& rng = test_rng();
+ Test::Result result("ECC Unit");
- EC_Group dom_pars(OID("1.3.132.0.8"));
+ Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8"));
for(int i = 0; i<50; i++)
{
try
{
- PointGFp a(create_random_point(rng, dom_pars.get_curve()));
- BigInt scal(BigInt(rng, 40));
- PointGFp b = a * scal;
- PointGFp c(a);
+ Botan::PointGFp a(create_random_point(Test::rng(), dom_pars.get_curve()));
+ Botan::BigInt scal(Botan::BigInt(Test::rng(), 40));
+ Botan::PointGFp b = a * scal;
+ Botan::PointGFp c(a);
c *= scal;
- CHECK(b == c);
+ result.test_eq("same result", b, c);
}
catch(std::exception& e)
{
- std::cout << "test_mult_sec_mass failed: " << e.what() << std::endl;
- ++fails;
+ result.test_failure("mult_sec_mass", e.what());
}
}
- return fails;
+ return result;
}
-size_t test_curve_cp_ctor()
+Test::Result test_curve_cp_ctor()
{
+ Test::Result result("ECC Unit");
+
try
{
- EC_Group dom_pars(OID("1.3.132.0.8"));
- CurveGFp curve(dom_pars.get_curve());
+ Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8"));
+ Botan::CurveGFp curve(dom_pars.get_curve());
}
- catch(...)
+ catch(std::exception& e)
{
- return 1;
-
+ result.test_failure("curve_cp_ctor", e.what());
}
- return 0;
+ return result;
}
-namespace {
-
-const std::vector<std::string> ec_groups = {
- "brainpool160r1",
- "brainpool192r1",
- "brainpool224r1",
- "brainpool256r1",
- "brainpool320r1",
- "brainpool384r1",
- "brainpool512r1",
- "gost_256A",
- "secp112r1",
- "secp112r2",
- "secp128r1",
- "secp128r2",
- "secp160k1",
- "secp160r1",
- "secp160r2",
- "secp192k1",
- "secp192r1",
- "secp224k1",
- "secp224r1",
- "secp256k1",
- "secp256r1",
- "secp384r1",
- "secp521r1",
- "x962_p192v2",
- "x962_p192v3",
- "x962_p239v1",
- "x962_p239v2",
- "x962_p239v3"
- };
-
-}
-
-}
-
-BOTAN_TEST_CASE(ecc_randomized, "ECC Randomized", {
- auto& rng = test_rng();
- size_t fails = 0;
- size_t tests = 0;
-
- for(auto&& group_name : ec_groups)
- {
- EC_Group group(group_name);
-
- const PointGFp& base_point = group.get_base_point();
- const BigInt& group_order = group.get_order();
-
- const PointGFp inf = base_point * group_order;
- BOTAN_CONFIRM(inf.is_zero(), "Group math ok");
- BOTAN_CONFIRM(inf.on_the_curve(), "Infinity still on the curve");
-
- try
- {
- for(size_t i = 0; i != 10; ++i)
- {
- ++tests;
-
- const size_t h = 1 + (rng.next_byte() % 8);
- Blinded_Point_Multiply blind(base_point, group_order, h);
-
- const BigInt a = BigInt::random_integer(rng, 2, group_order);
- const BigInt b = BigInt::random_integer(rng, 2, group_order);
- const BigInt c = a + b;
-
- const PointGFp P = base_point * a;
- const PointGFp Q = base_point * b;
- const PointGFp R = base_point * c;
-
- const PointGFp P1 = blind.blinded_multiply(a, rng);
- const PointGFp Q1 = blind.blinded_multiply(b, rng);
- const PointGFp R1 = blind.blinded_multiply(c, rng);
-
- const PointGFp A1 = P + Q;
- const PointGFp A2 = Q + P;
-
- BOTAN_TEST(A1, R, "Addition");
- BOTAN_TEST(A2, R, "Addition");
- BOTAN_CONFIRM(P.on_the_curve(), "On the curve");
- BOTAN_CONFIRM(Q.on_the_curve(), "On the curve");
- BOTAN_CONFIRM(R.on_the_curve(), "On the curve");
- BOTAN_CONFIRM(A1.on_the_curve(), "On the curve");
- BOTAN_CONFIRM(A2.on_the_curve(), "On the curve");
-
- BOTAN_TEST(P, P1, "P1");
- BOTAN_TEST(Q, Q1, "Q1");
- BOTAN_TEST(R, R1, "R1");
- }
- }
- catch(std::exception& e)
+class ECC_Unit_Tests : public Test
+ {
+ public:
+ std::vector<Test::Result> run() override
{
- std::cout << "Testing " << group_name << " failed: " << e.what() << std::endl;
- ++fails;
+ std::vector<Test::Result> results;
+
+ results.push_back(test_coordinates());
+ results.push_back(test_point_transformation ());
+ results.push_back(test_point_mult ());
+ results.push_back(test_point_negative());
+ results.push_back(test_zeropoint());
+ results.push_back(test_zeropoint_enc_dec());
+ results.push_back(test_calc_with_zeropoint());
+ results.push_back(test_add_point());
+ results.push_back(test_sub_point());
+ results.push_back(test_mult_point());
+ results.push_back(test_basic_operations());
+ results.push_back(test_enc_dec_compressed_160());
+ results.push_back(test_enc_dec_compressed_256());
+ results.push_back(test_enc_dec_uncompressed_112());
+ results.push_back(test_enc_dec_uncompressed_521());
+ results.push_back(test_enc_dec_uncompressed_521_prime_too_large());
+ results.push_back(test_gfp_store_restore());
+ results.push_back(test_cdc_curve_33());
+ results.push_back(test_more_zeropoint());
+ results.push_back(test_mult_by_order());
+ results.push_back(test_point_swap());
+ results.push_back(test_mult_sec_mass());
+ results.push_back(test_curve_cp_ctor());
+
+ return results;
}
- }
- });
-
+ };
-size_t test_ecc_unit()
- {
- size_t fails = 0;
-
- fails += test_point_turn_on_sp_red_mul();
- fails += test_coordinates();
- fails += test_point_transformation ();
- fails += test_point_mult ();
- fails += test_point_negative();
- fails += test_zeropoint();
- fails += test_zeropoint_enc_dec();
- fails += test_calc_with_zeropoint();
- fails += test_add_point();
- fails += test_sub_point();
- fails += test_mult_point();
- fails += test_basic_operations();
- fails += test_enc_dec_compressed_160();
- fails += test_enc_dec_compressed_256();
- fails += test_enc_dec_uncompressed_112();
- fails += test_enc_dec_uncompressed_521();
- fails += test_enc_dec_uncompressed_521_prime_too_large();
- fails += test_gfp_store_restore();
- fails += test_cdc_curve_33();
- fails += test_more_zeropoint();
- fails += test_mult_by_order();
- fails += test_point_swap();
- fails += test_mult_sec_mass();
- fails += test_curve_cp_ctor();
-
- test_report("ECC", 0, fails);
-
- return fails;
- }
+BOTAN_REGISTER_TEST("ecc_unit", ECC_Unit_Tests);
-#else
+#endif
-SKIP_TEST(ecc_unit);
-SKIP_TEST(ecc_randomized);
+}
-#endif // BOTAN_HAS_ECC_GROUP
+}
diff --git a/src/tests/unit_ecdh.cpp b/src/tests/unit_ecdh.cpp
index 8018bb8da..0368a53d1 100644
--- a/src/tests/unit_ecdh.cpp
+++ b/src/tests/unit_ecdh.cpp
@@ -10,132 +10,65 @@
#include "tests.h"
#if defined(BOTAN_HAS_ECDH)
-#include <iostream>
-#include <fstream>
-
-
-#include <botan/pubkey.h>
-#include <botan/ecdh.h>
-#if defined(BOTAN_HAS_X509_CERTIFICATES)
-#include <botan/x509self.h>
+ #include <botan/pubkey.h>
+ #include <botan/ecdh.h>
+ #include <botan/der_enc.h>
+ #include <botan/oids.h>
#endif
-#include <botan/der_enc.h>
-using namespace Botan;
-
-#define CHECK_MESSAGE(expr, print) try { if(!(expr)) { ++fails; std::cout << print << std::endl; } } catch(std::exception& e) { std::cout << __FUNCTION__ << ": " << e.what() << std::endl; }
-#define CHECK(expr) try { if(!(expr)) { ++fails; std::cout << #expr << std::endl; } } catch(std::exception& e) { std::cout << __FUNCTION__ << ": " << e.what() << std::endl; }
+namespace Botan_Tests {
namespace {
-size_t test_ecdh_normal_derivation(RandomNumberGenerator& rng)
- {
- size_t fails = 0;
-
- EC_Group dom_pars(OID("1.3.132.0.8"));
-
- ECDH_PrivateKey private_a(rng, dom_pars);
-
- ECDH_PrivateKey private_b(rng, dom_pars); //public_a.getCurve()
-
- PK_Key_Agreement ka(private_a, "KDF2(SHA-1)");
- PK_Key_Agreement kb(private_b, "KDF2(SHA-1)");
-
- SymmetricKey alice_key = ka.derive_key(32, private_b.public_value());
- SymmetricKey bob_key = kb.derive_key(32, private_a.public_value());
-
- if(alice_key != bob_key)
- {
- std::cout << "The two keys didn't match!" << std::endl;
- std::cout << "Alice's key was: " << alice_key.as_string() << std::endl;
- std::cout << "Bob's key was: " << bob_key.as_string() << std::endl;
- ++fails;
- }
-
- return fails;
- }
-
-size_t test_ecdh_some_dp(RandomNumberGenerator& rng)
+#if defined(BOTAN_HAS_ECDH)
+class ECDH_Unit_Tests : public Test
{
- size_t fails = 0;
-
- std::vector<std::string> oids;
- oids.push_back("1.2.840.10045.3.1.7");
- oids.push_back("1.3.132.0.8");
- oids.push_back("1.2.840.10045.3.1.1");
-
- for(u32bit i = 0; i< oids.size(); i++)
- {
- OID oid(oids[i]);
- EC_Group dom_pars(oid);
+ public:
+ std::vector<Test::Result> run() override
+ {
+ std::vector<Test::Result> results;
- ECDH_PrivateKey private_a(rng, dom_pars);
- ECDH_PrivateKey private_b(rng, dom_pars);
+ results.push_back(test_ecdh_normal_derivation());
- PK_Key_Agreement ka(private_a, "KDF2(SHA-1)");
- PK_Key_Agreement kb(private_b, "KDF2(SHA-1)");
+ return results;
+ }
+ private:
- SymmetricKey alice_key = ka.derive_key(32, private_b.public_value());
- SymmetricKey bob_key = kb.derive_key(32, private_a.public_value());
+ Test::Result test_ecdh_normal_derivation()
+ {
+ Test::Result result("ECDH kex");
- CHECK_MESSAGE(alice_key == bob_key, "different keys - " << "Alice's key was: " << alice_key.as_string() << ", Bob's key was: " << bob_key.as_string());
- }
+ std::vector<std::string> oids = { "1.2.840.10045.3.1.7",
+ "1.3.132.0.8",
+ "1.2.840.10045.3.1.1" };
- return fails;
- }
+ for(auto&& oid : oids)
+ {
+ Botan::EC_Group dom_pars(Botan::OIDS::lookup(oid));
+ Botan::ECDH_PrivateKey private_a(Test::rng(), dom_pars);
+ Botan::ECDH_PrivateKey private_b(Test::rng(), dom_pars);
-size_t test_ecdh_der_derivation(RandomNumberGenerator& rng)
- {
- size_t fails = 0;
-
- std::vector<std::string> oids;
- oids.push_back("1.2.840.10045.3.1.7");
- oids.push_back("1.3.132.0.8");
- oids.push_back("1.2.840.10045.3.1.1");
-
- for(u32bit i = 0; i< oids.size(); i++)
- {
- OID oid(oids[i]);
- EC_Group dom_pars(oid);
-
- ECDH_PrivateKey private_a(rng, dom_pars);
- ECDH_PrivateKey private_b(rng, dom_pars);
+ Botan::PK_Key_Agreement ka(private_a, "KDF2(SHA-1)");
+ Botan::PK_Key_Agreement kb(private_b, "KDF2(SHA-1)");
- std::vector<byte> key_a = private_a.public_value();
- std::vector<byte> key_b = private_b.public_value();
+ Botan::SymmetricKey alice_key = ka.derive_key(32, private_b.public_value());
+ Botan::SymmetricKey bob_key = kb.derive_key(32, private_a.public_value());
- PK_Key_Agreement ka(private_a, "KDF2(SHA-1)");
- PK_Key_Agreement kb(private_b, "KDF2(SHA-1)");
+ if(!result.test_eq("same derived key", alice_key.bits_of(), bob_key.bits_of()))
+ {
+ result.test_note("Keys where " + alice_key.as_string() + " and " + bob_key.as_string());
+ }
+ }
- SymmetricKey alice_key = ka.derive_key(32, key_b);
- SymmetricKey bob_key = kb.derive_key(32, key_a);
+ return result;
+ }
- CHECK_MESSAGE(alice_key == bob_key, "different keys - " << "Alice's key was: " << alice_key.as_string() << ", Bob's key was: " << bob_key.as_string());
+ };
- }
+BOTAN_REGISTER_TEST("ecdh_unit", ECDH_Unit_Tests);
- return fails;
- }
+#endif
}
-size_t test_ecdh_unit()
- {
- size_t fails = 0;
-
- auto& rng = test_rng();
-
- fails += test_ecdh_normal_derivation(rng);
- fails += test_ecdh_some_dp(rng);
- fails += test_ecdh_der_derivation(rng);
-
- test_report("ECDH", 3, fails);
-
- return fails;
- }
-
-#else
-
-size_t test_ecdh_unit() { return 0; }
-
-#endif
+}
diff --git a/src/tests/unit_ecdsa.cpp b/src/tests/unit_ecdsa.cpp
index 9983de7cc..ed9096083 100644
--- a/src/tests/unit_ecdsa.cpp
+++ b/src/tests/unit_ecdsa.cpp
@@ -9,499 +9,430 @@
*/
#include "tests.h"
+#include <botan/hex.h>
#if defined(BOTAN_HAS_ECDSA)
+ #include <botan/pubkey.h>
+ #include <botan/ecdsa.h>
+ #include <botan/ec_group.h>
+ #include <botan/oids.h>
+ #include <botan/pkcs8.h>
+#endif
#if defined(BOTAN_HAS_RSA)
-
-#include <botan/hex.h>
-#include <botan/pkcs8.h>
-#include <botan/pubkey.h>
-#include <botan/ecdsa.h>
-#include <botan/rsa.h>
-#include <botan/oids.h>
+ #include <botan/rsa.h>
+#endif
#if defined(BOTAN_HAS_X509_CERTIFICATES)
-#include <botan/x509cert.h>
+ #include <botan/x509cert.h>
#endif
-#include <iostream>
-#include <fstream>
-#include <memory>
-
-using namespace Botan;
-
-#define CHECK_MESSAGE(expr, print) try { if(!(expr)) { ++fails; std::cout << print << std::endl; } } catch(std::exception& e) { std::cout << __FUNCTION__ << ": " << e.what() << std::endl; }
-#define CHECK(expr) try { if(!(expr)) { ++fails; std::cout << #expr << std::endl; } } catch(std::exception& e) { std::cout << __FUNCTION__ << ": " << e.what() << std::endl; }
+namespace Botan_Tests {
namespace {
-/**
+#if defined(BOTAN_HAS_ECDSA)
+/**
* Tests whether the the signing routine will work correctly in case
* the integer e that is constructed from the message (thus the hash
* value) is larger than n, the order of the base point. Tests the
-* signing function of the pk signer object */
-
-size_t test_hash_larger_than_n(RandomNumberGenerator& rng)
+* signing function of the pk signer object
+*/
+Test::Result test_hash_larger_than_n()
{
- EC_Group dom_pars(OID("1.3.132.0.8")); // secp160r1
+ Test::Result result("ECDSA Unit");
+
+ Botan::EC_Group dom_pars(Botan::OIDS::lookup("1.3.132.0.8")); // secp160r1
// n = 0x0100000000000000000001f4c8f927aed3ca752257 (21 bytes)
// -> shouldn't work with SHA224 which outputs 28 bytes
- size_t fails = 0;
- ECDSA_PrivateKey priv_key(rng, dom_pars);
+ Botan::ECDSA_PrivateKey priv_key(Test::rng(), dom_pars);
std::vector<byte> message(20);
for(size_t i = 0; i != message.size(); ++i)
message[i] = i;
- PK_Signer pk_signer_160(priv_key, "EMSA1_BSI(SHA-1)");
- PK_Verifier pk_verifier_160(priv_key, "EMSA1_BSI(SHA-1)");
+ Botan::PK_Signer pk_signer_160(priv_key, "EMSA1_BSI(SHA-1)");
+ Botan::PK_Verifier pk_verifier_160(priv_key, "EMSA1_BSI(SHA-1)");
- PK_Signer pk_signer_224(priv_key, "EMSA1_BSI(SHA-224)");
+ Botan::PK_Signer pk_signer_224(priv_key, "EMSA1_BSI(SHA-224)");
// Verify we can sign and verify with SHA-160
- std::vector<byte> signature_160 = pk_signer_160.sign_message(message, rng);
+ std::vector<byte> signature_160 = pk_signer_160.sign_message(message, Test::rng());
- CHECK(pk_verifier_160.verify_message(message, signature_160));
+ result.test_eq("message verifies", pk_verifier_160.verify_message(message, signature_160), true);
- bool signature_failed = false;
try
{
- std::vector<byte> signature_224 = pk_signer_224.sign_message(message, rng);
+ std::vector<byte> signature_224 = pk_signer_224.sign_message(message, Test::rng());
+ result.test_failure("bad key/hash combination not rejected");
}
- catch(Encoding_Error)
+ catch(Botan::Encoding_Error)
{
- signature_failed = true;
+ result.test_note("bad key/hash combination rejected");
}
- CHECK(signature_failed);
-
// now check that verification alone fails
// sign it with the normal EMSA1
- PK_Signer pk_signer(priv_key, "EMSA1(SHA-224)");
- std::vector<byte> signature = pk_signer.sign_message(message, rng);
+ Botan::PK_Signer pk_signer(priv_key, "EMSA1(SHA-224)");
+ std::vector<byte> signature = pk_signer.sign_message(message, Test::rng());
- PK_Verifier pk_verifier(priv_key, "EMSA1_BSI(SHA-224)");
+ Botan::PK_Verifier pk_verifier(priv_key, "EMSA1_BSI(SHA-224)");
- // verify against EMSA1_BSI
- if(pk_verifier.verify_message(message, signature))
- {
- std::cout << "Corrupt ECDSA signature verified, should not have" << std::endl;
- ++fails;
- }
+ result.test_eq("corrupt message does not verify", pk_verifier.verify_message(message, signature), false);
- return fails;
+ return result;
}
#if defined(BOTAN_HAS_X509_CERTIFICATES)
-size_t test_decode_ecdsa_X509()
+Test::Result test_decode_ecdsa_X509()
{
- X509_Certificate cert(TEST_DATA_DIR_ECC "/CSCA.CSCA.csca-germany.1.crt");
- size_t fails = 0;
+ Test::Result result("ECDSA Unit");
+ Botan::X509_Certificate cert(Test::data_file("ecc/CSCA.CSCA.csca-germany.1.crt"));
- CHECK_MESSAGE(OIDS::lookup(cert.signature_algorithm().oid) == "ECDSA/EMSA1(SHA-224)", "error reading signature algorithm from x509 ecdsa certificate");
+ result.test_eq("correct signature oid", Botan::OIDS::lookup(cert.signature_algorithm().oid), "ECDSA/EMSA1(SHA-224)");
- CHECK_MESSAGE(hex_encode(cert.serial_number()) == "01", "error reading serial from x509 ecdsa certificate");
- CHECK_MESSAGE(hex_encode(cert.authority_key_id()) == "0096452DE588F966C4CCDF161DD1F3F5341B71E7", "error reading authority key id from x509 ecdsa certificate");
- CHECK_MESSAGE(hex_encode(cert.subject_key_id()) == "0096452DE588F966C4CCDF161DD1F3F5341B71E7", "error reading Subject key id from x509 ecdsa certificate");
- CHECK_MESSAGE(cert.fingerprint("SHA-1") == "32:42:1C:C3:EC:54:D7:E9:43:EC:51:F0:19:23:BD:85:1D:F2:1B:B9", "Incorrect fingerprint");
+ result.test_eq("serial number", cert.serial_number(), Botan::hex_decode("01"));
+ result.test_eq("authority key id", cert.authority_key_id(), cert.subject_key_id());
+ result.test_eq("key fingerprint", cert.fingerprint("SHA-1"), "32:42:1C:C3:EC:54:D7:E9:43:EC:51:F0:19:23:BD:85:1D:F2:1B:B9");
- std::unique_ptr<X509_PublicKey> pubkey(cert.subject_public_key());
- bool ver_ec = cert.check_signature(*pubkey);
- CHECK_MESSAGE(ver_ec, "could not positively verify correct selfsigned x509-ecdsa certificate");
+ std::unique_ptr<Botan::Public_Key> pubkey(cert.subject_public_key());
+ result.test_eq("verify self-signed signature", cert.check_signature(*pubkey), true);
- return fails;
+ return result;
}
-size_t test_decode_ver_link_SHA256()
+Test::Result test_decode_ver_link_SHA256()
{
- X509_Certificate root_cert(TEST_DATA_DIR_ECC "/root2_SHA256.cer");
- X509_Certificate link_cert(TEST_DATA_DIR_ECC "/link_SHA256.cer");
-
- size_t fails = 0;
- std::unique_ptr<X509_PublicKey> pubkey(root_cert.subject_public_key());
- bool ver_ec = link_cert.check_signature(*pubkey);
- CHECK_MESSAGE(ver_ec, "could not positively verify correct SHA256 link x509-ecdsa certificate");
- return fails;
+ Test::Result result("ECDSA Unit");
+ Botan::X509_Certificate root_cert(Test::data_file("ecc/root2_SHA256.cer"));
+ Botan::X509_Certificate link_cert(Test::data_file("ecc/link_SHA256.cer"));
+
+ std::unique_ptr<Botan::Public_Key> pubkey(root_cert.subject_public_key());
+ result.confirm("verified self-signed signature", link_cert.check_signature(*pubkey));
+ return result;
}
-size_t test_decode_ver_link_SHA1()
+Test::Result test_decode_ver_link_SHA1()
{
- X509_Certificate root_cert(TEST_DATA_DIR_ECC "/root_SHA1.163.crt");
- X509_Certificate link_cert(TEST_DATA_DIR_ECC "/link_SHA1.166.crt");
-
- size_t fails = 0;
- std::unique_ptr<X509_PublicKey> pubkey(root_cert.subject_public_key());
- bool ver_ec = link_cert.check_signature(*pubkey);
- CHECK_MESSAGE(ver_ec, "could not positively verify correct SHA1 link x509-ecdsa certificate");
- return fails;
+ Botan::X509_Certificate root_cert(Test::data_file("ecc/root_SHA1.163.crt"));
+ Botan::X509_Certificate link_cert(Test::data_file("ecc/link_SHA1.166.crt"));
+
+ Test::Result result("ECDSA Unit");
+ std::unique_ptr<Botan::Public_Key> pubkey(root_cert.subject_public_key());
+ result.confirm("verified self-signed signature", link_cert.check_signature(*pubkey));
+ return result;
}
#endif
-size_t test_sign_then_ver(RandomNumberGenerator& rng)
+Test::Result test_sign_then_ver()
{
- EC_Group dom_pars(OID("1.3.132.0.8"));
- ECDSA_PrivateKey ecdsa(rng, dom_pars);
+ Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8"));
+ Botan::ECDSA_PrivateKey ecdsa(Test::rng(), dom_pars);
- size_t fails = 0;
- PK_Signer signer(ecdsa, "EMSA1(SHA-1)");
+ Test::Result result("ECDSA Unit");
+ Botan::PK_Signer signer(ecdsa, "EMSA1(SHA-1)");
- auto msg = hex_decode("12345678901234567890abcdef12");
- std::vector<byte> sig = signer.sign_message(msg, rng);
+ auto msg = Botan::hex_decode("12345678901234567890abcdef12");
+ std::vector<byte> sig = signer.sign_message(msg, Test::rng());
- PK_Verifier verifier(ecdsa, "EMSA1(SHA-1)");
+ Botan::PK_Verifier verifier(ecdsa, "EMSA1(SHA-1)");
- bool ok = verifier.verify_message(msg, sig);
+ result.confirm("signature verifies", verifier.verify_message(msg, sig));
- if(!ok)
- {
- std::cout << "ERROR: Could not verify ECDSA signature" << std::endl;
- fails++;
- }
+ result.confirm("invalid signature rejected", !verifier.verify_message(msg, Test::mutate_vec(sig)));
- sig[0]++;
- ok = verifier.verify_message(msg, sig);
-
- if(ok)
- {
- std::cout << "ERROR: Bogus ECDSA signature verified anyway" << std::endl;
- fails++;
- }
-
- return fails;
+ return result;
}
-size_t test_ec_sign(RandomNumberGenerator& rng)
+Test::Result test_ec_sign()
{
- size_t fails = 0;
+ Test::Result result("ECDSA Unit");
try
{
- EC_Group dom_pars(OID("1.3.132.0.8"));
- ECDSA_PrivateKey priv_key(rng, dom_pars);
- std::string pem_encoded_key = PKCS8::PEM_encode(priv_key);
+ Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8"));
+ Botan::ECDSA_PrivateKey priv_key(Test::rng(), dom_pars);
+ std::string pem_encoded_key = Botan::PKCS8::PEM_encode(priv_key);
- PK_Signer signer(priv_key, "EMSA1(SHA-224)");
- PK_Verifier verifier(priv_key, "EMSA1(SHA-224)");
+ Botan::PK_Signer signer(priv_key, "EMSA1(SHA-224)");
+ Botan::PK_Verifier verifier(priv_key, "EMSA1(SHA-224)");
for(size_t i = 0; i != 256; ++i)
+ {
signer.update(static_cast<byte>(i));
- std::vector<byte> sig = signer.signature(rng);
+ }
+ std::vector<byte> sig = signer.signature(Test::rng());
- for(u32bit i = 0; i != 256; ++i)
- verifier.update(static_cast<byte>(i));
- if(!verifier.check_signature(sig))
+ for(size_t i = 0; i != 256; ++i)
{
- std::cout << "ECDSA self-test failed!";
- ++fails;
+ verifier.update(static_cast<byte>(i));
}
- // now check valid signature, different input
- for(u32bit i = 1; i != 256; ++i) //starting from 1
- verifier.update(static_cast<byte>(i));
+ result.test_eq("ECDSA signature valid", verifier.check_signature(sig), true);
- if(verifier.check_signature(sig))
+ // now check valid signature, different input
+ for(size_t i = 1; i != 256; ++i) //starting from 1
{
- std::cout << "ECDSA with bad input passed validation";
- ++fails;
+ verifier.update(static_cast<byte>(i));
}
+ result.test_eq("invalid ECDSA signature invalid", verifier.check_signature(sig), false);
+
// now check with original input, modified signature
sig[sig.size()/2]++;
- for(u32bit i = 0; i != 256; ++i)
+ for(size_t i = 0; i != 256; ++i)
verifier.update(static_cast<byte>(i));
- if(verifier.check_signature(sig))
- {
- std::cout << "ECDSA with bad signature passed validation";
- ++fails;
- }
+ result.test_eq("invalid ECDSA signature invalid", verifier.check_signature(sig), false);
}
catch (std::exception& e)
{
- std::cout << "Exception in test_ec_sign - " << e.what() << std::endl;
- ++fails;
+ result.test_failure("test_ec_sign", e.what());
}
- return fails;
+ return result;
}
-
-size_t test_create_pkcs8(RandomNumberGenerator& rng)
+Test::Result test_create_pkcs8()
{
- size_t fails = 0;
+ Test::Result result("ECDSA Unit");
try
{
- RSA_PrivateKey rsa_key(rng, 1024);
- //RSA_PrivateKey rsa_key2(1024);
- //cout << "\nequal: " << (rsa_key == rsa_key2) << std::endl;
- //DSA_PrivateKey key(DL_Group("dsa/jce/1024"));
+#if defined(BOTAN_HAS_RSA)
+ Botan::RSA_PrivateKey rsa_key(Test::rng(), 1024);
- std::ofstream rsa_priv_key(TEST_OUTDATA_DIR "/rsa_private.pkcs8.pem");
- rsa_priv_key << PKCS8::PEM_encode(rsa_key);
+ std::ofstream rsa_priv_key(Test::full_path_for_output_file("rsa_private.pkcs8.pem"));
+ rsa_priv_key << Botan::PKCS8::PEM_encode(rsa_key);
+#endif
- EC_Group dom_pars(OID("1.3.132.0.8"));
- ECDSA_PrivateKey key(rng, dom_pars);
+ Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8"));
+ Botan::ECDSA_PrivateKey key(Test::rng(), dom_pars);
// later used by other tests :(
- std::ofstream priv_key(TEST_OUTDATA_DIR "/wo_dompar_private.pkcs8.pem");
- priv_key << PKCS8::PEM_encode(key);
+ std::ofstream priv_key(Test::full_path_for_output_file("wo_dompar_private.pkcs8.pem"));
+ priv_key << Botan::PKCS8::PEM_encode(key);
}
catch (std::exception& e)
{
- std::cout << "Exception: " << e.what() << std::endl;
- ++fails;
+ result.test_failure("create_pkcs8", e.what());
}
- return fails;
+ return result;
}
-size_t test_create_and_verify(RandomNumberGenerator& rng)
+Test::Result test_create_and_verify()
{
- size_t fails = 0;
+ Test::Result result("ECDSA Unit");
- EC_Group dom_pars(OID("1.3.132.0.8"));
- ECDSA_PrivateKey key(rng, dom_pars);
- std::ofstream priv_key(TEST_OUTDATA_DIR "/dompar_private.pkcs8.pem");
- priv_key << PKCS8::PEM_encode(key);
+ Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8"));
+ Botan::ECDSA_PrivateKey key(Test::rng(), dom_pars);
+ std::ofstream priv_key(Test::full_path_for_output_file("dompar_private.pkcs8.pem"));
+ priv_key << Botan::PKCS8::PEM_encode(key);
- std::unique_ptr<PKCS8_PrivateKey> loaded_key(PKCS8::load_key(TEST_OUTDATA_DIR "/wo_dompar_private.pkcs8.pem", rng));
- ECDSA_PrivateKey* loaded_ec_key = dynamic_cast<ECDSA_PrivateKey*>(loaded_key.get());
- CHECK_MESSAGE(loaded_ec_key, "the loaded key could not be converted into an ECDSA_PrivateKey");
+ std::unique_ptr<Botan::Private_Key> loaded_key(Botan::PKCS8::load_key(Test::full_path_for_output_file("wo_dompar_private.pkcs8.pem"), Test::rng()));
+ Botan::ECDSA_PrivateKey* loaded_ec_key = dynamic_cast<Botan::ECDSA_PrivateKey*>(loaded_key.get());
+ result.confirm("the loaded key could not be converted into an ECDSA_PrivateKey", loaded_ec_key);
- std::unique_ptr<PKCS8_PrivateKey> loaded_key_1(PKCS8::load_key(TEST_OUTDATA_DIR "/rsa_private.pkcs8.pem", rng));
- ECDSA_PrivateKey* loaded_rsa_key = dynamic_cast<ECDSA_PrivateKey*>(loaded_key_1.get());
- CHECK_MESSAGE(!loaded_rsa_key, "the loaded key is ECDSA_PrivateKey -> shouldn't be, is a RSA-Key");
+#if defined(BOTAN_HAS_RSA)
+ std::unique_ptr<Botan::Private_Key> loaded_key_1(Botan::PKCS8::load_key(Test::full_path_for_output_file("rsa_private.pkcs8.pem"), Test::rng()));
+ Botan::ECDSA_PrivateKey* loaded_rsa_key = dynamic_cast<Botan::ECDSA_PrivateKey*>(loaded_key_1.get());
+ result.test_eq("loaded key type corrected", loaded_key_1->algo_name(), "RSA");
+ result.confirm("RSA key cannot be casted to ECDSA", !loaded_rsa_key);
+#endif
//calc a curve which is not in the registry
+ const std::string G_secp_comp = "04081523d03d4f12cd02879dea4bf6a4f3a7df26ed888f10c5b2235a1274c386a2f218300dee6ed217841164533bcdc903f07a096f9fbf4ee95bac098a111f296f5830fe5c35b3e344d5df3a2256985f64fbe6d0edcc4c61d18bef681dd399df3d0194c5a4315e012e0245ecea56365baa9e8be1f7";
+ const Botan::BigInt bi_p_secp("2117607112719756483104013348936480976596328609518055062007450442679169492999007105354629105748524349829824407773719892437896937279095106809");
+ const Botan::BigInt bi_a_secp("0x0a377dede6b523333d36c78e9b0eaa3bf48ce93041f6d4fc34014d08f6833807498deedd4290101c5866e8dfb589485d13357b9e78c2d7fbe9fe");
+ const Botan::BigInt bi_b_secp("0x0a9acf8c8ba617777e248509bcb4717d4db346202bf9e352cd5633731dd92a51b72a4dc3b3d17c823fcc8fbda4da08f25dea89046087342595a7");
+ Botan::BigInt bi_order_g("0x0e1a16196e6000000000bc7f1618d867b15bb86474418f");
+ Botan::CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
+ Botan::PointGFp p_G = Botan::OS2ECP(Botan::hex_decode(G_secp_comp), curve);
- // string p_secp = "2117607112719756483104013348936480976596328609518055062007450442679169492999007105354629105748524349829824407773719892437896937279095106809";
- std::string a_secp = "0a377dede6b523333d36c78e9b0eaa3bf48ce93041f6d4fc34014d08f6833807498deedd4290101c5866e8dfb589485d13357b9e78c2d7fbe9fe";
- std::string b_secp = "0a9acf8c8ba617777e248509bcb4717d4db346202bf9e352cd5633731dd92a51b72a4dc3b3d17c823fcc8fbda4da08f25dea89046087342595a7";
- std::string G_secp_comp = "04081523d03d4f12cd02879dea4bf6a4f3a7df26ed888f10c5b2235a1274c386a2f218300dee6ed217841164533bcdc903f07a096f9fbf4ee95bac098a111f296f5830fe5c35b3e344d5df3a2256985f64fbe6d0edcc4c61d18bef681dd399df3d0194c5a4315e012e0245ecea56365baa9e8be1f7";
- std::string order_g = "0e1a16196e6000000000bc7f1618d867b15bb86474418f";
-
- // ::std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- auto sv_a_secp = hex_decode ( a_secp );
- auto sv_b_secp = hex_decode ( b_secp );
- auto sv_G_secp_comp = hex_decode ( G_secp_comp );
- auto sv_order_g = hex_decode ( order_g );
-
- // BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_p_secp("2117607112719756483104013348936480976596328609518055062007450442679169492999007105354629105748524349829824407773719892437896937279095106809");
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- BigInt bi_order_g = BigInt::decode ( sv_order_g.data(), sv_order_g.size() );
- CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_secp_comp, curve );
-
- EC_Group dom_params(curve, p_G, bi_order_g, BigInt(1));
- if(!p_G.on_the_curve())
- throw Internal_Error("Point not on the curve");
-
- ECDSA_PrivateKey key_odd_oid(rng, dom_params);
- std::string key_odd_oid_str = PKCS8::PEM_encode(key_odd_oid);
-
- DataSource_Memory key_data_src(key_odd_oid_str);
- std::unique_ptr<PKCS8_PrivateKey> loaded_key2(PKCS8::load_key(key_data_src, rng));
-
- if(!dynamic_cast<ECDSA_PrivateKey*>(loaded_key.get()))
- {
- std::cout << "Failed to reload an ECDSA key with unusual parameter set" << std::endl;
- ++fails;
- }
+ Botan::EC_Group dom_params(curve, p_G, bi_order_g, Botan::BigInt(1));
+ if(!result.confirm("point is on curve", p_G.on_the_curve()))
+ return result;
+
+ Botan::ECDSA_PrivateKey key_odd_oid(Test::rng(), dom_params);
+ std::string key_odd_oid_str = Botan::PKCS8::PEM_encode(key_odd_oid);
+
+ Botan::DataSource_Memory key_data_src(key_odd_oid_str);
+ std::unique_ptr<Botan::Private_Key> loaded_key2(Botan::PKCS8::load_key(key_data_src, Test::rng()));
+
+ result.confirm("reloaded key", loaded_key.get());
- return fails;
+ return result;
}
-size_t test_curve_registry(RandomNumberGenerator& rng)
+Test::Result test_curve_registry()
{
- std::vector<std::string> oids;
- oids.push_back("1.3.132.0.8");
- oids.push_back("1.2.840.10045.3.1.1");
- oids.push_back("1.2.840.10045.3.1.2");
- oids.push_back("1.2.840.10045.3.1.3");
- oids.push_back("1.2.840.10045.3.1.4");
- oids.push_back("1.2.840.10045.3.1.5");
- oids.push_back("1.2.840.10045.3.1.6");
- oids.push_back("1.2.840.10045.3.1.7");
- oids.push_back("1.3.132.0.6");
- oids.push_back("1.3.132.0.7");
- oids.push_back("1.3.132.0.28");
- oids.push_back("1.3.132.0.29");
- oids.push_back("1.3.132.0.9");
- oids.push_back("1.3.132.0.30");
- oids.push_back("1.3.132.0.31");
- oids.push_back("1.3.132.0.32");
- oids.push_back("1.3.132.0.33");
- oids.push_back("1.3.132.0.10");
- oids.push_back("1.3.132.0.34");
- oids.push_back("1.3.132.0.35");
- //oids.push_back("1.3.6.1.4.1.8301.3.1.2.9.0.38");
- oids.push_back("1.3.36.3.3.2.8.1.1.1");
- oids.push_back("1.3.36.3.3.2.8.1.1.3");
- oids.push_back("1.3.36.3.3.2.8.1.1.5");
- oids.push_back("1.3.36.3.3.2.8.1.1.7");
- oids.push_back("1.3.36.3.3.2.8.1.1.9");
- oids.push_back("1.3.36.3.3.2.8.1.1.11");
- oids.push_back("1.3.36.3.3.2.8.1.1.13");
-
- size_t fails = 0;
-
- unsigned int i;
- for (i = 0; i < oids.size(); i++)
+ const std::vector<std::string> oids = {
+ "1.3.132.0.8",
+ "1.2.840.10045.3.1.1",
+ "1.2.840.10045.3.1.2",
+ "1.2.840.10045.3.1.3",
+ "1.2.840.10045.3.1.4",
+ "1.2.840.10045.3.1.5",
+ "1.2.840.10045.3.1.6",
+ "1.2.840.10045.3.1.7",
+ "1.3.132.0.6",
+ "1.3.132.0.7",
+ "1.3.132.0.28",
+ "1.3.132.0.29",
+ "1.3.132.0.9",
+ "1.3.132.0.30",
+ "1.3.132.0.31",
+ "1.3.132.0.32",
+ "1.3.132.0.33",
+ "1.3.132.0.10",
+ "1.3.132.0.34",
+ "1.3.132.0.35",
+ "1.3.36.3.3.2.8.1.1.1",
+ "1.3.36.3.3.2.8.1.1.3",
+ "1.3.36.3.3.2.8.1.1.5",
+ "1.3.36.3.3.2.8.1.1.7",
+ "1.3.36.3.3.2.8.1.1.9",
+ "1.3.36.3.3.2.8.1.1.11",
+ "1.3.36.3.3.2.8.1.1.13",
+ };
+
+ Test::Result result("ECDSA Unit");
+
+ for(auto&& oid_str : oids)
{
try
{
- OID oid(oids[i]);
- EC_Group dom_pars(oid);
- ECDSA_PrivateKey ecdsa(rng, dom_pars);
+ Botan::OID oid(oid_str);
+ Botan::EC_Group dom_pars(oid);
+ Botan::ECDSA_PrivateKey ecdsa(Test::rng(), dom_pars);
- PK_Signer signer(ecdsa, "EMSA1(SHA-1)");
- PK_Verifier verifier(ecdsa, "EMSA1(SHA-1)");
+ Botan::PK_Signer signer(ecdsa, "EMSA1(SHA-1)");
+ Botan::PK_Verifier verifier(ecdsa, "EMSA1(SHA-1)");
- auto msg = hex_decode("12345678901234567890abcdef12");
- std::vector<byte> sig = signer.sign_message(msg, rng);
+ auto msg = Botan::hex_decode("12345678901234567890abcdef12");
+ std::vector<byte> sig = signer.sign_message(msg, Test::rng());
- if(!verifier.verify_message(msg, sig))
- {
- std::cout << "Failed testing ECDSA sig for curve " << oids[i] << std::endl;
- ++fails;
- }
+ result.confirm("verified signature", verifier.verify_message(msg, sig));
}
- catch(Invalid_Argument& e)
+ catch(Botan::Invalid_Argument& e)
{
- std::cout << "Error testing curve " << oids[i] << " - " << e.what() << std::endl;
- ++fails;
+ result.test_failure("testing " + oid_str + ": " + e.what());
}
}
- return fails;
+
+ return result;
}
-size_t test_read_pkcs8(RandomNumberGenerator& rng)
+Test::Result test_read_pkcs8()
{
- auto msg = hex_decode("12345678901234567890abcdef12");
- size_t fails = 0;
+ Test::Result result("ECDSA Unit");
+
+ const std::vector<byte> msg = Botan::hex_decode("12345678901234567890abcdef12");
try
{
- std::unique_ptr<PKCS8_PrivateKey> loaded_key(PKCS8::load_key(TEST_OUTDATA_DIR "/wo_dompar_private.pkcs8.pem", rng));
- ECDSA_PrivateKey* ecdsa = dynamic_cast<ECDSA_PrivateKey*>(loaded_key.get());
- CHECK_MESSAGE(ecdsa, "the loaded key could not be converted into an ECDSA_PrivateKey");
+ std::unique_ptr<Botan::Private_Key> loaded_key(Botan::PKCS8::load_key(Test::full_path_for_output_file("wo_dompar_private.pkcs8.pem"), Test::rng()));
+ Botan::ECDSA_PrivateKey* ecdsa = dynamic_cast<Botan::ECDSA_PrivateKey*>(loaded_key.get());
+ result.confirm("key loaded", ecdsa);
- PK_Signer signer(*ecdsa, "EMSA1(SHA-1)");
+ Botan::PK_Signer signer(*ecdsa, "EMSA1(SHA-1)");
- std::vector<byte> sig = signer.sign_message(msg, rng);
+ std::vector<byte> sig = signer.sign_message(msg, Test::rng());
- PK_Verifier verifier(*ecdsa, "EMSA1(SHA-1)");
+ Botan::PK_Verifier verifier(*ecdsa, "EMSA1(SHA-1)");
- CHECK_MESSAGE(verifier.verify_message(msg, sig),
- "generated sig could not be verified positively");
+ result.confirm("generated signature valid", verifier.verify_message(msg, sig));
}
catch (std::exception& e)
{
- ++fails;
- std::cout << "Exception in test_read_pkcs8 - " << e.what() << std::endl;
+ result.test_failure("read_pkcs8", e.what());
}
try
{
- std::unique_ptr<PKCS8_PrivateKey> loaded_key_nodp(PKCS8::load_key(TEST_DATA_DIR_ECC "/nodompar_private.pkcs8.pem", rng));
+ std::unique_ptr<Botan::Private_Key> loaded_key_nodp(Botan::PKCS8::load_key(Test::data_file("ecc/nodompar_private.pkcs8.pem"), Test::rng()));
// anew in each test with unregistered domain-parameters
- ECDSA_PrivateKey* ecdsa_nodp = dynamic_cast<ECDSA_PrivateKey*>(loaded_key_nodp.get());
- CHECK_MESSAGE(ecdsa_nodp, "the loaded key could not be converted into an ECDSA_PrivateKey");
+ Botan::ECDSA_PrivateKey* ecdsa_nodp = dynamic_cast<Botan::ECDSA_PrivateKey*>(loaded_key_nodp.get());
+ result.confirm("key loaded", ecdsa_nodp);
- PK_Signer signer(*ecdsa_nodp, "EMSA1(SHA-1)");
- PK_Verifier verifier(*ecdsa_nodp, "EMSA1(SHA-1)");
+ Botan::PK_Signer signer(*ecdsa_nodp, "EMSA1(SHA-1)");
+ Botan::PK_Verifier verifier(*ecdsa_nodp, "EMSA1(SHA-1)");
- std::vector<byte> signature_nodp = signer.sign_message(msg, rng);
+ std::vector<byte> signature_nodp = signer.sign_message(msg, Test::rng());
- CHECK_MESSAGE(verifier.verify_message(msg, signature_nodp),
- "generated signature could not be verified positively (no_dom)");
+ result.confirm("signature valid", verifier.verify_message(msg, signature_nodp));
try
{
- std::unique_ptr<PKCS8_PrivateKey> loaded_key_withdp(
- PKCS8::load_key(TEST_DATA_DIR_ECC "/withdompar_private.pkcs8.pem", rng));
+ std::unique_ptr<Botan::Private_Key> loaded_key_withdp(
+ Botan::PKCS8::load_key(Test::data_file("ecc/withdompar_private.pkcs8.pem"), Test::rng()));
- std::cout << "Unexpected success: loaded key with unknown OID" << std::endl;
- ++fails;
+ result.test_failure("loaded key with unknown OID");
+ }
+ catch (std::exception& e)
+ {
+ result.test_note("rejected key with unknown OID");
}
- catch (std::exception) { /* OK */ }
}
catch (std::exception& e)
{
- std::cout << "Exception in test_read_pkcs8 - " << e.what() << std::endl;
- ++fails;
+ result.test_failure("read_pkcs8", e.what());
}
- return fails;
+ return result;
}
-size_t test_ecc_key_with_rfc5915_extensions(RandomNumberGenerator& rng)
+Test::Result test_ecc_key_with_rfc5915_extensions()
{
- size_t fails = 0;
+ Test::Result result("ECDSA Unit");
try
{
- std::unique_ptr<PKCS8_PrivateKey> pkcs8(
- PKCS8::load_key(TEST_DATA_DIR_ECC "/ecc_private_with_rfc5915_ext.pem", rng));
+ std::unique_ptr<Botan::Private_Key> pkcs8(
+ Botan::PKCS8::load_key(Test::data_file("ecc/ecc_private_with_rfc5915_ext.pem"), Test::rng()));
- if(!dynamic_cast<ECDSA_PrivateKey*>(pkcs8.get()))
- {
- std::cout << "Loaded RFC 5915 key, but got something other than an ECDSA key" << std::endl;
- ++fails;
- }
+ result.confirm("loaded RFC 5914 key", pkcs8.get());
+ result.test_eq("key is ECDSA", pkcs8->algo_name(), "ECDSA");
+ result.confirm("key type is ECDSA", dynamic_cast<Botan::ECDSA_PrivateKey*>(pkcs8.get()));
}
catch(std::exception& e)
{
- std::cout << "Exception in " << BOTAN_CURRENT_FUNCTION << " - " << e.what() << std::endl;
- ++fails;
+ result.test_failure("load_rfc5915", e.what());
}
- return fails;
+ return result;
}
-}
-size_t test_ecdsa_unit()
+class ECDSA_Unit_Tests : public Test
{
- size_t fails = 0;
-
- auto& rng = test_rng();
+ public:
+ std::vector<Test::Result> run() override
+ {
+ std::vector<Test::Result> results;
+ results.push_back(test_hash_larger_than_n());
+ results.push_back(test_decode_ecdsa_X509());
+ results.push_back(test_decode_ver_link_SHA256());
+ results.push_back(test_decode_ver_link_SHA1());
+ results.push_back(test_sign_then_ver());
+ results.push_back(test_ec_sign());
+ results.push_back(test_create_pkcs8());
+ results.push_back(test_create_and_verify());
+ results.push_back(test_curve_registry());
+ results.push_back(test_read_pkcs8());
+ results.push_back(test_ecc_key_with_rfc5915_extensions());
+ return results;
+ }
+ };
- fails += test_hash_larger_than_n(rng);
-#if defined(BOTAN_HAS_X509_CERTIFICATES)
- fails += test_decode_ecdsa_X509();
- fails += test_decode_ver_link_SHA256();
- fails += test_decode_ver_link_SHA1();
+BOTAN_REGISTER_TEST("ecdsa_unit", ECDSA_Unit_Tests);
#endif
- fails += test_sign_then_ver(rng);
- fails += test_ec_sign(rng);
- fails += test_create_pkcs8(rng);
- fails += test_create_and_verify(rng);
- fails += test_curve_registry(rng);
- fails += test_read_pkcs8(rng);
- fails += test_ecc_key_with_rfc5915_extensions(rng);
-
- test_report("ECDSA", 11, fails);
- return fails;
- }
-
-#else
-
-UNTESTED_WARNING(ecdsa_unit);
-
-#endif // BOTAN_HAS_RSA
-
-#else
-
-SKIP_TEST(ecdsa_unit);
+}
-#endif // BOTAN_HAS_ECDSA
+}
diff --git a/src/tests/unit_tls.cpp b/src/tests/unit_tls.cpp
index d4abef119..8e53fc3db 100644
--- a/src/tests/unit_tls.cpp
+++ b/src/tests/unit_tls.cpp
@@ -5,10 +5,12 @@
*/
#include "tests.h"
+#include <vector>
+#include <memory>
+#include <thread>
#if defined(BOTAN_HAS_TLS)
-
#include <botan/tls_server.h>
#include <botan/tls_client.h>
#include <botan/tls_handshake_msg.h>
@@ -18,46 +20,44 @@
#include <botan/x509_ca.h>
#include <botan/auto_rng.h>
#include <botan/hex.h>
+#endif
-#include <iostream>
-#include <vector>
-#include <memory>
-#include <thread>
-using namespace Botan;
+namespace Botan_Tests {
namespace {
+#if defined(BOTAN_HAS_TLS)
class Credentials_Manager_Test : public Botan::Credentials_Manager
{
public:
- Credentials_Manager_Test(const X509_Certificate& server_cert,
- const X509_Certificate& ca_cert,
- Private_Key* server_key) :
+ Credentials_Manager_Test(const Botan::X509_Certificate& server_cert,
+ const Botan::X509_Certificate& ca_cert,
+ Botan::Private_Key* server_key) :
m_server_cert(server_cert),
m_ca_cert(ca_cert),
m_key(server_key)
{
- std::unique_ptr<Certificate_Store> store(new Certificate_Store_In_Memory(m_ca_cert));
+ std::unique_ptr<Botan::Certificate_Store> store(new Botan::Certificate_Store_In_Memory(m_ca_cert));
m_stores.push_back(std::move(store));
}
- std::vector<Certificate_Store*>
+ std::vector<Botan::Certificate_Store*>
trusted_certificate_authorities(const std::string&,
const std::string&) override
{
- std::vector<Certificate_Store*> v;
+ std::vector<Botan::Certificate_Store*> v;
for(auto&& store : m_stores)
v.push_back(store.get());
return v;
}
- std::vector<X509_Certificate> cert_chain(
+ std::vector<Botan::X509_Certificate> cert_chain(
const std::vector<std::string>& cert_key_types,
const std::string& type,
const std::string&) override
{
- std::vector<X509_Certificate> chain;
+ std::vector<Botan::X509_Certificate> chain;
if(type == "tls-server")
{
@@ -81,78 +81,77 @@ class Credentials_Manager_Test : public Botan::Credentials_Manager
const std::string& purported_hostname,
const std::vector<Botan::X509_Certificate>& cert_chain) override
{
- try
- {
- Credentials_Manager::verify_certificate_chain(type,
- purported_hostname,
- cert_chain);
- }
- catch(std::exception& e)
- {
- std::cout << "Certificate verification failed - " << e.what() << " - but will ignore" << std::endl;
- }
+ Credentials_Manager::verify_certificate_chain(type,
+ purported_hostname,
+ cert_chain);
}
- Private_Key* private_key_for(const X509_Certificate&,
- const std::string&,
- const std::string&) override
+ Botan::Private_Key* private_key_for(const Botan::X509_Certificate&,
+ const std::string&,
+ const std::string&) override
{
return m_key.get();
}
- SymmetricKey psk(const std::string& type,
- const std::string& context,
- const std::string&) override
+ Botan::SymmetricKey psk(const std::string& type,
+ const std::string& context,
+ const std::string&) override
{
if(type == "tls-server" && context == "session-ticket")
- return SymmetricKey("AABBCCDDEEFF012345678012345678");
- throw Exception("No PSK set for " + context);
+ return Botan::SymmetricKey("AABBCCDDEEFF012345678012345678");
+
+ if(context == "server.example.com" && type == "tls-client")
+ return Botan::SymmetricKey("20B602D1475F2DF888FCB60D2AE03AFD");
+
+ if(context == "server.example.com" && type == "tls-server")
+ return Botan::SymmetricKey("20B602D1475F2DF888FCB60D2AE03AFD");
+
+ throw std::runtime_error("No PSK set for " + type + "/" + context);
}
public:
- X509_Certificate m_server_cert, m_ca_cert;
- std::unique_ptr<Private_Key> m_key;
- std::vector<std::unique_ptr<Certificate_Store>> m_stores;
+ Botan::X509_Certificate m_server_cert, m_ca_cert;
+ std::unique_ptr<Botan::Private_Key> m_key;
+ std::vector<std::unique_ptr<Botan::Certificate_Store>> m_stores;
};
-Credentials_Manager* create_creds()
+Botan::Credentials_Manager* create_creds()
{
- AutoSeeded_RNG rng;
- std::unique_ptr<Private_Key> ca_key(new RSA_PrivateKey(rng, 1024));
+ std::unique_ptr<Botan::Private_Key> ca_key(new Botan::RSA_PrivateKey(Test::rng(), 1024));
- X509_Cert_Options ca_opts;
+ Botan::X509_Cert_Options ca_opts;
ca_opts.common_name = "Test CA";
ca_opts.country = "US";
ca_opts.CA_key(1);
- X509_Certificate ca_cert =
- X509::create_self_signed_cert(ca_opts,
- *ca_key,
- "SHA-256",
- rng);
+ Botan::X509_Certificate ca_cert =
+ Botan::X509::create_self_signed_cert(ca_opts,
+ *ca_key,
+ "SHA-256",
+ Test::rng());
- Private_Key* server_key = new RSA_PrivateKey(rng, 1024);
+ Botan::Private_Key* server_key = new Botan::RSA_PrivateKey(Test::rng(), 1024);
- X509_Cert_Options server_opts;
+ Botan::X509_Cert_Options server_opts;
server_opts.common_name = "server.example.com";
server_opts.country = "US";
- PKCS10_Request req = X509::create_cert_req(server_opts,
- *server_key,
- "SHA-256",
- rng);
+ Botan::PKCS10_Request req = Botan::X509::create_cert_req(server_opts,
+ *server_key,
+ "SHA-256",
+ Test::rng());
- X509_CA ca(ca_cert, *ca_key, "SHA-256");
+ Botan::X509_CA ca(ca_cert, *ca_key, "SHA-256");
auto now = std::chrono::system_clock::now();
- X509_Time start_time(now);
+ Botan::X509_Time start_time(now);
typedef std::chrono::duration<int, std::ratio<31556926>> years;
- X509_Time end_time(now + years(1));
+ Botan::X509_Time end_time(now + years(1));
- X509_Certificate server_cert = ca.sign_request(req,
- rng,
- start_time,
- end_time);
+ Botan::X509_Certificate server_cert = ca.sign_request(req,
+ Test::rng(),
+ start_time,
+ end_time);
return new Credentials_Manager_Test(server_cert, ca_cert, server_key);
}
@@ -162,53 +161,54 @@ std::function<void (const byte[], size_t)> queue_inserter(std::vector<byte>& q)
return [&](const byte buf[], size_t sz) { q.insert(q.end(), buf, buf + sz); };
}
-void print_alert(TLS::Alert alert, const byte[], size_t)
+void print_alert(Botan::TLS::Alert, const byte[], size_t)
{
- //std::cout << "Alert " << alert.type_string() << std::endl;
};
-void mutate(std::vector<byte>& v, RandomNumberGenerator& rng)
+Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version,
+ Botan::Credentials_Manager& creds,
+ Botan::TLS::Policy& policy)
{
- if(v.empty())
- return;
+ Botan::RandomNumberGenerator& rng = Test::rng();
- size_t voff = rng.get_random<size_t>() % v.size();
- v[voff] ^= rng.next_nonzero_byte();
- }
+ Botan::TLS::Session_Manager_In_Memory server_sessions(rng);
+ Botan::TLS::Session_Manager_In_Memory client_sessions(rng);
-size_t test_tls_handshake(RandomNumberGenerator& rng,
- TLS::Protocol_Version offer_version,
- Credentials_Manager& creds,
- TLS::Policy& policy)
- {
- TLS::Session_Manager_In_Memory server_sessions(rng);
- TLS::Session_Manager_In_Memory client_sessions(rng);
+ Test::Result result(offer_version.to_string());
+
+ result.start_timer();
for(size_t r = 1; r <= 4; ++r)
{
- //std::cout << offer_version.to_string() << " r " << r << "\n";
-
bool handshake_done = false;
- auto handshake_complete = [&](const TLS::Session& session) -> bool {
+ result.test_note("Test round " + std::to_string(r));
+
+ auto handshake_complete = [&](const Botan::TLS::Session& session) -> bool {
handshake_done = true;
- /*
- std::cout << "Session established " << session.version().to_string() << " "
- << session.ciphersuite().to_string() << " " << hex_encode(session.session_id()) << "\n";
- */
+ result.test_note("Session established " + session.version().to_string() + " " +
+ session.ciphersuite().to_string() + " " +
+ Botan::hex_encode(session.session_id()));
if(session.version() != offer_version)
- std::cout << "Offered " << offer_version.to_string()
- << " got " << session.version().to_string() << std::endl;
- return true;
- };
+ {
+ result.test_failure("Offered " + offer_version.to_string() +
+ " got " + session.version().to_string());
+ }
+
+ if(r <= 2)
+ return true;
+ return false;
+ };
auto next_protocol_chooser = [&](std::vector<std::string> protos) {
- if(protos.size() != 2)
- std::cout << "Bad protocol size" << std::endl;
- if(protos[0] != "test/1" || protos[1] != "test/2")
- std::cout << "Bad protocol values" << std::endl;
+ if(r <= 2)
+ {
+ result.test_eq("protocol count", protos.size(), 2);
+ result.test_eq("protocol[0]", protos[0], "test/1");
+ result.test_eq("protocol[1]", protos[1], "test/2");
+ }
return "test/3";
};
@@ -218,28 +218,28 @@ size_t test_tls_handshake(RandomNumberGenerator& rng,
{
std::vector<byte> c2s_traffic, s2c_traffic, client_recv, server_recv, client_sent, server_sent;
- TLS::Server server(queue_inserter(s2c_traffic),
- queue_inserter(server_recv),
- print_alert,
- handshake_complete,
- server_sessions,
- creds,
- policy,
- rng,
- next_protocol_chooser,
- false);
-
- TLS::Client client(queue_inserter(c2s_traffic),
- queue_inserter(client_recv),
- print_alert,
- handshake_complete,
- client_sessions,
- creds,
- policy,
- rng,
- TLS::Server_Information("server.example.com"),
- offer_version,
- protocols_offered);
+ Botan::TLS::Server server(queue_inserter(s2c_traffic),
+ queue_inserter(server_recv),
+ print_alert,
+ handshake_complete,
+ server_sessions,
+ creds,
+ policy,
+ rng,
+ next_protocol_chooser,
+ false);
+
+ Botan::TLS::Client client(queue_inserter(c2s_traffic),
+ queue_inserter(client_recv),
+ print_alert,
+ handshake_complete,
+ client_sessions,
+ creds,
+ policy,
+ rng,
+ Botan::TLS::Server_Information("server.example.com"),
+ offer_version,
+ protocols_offered);
size_t rounds = 0;
@@ -249,8 +249,9 @@ size_t test_tls_handshake(RandomNumberGenerator& rng,
if(rounds > 25)
{
- std::cout << "Still here, something went wrong\n";
- return 1;
+ if(r <= 2)
+ result.test_failure("Still here after many rounds, deadlock?");
+ break;
}
if(handshake_done && (client.is_closed() || server.is_closed()))
@@ -268,75 +269,97 @@ size_t test_tls_handshake(RandomNumberGenerator& rng,
if(server.is_active() && server_sent.empty())
{
- if(server.next_protocol() != "test/3")
- std::cout << "Wrong protocol " << server.next_protocol() << std::endl;
+ result.test_eq("server protocol", server.next_protocol(), "test/3");
const size_t s_len = 1 + rng.next_byte() + rng.next_byte();
server_sent = unlock(rng.random_vec(s_len));
server.send(server_sent);
}
- const bool corrupt_client_data = (r == 3 && c2s_traffic.size() && rng.next_byte() % 3 == 0 && rounds > 1);
- const bool corrupt_server_data = (r == 4 && s2c_traffic.size() && rng.next_byte() % 3 == 0 && rounds > 1);
+ const bool corrupt_client_data = (r == 3 && (rng.next_byte() <= 128 || rounds > 2));
+ const bool corrupt_server_data = (r == 4 && (rng.next_byte() <= 128 || rounds > 2));
- try
+ if(c2s_traffic.size() > 0)
{
/*
* Use this as a temp value to hold the queues as otherwise they
* might end up appending more in response to messages during the
* handshake.
*/
- //std::cout << "server recv " << c2s_traffic.size() << " bytes\n";
std::vector<byte> input;
std::swap(c2s_traffic, input);
if(corrupt_server_data)
{
- //std::cout << "Corrupting server data\n";
- mutate(input, rng);
+ input = Test::mutate_vec(input, true);
+ size_t needed = server.received_data(input.data(), input.size());
+
+ size_t total_consumed = needed;
+
+ while(needed > 0 &&
+ result.test_lt("Never requesting more than max protocol len", needed, 18*1024) &&
+ result.test_lt("Total requested is readonable", total_consumed, 128*1024))
+ {
+ input.resize(needed);
+ Test::rng().randomize(input.data(), input.size());
+ needed = server.received_data(input.data(), input.size());
+ total_consumed += needed;
+ }
}
- server.received_data(input.data(), input.size());
- }
- catch(std::exception& e)
- {
- std::cout << "Server error - " << e.what() << std::endl;
+ else
+ {
+ size_t needed = server.received_data(input.data(), input.size());
+ result.test_eq("full packet received", needed, 0);
+ }
+
continue;
}
- try
+ if(s2c_traffic.size() > 0)
{
- //std::cout << "client recv " << s2c_traffic.size() << " bytes\n";
std::vector<byte> input;
std::swap(s2c_traffic, input);
+
if(corrupt_client_data)
{
- //std::cout << "Corrupting client data\n";
- mutate(input, rng);
+ input = Test::mutate_vec(input, true);
+ size_t needed = client.received_data(input.data(), input.size());
+
+ size_t total_consumed = 0;
+
+ while(needed > 0 && result.test_lt("Never requesting more than max protocol len", needed, 18*1024))
+ {
+ input.resize(needed);
+ Test::rng().randomize(input.data(), input.size());
+ needed = client.received_data(input.data(), input.size());
+ result.test_eq("no more data needed now", needed, 0);
+ total_consumed += needed;
+ }
+ }
+ else
+ {
+ size_t needed = client.received_data(input.data(), input.size());
+ result.test_eq("full packet received", needed, 0);
}
- client.received_data(input.data(), input.size());
- }
- catch(std::exception& e)
- {
- std::cout << "Client error - " << e.what() << std::endl;
continue;
}
if(client_recv.size())
{
- if(client_recv != server_sent)
- {
- std::cout << "Error in client recv" << std::endl;
- return 1;
- }
+ result.test_eq("client recv", client_recv, server_sent);
}
if(server_recv.size())
{
- if(server_recv != client_sent)
+ result.test_eq("server recv", server_recv, client_sent);
+ }
+
+ if(r > 2)
+ {
+ if(client_recv.size() && server_recv.size())
{
- std::cout << "Error in server recv" << std::endl;
- return 1;
+ result.test_failure("Negotiated in the face of data corruption " + std::to_string(r));
}
}
@@ -345,16 +368,10 @@ size_t test_tls_handshake(RandomNumberGenerator& rng,
if(server_recv.size() && client_recv.size())
{
- SymmetricKey client_key = client.key_material_export("label", "context", 32);
- SymmetricKey server_key = server.key_material_export("label", "context", 32);
+ Botan::SymmetricKey client_key = client.key_material_export("label", "context", 32);
+ Botan::SymmetricKey server_key = server.key_material_export("label", "context", 32);
- if(client_key != server_key)
- {
- std::cout << "TLS key material export mismatch: "
- << client_key.as_string() << " != "
- << server_key.as_string() << "\n";
- return 1;
- }
+ result.test_eq("TLS key material export", client_key.bits_of(), server_key.bits_of());
if(r % 2 == 0)
client.close();
@@ -365,49 +382,60 @@ size_t test_tls_handshake(RandomNumberGenerator& rng,
}
catch(std::exception& e)
{
- std::cout << e.what() << "\n";
- return 1;
+ if(r > 2)
+ {
+ result.test_note("Corruption caused exception");
+ }
+ else
+ {
+ result.test_failure("TLS client", e.what());
+ }
}
}
- return 0;
+ result.end_timer();
+
+ return result;
}
-size_t test_dtls_handshake(RandomNumberGenerator& rng,
- TLS::Protocol_Version offer_version,
- Credentials_Manager& creds,
- TLS::Policy& policy)
+Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version,
+ Botan::Credentials_Manager& creds,
+ Botan::TLS::Policy& policy)
{
BOTAN_ASSERT(offer_version.is_datagram_protocol(), "Test is for datagram version");
- TLS::Session_Manager_In_Memory server_sessions(rng);
- TLS::Session_Manager_In_Memory client_sessions(rng);
+ Botan::RandomNumberGenerator& rng = Test::rng();
+
+ Botan::TLS::Session_Manager_In_Memory server_sessions(rng);
+ Botan::TLS::Session_Manager_In_Memory client_sessions(rng);
+
+ Test::Result result(offer_version.to_string());
+
+ result.start_timer();
for(size_t r = 1; r <= 2; ++r)
{
- //std::cout << offer_version.to_string() << " round " << r << "\n";
-
bool handshake_done = false;
- auto handshake_complete = [&](const TLS::Session& session) -> bool {
+ auto handshake_complete = [&](const Botan::TLS::Session& session) -> bool {
handshake_done = true;
- /*
- std::cout << "Session established " << session.version().to_string() << " "
- << session.ciphersuite().to_string() << " " << hex_encode(session.session_id()) << "\n";
- */
-
if(session.version() != offer_version)
- std::cout << "Offered " << offer_version.to_string()
- << " got " << session.version().to_string() << std::endl;
+ {
+ result.test_failure("Offered " + offer_version.to_string() +
+ " got " + session.version().to_string());
+ }
+
return true;
- };
+ };
auto next_protocol_chooser = [&](std::vector<std::string> protos) {
- if(protos.size() != 2)
- std::cout << "Bad protocol size" << std::endl;
- if(protos[0] != "test/1" || protos[1] != "test/2")
- std::cout << "Bad protocol values" << std::endl;
+ if(r <= 2)
+ {
+ result.test_eq("protocol count", protos.size(), 2);
+ result.test_eq("protocol[0]", protos[0], "test/1");
+ result.test_eq("protocol[1]", protos[1], "test/2");
+ }
return "test/3";
};
@@ -417,28 +445,28 @@ size_t test_dtls_handshake(RandomNumberGenerator& rng,
{
std::vector<byte> c2s_traffic, s2c_traffic, client_recv, server_recv, client_sent, server_sent;
- TLS::Server server(queue_inserter(s2c_traffic),
- queue_inserter(server_recv),
- print_alert,
- handshake_complete,
- server_sessions,
- creds,
- policy,
- rng,
- next_protocol_chooser,
- true);
-
- TLS::Client client(queue_inserter(c2s_traffic),
- queue_inserter(client_recv),
- print_alert,
- handshake_complete,
- client_sessions,
- creds,
- policy,
- rng,
- TLS::Server_Information("server.example.com"),
- offer_version,
- protocols_offered);
+ Botan::TLS::Server server(queue_inserter(s2c_traffic),
+ queue_inserter(server_recv),
+ print_alert,
+ handshake_complete,
+ server_sessions,
+ creds,
+ policy,
+ rng,
+ next_protocol_chooser,
+ true);
+
+ Botan::TLS::Client client(queue_inserter(c2s_traffic),
+ queue_inserter(client_recv),
+ print_alert,
+ handshake_complete,
+ client_sessions,
+ creds,
+ policy,
+ rng,
+ Botan::TLS::Server_Information("server.example.com"),
+ offer_version,
+ protocols_offered);
size_t rounds = 0;
@@ -450,8 +478,8 @@ size_t test_dtls_handshake(RandomNumberGenerator& rng,
if(rounds > 100)
{
- std::cout << "Still here, something went wrong\n";
- return 1;
+ result.test_failure("Still here after many rounds");
+ break;
}
if(handshake_done && (client.is_closed() || server.is_closed()))
@@ -464,65 +492,105 @@ size_t test_dtls_handshake(RandomNumberGenerator& rng,
client_sent = unlock(rng.random_vec(c_len));
// TODO send multiple parts
- //std::cout << "Sending " << client_sent.size() << " bytes to server\n";
client.send(client_sent);
}
if(server.is_active() && server_sent.empty())
{
- if(server.next_protocol() != "test/3")
- std::cout << "Wrong protocol " << server.next_protocol() << std::endl;
+ result.test_eq("server ALPN", server.next_protocol(), "test/3");
const size_t s_len = 1 + rng.next_byte() + rng.next_byte();
server_sent = unlock(rng.random_vec(s_len));
- //std::cout << "Sending " << server_sent.size() << " bytes to client\n";
server.send(server_sent);
}
- const bool corrupt_client_data = (r == 3 && c2s_traffic.size() && rng.next_byte() % 3 == 0 && rounds < 10);
- const bool corrupt_server_data = (r == 4 && s2c_traffic.size() && rng.next_byte() % 3 == 0 && rounds < 10);
+ const bool corrupt_client_data = (r == 3 && rng.next_byte() % 3 <= 1 && rounds < 10);
+ const bool corrupt_server_data = (r == 4 && rng.next_byte() % 3 <= 1 && rounds < 10);
- try
+ if(c2s_traffic.size() > 0)
{
/*
* Use this as a temp value to hold the queues as otherwise they
* might end up appending more in response to messages during the
* handshake.
*/
- //std::cout << "server got " << c2s_traffic.size() << " bytes\n";
std::vector<byte> input;
std::swap(c2s_traffic, input);
- if(corrupt_client_data)
+ if(corrupt_server_data)
{
- //std::cout << "Corrupting client data\n";
- mutate(input, rng);
+ try
+ {
+ input = Test::mutate_vec(input, true);
+ size_t needed = server.received_data(input.data(), input.size());
+
+ if(needed > 0 && result.test_lt("Never requesting more than max protocol len", needed, 18*1024))
+ {
+ input.resize(needed);
+ Test::rng().randomize(input.data(), input.size());
+ needed = client.received_data(input.data(), input.size());
+ result.test_eq("no more data needed now", needed, 0);
+ }
+ }
+ catch(std::exception& e)
+ {
+ result.test_note("corruption caused server exception");
+ }
+ }
+ else
+ {
+ try
+ {
+ size_t needed = server.received_data(input.data(), input.size());
+ result.test_eq("full packet received", needed, 0);
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure("server error", e.what());
+ }
}
- server.received_data(input.data(), input.size());
- }
- catch(std::exception& e)
- {
- std::cout << "Server error - " << e.what() << std::endl;
continue;
}
- try
+ if(s2c_traffic.size() > 0)
{
- //std::cout << "client got " << s2c_traffic.size() << " bytes\n";
std::vector<byte> input;
std::swap(s2c_traffic, input);
- if(corrupt_server_data)
+ if(corrupt_client_data)
{
- //std::cout << "Corrupting server data\n";
- mutate(input, rng);
+ try
+ {
+ input = Test::mutate_vec(input, true);
+ size_t needed = client.received_data(input.data(), input.size());
+
+ if(needed > 0 && result.test_lt("Never requesting more than max protocol len", needed, 18*1024))
+ {
+ input.resize(needed);
+ Test::rng().randomize(input.data(), input.size());
+ needed = client.received_data(input.data(), input.size());
+ result.test_eq("no more data needed now", needed, 0);
+ }
+ }
+ catch(std::exception& e)
+ {
+ result.test_note("corruption caused client exception");
+ }
}
- client.received_data(input.data(), input.size());
- }
- catch(std::exception& e)
- {
- std::cout << "Client error - " << e.what() << std::endl;
+ else
+ {
+ try
+ {
+ size_t needed = client.received_data(input.data(), input.size());
+ result.test_eq("full packet received", needed, 0);
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure("client error", e.what());
+ }
+ }
+
continue;
}
@@ -534,20 +602,12 @@ size_t test_dtls_handshake(RandomNumberGenerator& rng,
if(client_recv.size())
{
- if(client_recv != server_sent)
- {
- std::cout << "Error in client recv" << std::endl;
- return 1;
- }
+ result.test_eq("client recv", client_recv, server_sent);
}
if(server_recv.size())
{
- if(server_recv != client_sent)
- {
- std::cout << "Error in server recv" << std::endl;
- return 1;
- }
+ result.test_eq("server recv", server_recv, client_sent);
}
if(client.is_closed() && server.is_closed())
@@ -555,16 +615,10 @@ size_t test_dtls_handshake(RandomNumberGenerator& rng,
if(server_recv.size() && client_recv.size())
{
- SymmetricKey client_key = client.key_material_export("label", "context", 32);
- SymmetricKey server_key = server.key_material_export("label", "context", 32);
+ Botan::SymmetricKey client_key = client.key_material_export("label", "context", 32);
+ Botan::SymmetricKey server_key = server.key_material_export("label", "context", 32);
- if(client_key != server_key)
- {
- std::cout << "TLS key material export mismatch: "
- << client_key.as_string() << " != "
- << server_key.as_string() << "\n";
- return 1;
- }
+ result.test_eq("key material export", client_key.bits_of(), server_key.bits_of());
if(r % 2 == 0)
client.close();
@@ -575,72 +629,108 @@ size_t test_dtls_handshake(RandomNumberGenerator& rng,
}
catch(std::exception& e)
{
- std::cout << e.what() << "\n";
- return 1;
+ if(r > 2)
+ {
+ result.test_note("Corruption caused failure");
+ }
+ else
+ {
+ result.test_failure("DTLS handshake", e.what());
+ }
}
}
- return 0;
+ result.end_timer();
+ return result;
}
-class Test_Policy : public TLS::Text_Policy
+class Test_Policy : public Botan::TLS::Text_Policy
{
public:
Test_Policy() : Text_Policy("") {}
- bool acceptable_protocol_version(TLS::Protocol_Version) const override { return true; }
- bool send_fallback_scsv(TLS::Protocol_Version) const override { return false; }
+ bool acceptable_protocol_version(Botan::TLS::Protocol_Version) const override { return true; }
+ bool send_fallback_scsv(Botan::TLS::Protocol_Version) const override { return false; }
size_t dtls_initial_timeout() const override { return 1; }
size_t dtls_maximum_timeout() const override { return 8; }
};
-}
-size_t test_tls()
+class TLS_Unit_Tests : public Test
{
- size_t errors = 0;
-
- auto& rng = test_rng();
- std::unique_ptr<Credentials_Manager> basic_creds(create_creds());
-
- Test_Policy policy;
- errors += test_tls_handshake(rng, TLS::Protocol_Version::TLS_V10, *basic_creds, policy);
- errors += test_tls_handshake(rng, TLS::Protocol_Version::TLS_V11, *basic_creds, policy);
- errors += test_tls_handshake(rng, TLS::Protocol_Version::TLS_V12, *basic_creds, policy);
- errors += test_dtls_handshake(rng, TLS::Protocol_Version::DTLS_V10, *basic_creds, policy);
- errors += test_dtls_handshake(rng, TLS::Protocol_Version::DTLS_V12, *basic_creds, policy);
-
- policy.set("key_exchange_methods", "RSA");
- errors += test_tls_handshake(rng, TLS::Protocol_Version::TLS_V10, *basic_creds, policy);
- errors += test_tls_handshake(rng, TLS::Protocol_Version::TLS_V11, *basic_creds, policy);
- errors += test_tls_handshake(rng, TLS::Protocol_Version::TLS_V12, *basic_creds, policy);
- errors += test_dtls_handshake(rng, TLS::Protocol_Version::DTLS_V10, *basic_creds, policy);
- errors += test_dtls_handshake(rng, TLS::Protocol_Version::DTLS_V12, *basic_creds, policy);
-
- policy.set("key_exchange_methods", "DH");
- errors += test_tls_handshake(rng, TLS::Protocol_Version::TLS_V10, *basic_creds, policy);
- errors += test_tls_handshake(rng, TLS::Protocol_Version::TLS_V11, *basic_creds, policy);
- policy.set("key_exchange_methods", "ECDH");
- errors += test_tls_handshake(rng, TLS::Protocol_Version::TLS_V12, *basic_creds, policy);
- errors += test_dtls_handshake(rng, TLS::Protocol_Version::DTLS_V10, *basic_creds, policy);
- errors += test_dtls_handshake(rng, TLS::Protocol_Version::DTLS_V12, *basic_creds, policy);
-
- policy.set("ciphers", "AES-128");
- errors += test_tls_handshake(rng, TLS::Protocol_Version::TLS_V10, *basic_creds, policy);
- errors += test_tls_handshake(rng, TLS::Protocol_Version::TLS_V11, *basic_creds, policy);
- errors += test_tls_handshake(rng, TLS::Protocol_Version::TLS_V12, *basic_creds, policy);
- errors += test_dtls_handshake(rng, TLS::Protocol_Version::DTLS_V10, *basic_creds, policy);
- errors += test_dtls_handshake(rng, TLS::Protocol_Version::DTLS_V12, *basic_creds, policy);
-
- policy.set("ciphers", "ChaCha20Poly1305");
- errors += test_tls_handshake(rng, TLS::Protocol_Version::TLS_V12, *basic_creds, policy);
- errors += test_dtls_handshake(rng, TLS::Protocol_Version::DTLS_V12, *basic_creds, policy);
-
- test_report("TLS", 22, errors);
-
- return errors;
- }
+ public:
+ std::vector<Test::Result> run() override
+ {
+ std::unique_ptr<Botan::Credentials_Manager> basic_creds(create_creds());
+ std::vector<Test::Result> results;
+
+ Test_Policy policy;
+ results.push_back(test_tls_handshake(Botan::TLS::Protocol_Version::TLS_V10, *basic_creds, policy));
+
+ results.push_back(test_tls_handshake(Botan::TLS::Protocol_Version::TLS_V11, *basic_creds, policy));
+ results.push_back(test_tls_handshake(Botan::TLS::Protocol_Version::TLS_V12, *basic_creds, policy));
+ results.push_back(test_dtls_handshake(Botan::TLS::Protocol_Version::DTLS_V10, *basic_creds, policy));
+ results.push_back(test_dtls_handshake(Botan::TLS::Protocol_Version::DTLS_V12, *basic_creds, policy));
+
+ policy.set("key_exchange_methods", "RSA");
+ results.push_back(test_tls_handshake(Botan::TLS::Protocol_Version::TLS_V10, *basic_creds, policy));
+ results.push_back(test_tls_handshake(Botan::TLS::Protocol_Version::TLS_V11, *basic_creds, policy));
+ results.push_back(test_tls_handshake(Botan::TLS::Protocol_Version::TLS_V12, *basic_creds, policy));
+ results.push_back(test_dtls_handshake(Botan::TLS::Protocol_Version::DTLS_V10, *basic_creds, policy));
+ results.push_back(test_dtls_handshake(Botan::TLS::Protocol_Version::DTLS_V12, *basic_creds, policy));
+
+ policy.set("key_exchange_methods", "DH");
+ results.push_back(test_tls_handshake(Botan::TLS::Protocol_Version::TLS_V10, *basic_creds, policy));
+ results.push_back(test_tls_handshake(Botan::TLS::Protocol_Version::TLS_V11, *basic_creds, policy));
+
+ policy.set("key_exchange_methods", "ECDH");
+ results.push_back(test_tls_handshake(Botan::TLS::Protocol_Version::TLS_V12, *basic_creds, policy));
+ results.push_back(test_dtls_handshake(Botan::TLS::Protocol_Version::DTLS_V10, *basic_creds, policy));
+ results.push_back(test_dtls_handshake(Botan::TLS::Protocol_Version::DTLS_V12, *basic_creds, policy));
+
+ policy.set("ciphers", "AES-128");
+ results.push_back(test_tls_handshake(Botan::TLS::Protocol_Version::TLS_V10, *basic_creds, policy));
+ results.push_back(test_tls_handshake(Botan::TLS::Protocol_Version::TLS_V11, *basic_creds, policy));
+ results.push_back(test_tls_handshake(Botan::TLS::Protocol_Version::TLS_V12, *basic_creds, policy));
+ results.push_back(test_dtls_handshake(Botan::TLS::Protocol_Version::DTLS_V10, *basic_creds, policy));
+ results.push_back(test_dtls_handshake(Botan::TLS::Protocol_Version::DTLS_V12, *basic_creds, policy));
+
+#if defined(BOTAN_HAS_AEAD_OCB)
+ policy.set("ciphers", "AES-128/OCB(12)");
+ results.push_back(test_tls_handshake(Botan::TLS::Protocol_Version::TLS_V12, *basic_creds, policy));
+ results.push_back(test_dtls_handshake(Botan::TLS::Protocol_Version::DTLS_V12, *basic_creds, policy));
+#endif
-#else
-size_t test_tls() { return 0; }
+#if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305)
+ policy.set("ciphers", "ChaCha20Poly1305");
+ results.push_back(test_tls_handshake(Botan::TLS::Protocol_Version::TLS_V12, *basic_creds, policy));
+ results.push_back(test_dtls_handshake(Botan::TLS::Protocol_Version::DTLS_V12, *basic_creds, policy));
#endif
+
+ policy.set("ciphers", "AES-128/GCM");
+ policy.set("key_exchange_methods", "PSK");
+ results.push_back(test_tls_handshake(Botan::TLS::Protocol_Version::TLS_V12, *basic_creds, policy));
+ results.push_back(test_dtls_handshake(Botan::TLS::Protocol_Version::DTLS_V12, *basic_creds, policy));
+
+ // For whatever reason no (EC)DHE_PSK GCM ciphersuites are defined
+ policy.set("ciphers", "AES-128");
+ policy.set("key_exchange_methods", "ECDHE_PSK");
+ results.push_back(test_tls_handshake(Botan::TLS::Protocol_Version::TLS_V12, *basic_creds, policy));
+ results.push_back(test_dtls_handshake(Botan::TLS::Protocol_Version::DTLS_V12, *basic_creds, policy));
+
+ policy.set("key_exchange_methods", "DHE_PSK");
+ results.push_back(test_tls_handshake(Botan::TLS::Protocol_Version::TLS_V12, *basic_creds, policy));
+ results.push_back(test_dtls_handshake(Botan::TLS::Protocol_Version::DTLS_V12, *basic_creds, policy));
+
+ return results;
+ }
+
+ };
+
+BOTAN_REGISTER_TEST("tls", TLS_Unit_Tests);
+
+#endif
+
+}
+
+}
diff --git a/src/tests/unit_x509.cpp b/src/tests/unit_x509.cpp
index 0d3946012..08ed5b578 100644
--- a/src/tests/unit_x509.cpp
+++ b/src/tests/unit_x509.cpp
@@ -8,8 +8,6 @@
#if defined(BOTAN_HAS_X509_CERTIFICATES)
-#if defined(BOTAN_HAS_RSA) && defined(BOTAN_HAS_DSA)
-
#include <botan/calendar.h>
#include <botan/pkcs8.h>
#include <botan/hash.h>
@@ -30,34 +28,24 @@
#include <botan/ecdsa.h>
#endif
-#include <iostream>
-#include <memory>
+#endif
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-X509_Time from_date(const int y, const int m, const int d)
- {
- auto t = calendar_point(y, m, d, 0, 0, 0);
- return X509_Time(t.to_std_timepoint());
- }
+#if defined(BOTAN_HAS_X509_CERTIFICATES)
-u64bit key_id(const Public_Key* key)
+Botan::X509_Time from_date(const int y, const int m, const int d)
{
- std::unique_ptr<HashFunction> hash(HashFunction::create("SHA-1"));
- hash->update(key->algo_name());
- hash->update(key->algorithm_identifier().parameters);
- hash->update(key->x509_subject_public_key());
- secure_vector<byte> output = hash->final();
- return load_be<u64bit>(output.data(), 0);
+ Botan::calendar_point t(y, m, d, 0, 0, 0);
+ return Botan::X509_Time(t.to_std_timepoint());
}
-
/* Return some option sets */
-X509_Cert_Options ca_opts()
+Botan::X509_Cert_Options ca_opts()
{
- X509_Cert_Options opts("Test CA/US/Botan Project/Testing");
+ Botan::X509_Cert_Options opts("Test CA/US/Botan Project/Testing");
opts.uri = "http://botan.randombit.net";
opts.dns = "botan.randombit.net";
@@ -68,9 +56,9 @@ X509_Cert_Options ca_opts()
return opts;
}
-X509_Cert_Options req_opts1()
+Botan::X509_Cert_Options req_opts1()
{
- X509_Cert_Options opts("Test User 1/US/Botan Project/Testing");
+ Botan::X509_Cert_Options opts("Test User 1/US/Botan Project/Testing");
opts.uri = "http://botan.randombit.net";
opts.dns = "botan.randombit.net";
@@ -79,9 +67,9 @@ X509_Cert_Options req_opts1()
return opts;
}
-X509_Cert_Options req_opts2()
+Botan::X509_Cert_Options req_opts2()
{
- X509_Cert_Options opts("Test User 2/US/Botan Project/Testing");
+ Botan::X509_Cert_Options opts("Test User 2/US/Botan Project/Testing");
opts.uri = "http://botan.randombit.net";
opts.dns = "botan.randombit.net";
@@ -92,164 +80,253 @@ X509_Cert_Options req_opts2()
return opts;
}
-u32bit check_against_copy(const Private_Key& orig,
- RandomNumberGenerator& rng)
+std::unique_ptr<Botan::Private_Key> make_a_private_key()
{
- Private_Key* copy_priv = PKCS8::copy_key(orig, rng);
- Public_Key* copy_pub = X509::copy_key(orig);
-
- const std::string passphrase= "I need work! -Mr. T";
- DataSource_Memory enc_source(PKCS8::PEM_encode(orig, rng, passphrase));
- Private_Key* copy_priv_enc = PKCS8::load_key(enc_source, rng,
- passphrase);
-
- u64bit orig_id = key_id(&orig);
- u64bit pub_id = key_id(copy_pub);
- u64bit priv_id = key_id(copy_priv);
- u64bit priv_enc_id = key_id(copy_priv_enc);
-
- delete copy_pub;
- delete copy_priv;
- delete copy_priv_enc;
+#if defined(BOTAN_HAS_DSA)
+ if(Test::rng().next_byte() < 32)
+ {
+ Botan::DL_Group grp("dsa/botan/2048");
+ return std::unique_ptr<Botan::Private_Key>(new Botan::DSA_PrivateKey(Test::rng(), grp));
+ }
+#endif
- if(orig_id != pub_id || orig_id != priv_id || orig_id != priv_enc_id)
+#if defined(BOTAN_HAS_RSA)
+ if(Test::rng().next_byte() < 32)
{
- std::cout << "Failed copy check for " << orig.algo_name() << std::endl;
- return 1;
+ return std::unique_ptr<Botan::Private_Key>(new Botan::RSA_PrivateKey(Test::rng(), 1536));
}
- return 0;
- }
+#endif
-}
+#if defined(BOTAN_HAS_ECDSA)
+ Botan::EC_Group grp("secp256r1");
+ return std::unique_ptr<Botan::Private_Key>(new Botan::ECDSA_PrivateKey(Test::rng(), grp));
+#endif
-size_t test_x509()
+ throw std::runtime_error("Skipping X.509 cert test due to missing algos");
+ }
+
+class X509_Cert_Unit_Tests : public Test
{
- auto& rng = test_rng();
- const std::string hash_fn = "SHA-256";
+ public:
+ std::vector<Test::Result> run() override;
+
+ private:
+ Test::Result test_x509_dates()
+ {
+ Test::Result result("X509_Time");
+
+ Botan::X509_Time time;
+ result.confirm("unset time not set", !time.time_is_set());
+ time = Botan::X509_Time("0802011822Z", Botan::ASN1_Tag::UTC_TIME);
+ result.confirm("time set after construction", time.time_is_set());
+ result.test_eq("time readable_string", time.readable_string(), "2008/02/01 18:22:00 UTC");
+
+ const std::vector<std::string> valid = {
+ "0802010000Z",
+ "0802011724Z",
+ "0406142334Z",
+ "9906142334Z",
+ "0006142334Z",
+
+ "080201000000Z",
+ "080201172412Z",
+ "040614233433Z",
+ "990614233444Z",
+ "000614233455Z",
+ };
+
+ // Dates that are valid per X.500 but rejected as unsupported
+ const std::vector<std::string> valid_but_unsup = {
+ "0802010000-0000",
+ "0802011724+0000",
+ "0406142334-0500",
+ "9906142334+0500",
+ "0006142334-0530",
+ "0006142334+0530",
+
+ "080201000000-0000",
+ "080201172412+0000",
+ "040614233433-0500",
+ "990614233444+0500",
+ "000614233455-0530",
+ "000614233455+0530",
+ };
+
+ const std::vector<std::string> invalid = {
+ "",
+ " ",
+ "2008`02-01",
+ "9999-02-01",
+ "2000-02-01 17",
+ "999921",
+
+ // valid length 13 -> range check
+ "080201000061Z", // seconds too big (61)
+ "080201000060Z", // seconds too big (60, leap seconds not covered by the standard)
+ "0802010000-1Z", // seconds too small (-1)
+ "080201006000Z", // minutes too big (60)
+ "080201240000Z", // hours too big (24:00)
+
+ // valid length 13 -> invalid numbers
+ "08020123112 Z",
+ "08020123112!Z",
+ "08020123112,Z",
+ "08020123112\nZ",
+ "080201232 33Z",
+ "080201232!33Z",
+ "080201232,33Z",
+ "080201232\n33Z",
+ "0802012 3344Z",
+ "0802012!3344Z",
+ "0802012,3344Z",
+ "08022\n334455Z",
+ "08022 334455Z",
+ "08022!334455Z",
+ "08022,334455Z",
+ "08022\n334455Z",
+ "082 33445511Z",
+ "082!33445511Z",
+ "082,33445511Z",
+ "082\n33445511Z",
+ "2 2211221122Z",
+ "2!2211221122Z",
+ "2,2211221122Z",
+ "2\n2211221122Z",
+
+ // wrong time zone
+ "0802010000",
+ "0802010000z"
+ };
+
+ for(auto&& v : valid)
+ {
+ Botan::X509_Time t(v, Botan::ASN1_Tag::UTC_TIME);
+ }
+
+ for(auto&& v : valid_but_unsup)
+ {
+ result.test_throws("valid but unsupported", [v]() { Botan::X509_Time t(v, Botan::ASN1_Tag::UTC_TIME); });
+ }
+
+ for(auto&& v : invalid)
+ {
+ result.test_throws("invalid", [v]() { Botan::X509_Time t(v, Botan::ASN1_Tag::UTC_TIME); });
+ }
+
+ return result;
+ }
+ };
+
+std::vector<Test::Result> X509_Cert_Unit_Tests::run()
+ {
+ std::vector<Test::Result> results;
+ Test::Result result("X509 Unit");
- size_t fails = 0;
+ const std::string hash_fn = "SHA-256";
/* Create the CA's key and self-signed cert */
- RSA_PrivateKey ca_key(rng, 2048);
+ std::unique_ptr<Botan::Private_Key> ca_key(make_a_private_key());
+
+ Botan::X509_Certificate ca_cert =
+ Botan::X509::create_self_signed_cert(ca_opts(),
+ *ca_key,
+ hash_fn,
+ Test::rng());
- X509_Certificate ca_cert = X509::create_self_signed_cert(ca_opts(),
- ca_key,
- hash_fn,
- rng);
/* Create user #1's key and cert request */
- DSA_PrivateKey user1_key(rng, DL_Group("dsa/botan/2048"));
+ std::unique_ptr<Botan::Private_Key> user1_key(make_a_private_key());
- PKCS10_Request user1_req = X509::create_cert_req(req_opts1(),
- user1_key,
- "SHA-1",
- rng);
+ Botan::PKCS10_Request user1_req =
+ Botan::X509::create_cert_req(req_opts1(),
+ *user1_key,
+ hash_fn,
+ Test::rng());
/* Create user #2's key and cert request */
-#if defined(BOTAN_HAS_ECDSA)
- EC_Group ecc_domain(OID("1.2.840.10045.3.1.7"));
- ECDSA_PrivateKey user2_key(rng, ecc_domain);
-#else
- RSA_PrivateKey user2_key(rng, 1536);
-#endif
+ std::unique_ptr<Botan::Private_Key> user2_key(make_a_private_key());
- PKCS10_Request user2_req = X509::create_cert_req(req_opts2(),
- user2_key,
- hash_fn,
- rng);
+ Botan::PKCS10_Request user2_req =
+ Botan::X509::create_cert_req(req_opts2(),
+ *user2_key,
+ hash_fn,
+ Test::rng());
/* Create the CA object */
- X509_CA ca(ca_cert, ca_key, hash_fn);
+ Botan::X509_CA ca(ca_cert, *ca_key, hash_fn);
/* Sign the requests to create the certs */
- X509_Certificate user1_cert =
- ca.sign_request(user1_req, rng,
- from_date(2008, 01, 01), from_date(2033, 01, 01));
+ Botan::X509_Certificate user1_cert =
+ ca.sign_request(user1_req, Test::rng(),
+ from_date(2008, 01, 01),
+ from_date(2033, 01, 01));
- X509_Certificate user2_cert = ca.sign_request(user2_req, rng,
+ Botan::X509_Certificate user2_cert = ca.sign_request(user2_req, Test::rng(),
from_date(2008, 01, 01),
from_date(2033, 01, 01));
- X509_CRL crl1 = ca.new_crl(rng);
+ Botan::X509_CRL crl1 = ca.new_crl(Test::rng());
/* Verify the certs */
- Certificate_Store_In_Memory store;
+ Botan::Certificate_Store_In_Memory store;
store.add_certificate(ca_cert);
- Path_Validation_Restrictions restrictions(false);
+ Botan::Path_Validation_Restrictions restrictions(false);
- Path_Validation_Result result_u1 = x509_path_validate(user1_cert, restrictions, store);
- if(!result_u1.successful_validation())
+ Botan::Path_Validation_Result result_u1 = Botan::x509_path_validate(user1_cert, restrictions, store);
+ if(!result.confirm("user 1 validates", result_u1.successful_validation()))
{
- std::cout << "FAILED: User cert #1 did not validate - "
- << result_u1.result_string() << std::endl;
- ++fails;
+ result.test_note("user 1 validation result was " + result_u1.result_string());
}
- Path_Validation_Result result_u2 = x509_path_validate(user2_cert, restrictions, store);
- if(!result_u2.successful_validation())
+ Botan::Path_Validation_Result result_u2 = Botan::x509_path_validate(user2_cert, restrictions, store);
+ if(!result.confirm("user 2 validates", result_u2.successful_validation()))
{
- std::cout << "FAILED: User cert #2 did not validate - "
- << result_u2.result_string() << std::endl;
- ++fails;
+ result.test_note("user 2 validation result was " + result_u2.result_string());
}
store.add_crl(crl1);
- std::vector<CRL_Entry> revoked;
- revoked.push_back(CRL_Entry(user1_cert, CESSATION_OF_OPERATION));
+ std::vector<Botan::CRL_Entry> revoked;
+ revoked.push_back(Botan::CRL_Entry(user1_cert, Botan::CESSATION_OF_OPERATION));
revoked.push_back(user2_cert);
- X509_CRL crl2 = ca.update_crl(crl1, revoked, rng);
+ Botan::X509_CRL crl2 = ca.update_crl(crl1, revoked, Test::rng());
store.add_crl(crl2);
- result_u1 = x509_path_validate(user1_cert, restrictions, store);
- if(result_u1.result() != Certificate_Status_Code::CERT_IS_REVOKED)
- {
- std::cout << "FAILED: User cert #1 was not revoked - "
- << result_u1.result_string() << std::endl;
- ++fails;
- }
+ const std::string revoked_str =
+ Botan::Path_Validation_Result::status_string(Botan::Certificate_Status_Code::CERT_IS_REVOKED);
- result_u2 = x509_path_validate(user2_cert, restrictions, store);
- if(result_u2.result() != Certificate_Status_Code::CERT_IS_REVOKED)
- {
- std::cout << "FAILED: User cert #2 was not revoked - "
- << result_u2.result_string() << std::endl;
- ++fails;
- }
+ result_u1 = Botan::x509_path_validate(user1_cert, restrictions, store);
+ result.test_eq("user 1 revoked", result_u1.result_string(), revoked_str);
+
+ result_u2 = Botan::x509_path_validate(user2_cert, restrictions, store);
+ result.test_eq("user 1 revoked", result_u2.result_string(), revoked_str);
revoked.clear();
- revoked.push_back(CRL_Entry(user1_cert, REMOVE_FROM_CRL));
- X509_CRL crl3 = ca.update_crl(crl2, revoked, rng);
+ revoked.push_back(Botan::CRL_Entry(user1_cert, Botan::REMOVE_FROM_CRL));
+ Botan::X509_CRL crl3 = ca.update_crl(crl2, revoked, Test::rng());
store.add_crl(crl3);
- result_u1 = x509_path_validate(user1_cert, restrictions, store);
- if(!result_u1.successful_validation())
+ result_u1 = Botan::x509_path_validate(user1_cert, restrictions, store);
+ if(!result.confirm("user 1 validates", result_u1.successful_validation()))
{
- std::cout << "FAILED: User cert #1 was not un-revoked - "
- << result_u1.result_string() << std::endl;
- ++fails;
+ result.test_note("user 1 validation result was " + result_u1.result_string());
}
- check_against_copy(ca_key, rng);
- check_against_copy(user1_key, rng);
- check_against_copy(user2_key, rng);
+ result_u2 = Botan::x509_path_validate(user2_cert, restrictions, store);
+ result.test_eq("user 2 still revoked", result_u2.result_string(), revoked_str);
- test_report("X509", 0, fails);
-
- return fails;
+ results.push_back(result);
+ results.push_back(test_x509_dates());
+ return results;
}
-#else
-
-UNTESTED_WARNING(x509);
+BOTAN_REGISTER_TEST("unit_x509", X509_Cert_Unit_Tests);
-#endif // BOTAN_HAS_RSA && BOTAN_HAS_DSA
-
-#else
+#endif
-SKIP_TEST(x509);
+}
-#endif // BOTAN_HAS_X509_CERTIFICATES
+}