diff options
120 files changed, 9382 insertions, 21886 deletions
diff --git a/botan_version.py b/botan_version.py index a99c6fc51..bb1431155 100644 --- a/botan_version.py +++ b/botan_version.py @@ -1,7 +1,7 @@ release_major = 1 release_minor = 11 -release_patch = 24 +release_patch = 25 release_so_abi_rev = release_patch # These are set by the distribution script diff --git a/doc/credits.rst b/doc/credits.rst index d979245c2..8a18d2237 100644 --- a/doc/credits.rst +++ b/doc/credits.rst @@ -84,8 +84,18 @@ snail-mail address (S), and Bitcoin address (B). D: x86/amd64 assembler, BigInt optimizations, Win32 mutex module S: Italy + N: Daniel Seither + E: [email protected] + D: iOS support, improved Android support, improved MSVC support + N: Falko Strenzke W: http://www.cryptosource.de D: McEliece, GF(p) arithmetic, CVC, Shanks-Tonelli algorithm S: Darmstadt, Germany + + N: Simon Warta + E: [email protected] + W: https://www.kullo.net + D: Build system + S: Germany diff --git a/doc/hacking.rst b/doc/hacking.rst index 3196faa0a..41ec9ca01 100644 --- a/doc/hacking.rst +++ b/doc/hacking.rst @@ -13,7 +13,7 @@ Under `src` there are directories example `build-data/cc/gcc.txt` describes various gcc options. * `scripts` contains various scripts: install, distribution, various codegen things. Scripts controlling CI go under `scripts/ci`. -* `python` and `ocaml` are the FFI bindings for those languages +* `python/botan.py` is the Python ctypes wrapper Library Layout ======================================== @@ -49,16 +49,50 @@ Library Layout * `ffi` is the C99 API * `vendor` contains bindings to external libraries like OpenSSL and Sqlite3 +Copyright Notice +======================================== + +At the top of any new file add a comment with a copyright and +a reference to the license, for examplee:: + + /* + * (C) 2015,2016 Copyright Holder + * Botan is released under the Simplified BSD License (see license.txt) + */ + +If you are making a substantial or non-trivial change to an existing +file, add or update your own copyright statement at the top of the +file. If you are making a change in a new year not covered by your +existing statement, add the year. Even if the years you are making the +change are consecutive, avoid year ranges: specify each year separated +by a comma. + +Also if you are a new contributor or making an addition in a new year, +include an update to `doc/license.txt` in your PR. + Style Conventions ======================================== When writing your code remember the need for it to be easily -understood by reviewers/auditors, both at the time of the patch +understood by reviewers and auditors, both at the time of the patch submission and in the future. Avoid complicated template metaprogramming where possible. It has its places but should be used judiciously. +When designing a new API (for use either by library users or just +internally) try writing out the calling code first. That is, write out +some code calling your idealized API, then just implement that. This +can often help avoid cut-and-paste by creating the correct abstractions +needed to solve the problem at hand. + +The C++11 `auto` keyword is very convenient but only use it when the +type truly is obvious (considering also the potential for unexpected +integer conversions and the like, such as an apparent uint8_t being +promoted to an int). + +Use `override` annotations whenever possible. + A formatting setup for emacs is included in `scripts/indent.el` but the basic formatting style should be obvious. No tabs, and remove trailing whitespace. @@ -73,14 +107,51 @@ this. Sending patches ======================================== -All contributions should be submitted as pull requests via the github page. -If you are planning a large change email the mailing list or open a -discussion ticket on github before starting out. +All contributions should be submitted as pull requests via GitHub +(https://github.com/randombit/botan). If you are planning a large +change email the mailing list or open a discussion ticket on github +before starting out to make sure you are on the right path to +something which we'll be able to accept. + +Depending on what your change is, your PR should probably also include +an update to `doc/news.rst` with a note explaining the change. If your +change is a simple bug fix, a one sentence description is perhaps +sufficient. If there is an existing ticket on GitHub with discussion +or other information, reference it in your change note as 'GH #000'. + +Update `doc/credits.txt` with your information so people know what +you did! (This is optional) If you are interested in contributing but don't know where to start -check out todo.rst for some ideas - these are projects we would almost -certainly accept if the code quality was high. +check out `doc/todo.rst` for some ideas - these are changes we would +almost certainly accept once they've passed code review. Also, try building and testing it on whatever hardware you have handy, especially non-x86 platforms, or especially C++11 compilers other than the regularly tested GCC, Clang, and Visual Studio compilers. + +Build Tools and Hints +======================================== + +If you don't already use it for all your C/C++ development, install +`ccache` now and configure a large cache on a fast disk. It allows for +very quick rebuilds by caching the compiler output. + +Use `--with-sanitizers` to enable ASan. UBSan has to be added separately +with --cc-abi-flags at the moment as GCC 4.8 does not have UBSan. + +Other Ways You Can Help +======================================== + +Convince your employer that the software your company uses and relies on is +worth the time and cost of serious audit. The code may be free, but you are +still using it - so make sure it is any good. Fund code and design reviews +whenever you can of the free software your company relies on, including Botan, +then share the results with the developers to improve the ecosystem for everyone. + +Funding Development +======================================== + +If there is a change you'd like implemented in the library but you'd rather not, +or can't, write it yourself, you can contact Jack Lloyd who in addition to being +the primary author also works as a freelance contractor and security consultant. diff --git a/doc/license.txt b/doc/license.txt index 02dcb0b6f..4e3907f48 100644 --- a/doc/license.txt +++ b/doc/license.txt @@ -22,6 +22,8 @@ Copyright (C) 1999-2013,2014,2015 Jack Lloyd 2013 Joel Low 2014 cryptosource GmbH 2014 Andrew Moon + 2015 Daniel Seither (Kullo GmbH) + 2015 Simon Warta (Kullo GmbH) All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/doc/manual/tls.rst b/doc/manual/tls.rst index f96f27620..1926d5c08 100644 --- a/doc/manual/tls.rst +++ b/doc/manual/tls.rst @@ -560,8 +560,9 @@ policy settings from a file. Returns the list of algorithms we are willing to use for public key signatures, in order of preference. - Default: "SHA-512", "SHA-384", "SHA-256", "SHA-224" + Default: "SHA-512", "SHA-384", "SHA-256" + Also allowed: "SHA-224" Also allowed (although **not recommended**): "MD5", "SHA-1" .. note:: diff --git a/doc/news.rst b/doc/news.rst index 58f58c14a..2622c66bd 100644 --- a/doc/news.rst +++ b/doc/news.rst @@ -1,9 +1,45 @@ Release Notes ======================================== -Version 1.11.24, Not Yet Released +Version 1.11.25, Not Yet Released ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +* In this release the test suite has been largely rewritten. Previously the + tests had internally used several different test helper frameworks created or + adopted over time, each of which was insufficient on its own for testing the + entire library. These have been fully converged on a new framework which + suffices for all of the tests. There should be no user-visible change as a + result of this. + +* The OpenSSL implementation of RC4 would return the wrong value from `name` if + leading bytes of the keystream had been skipped in the output. + +* Fixed the signature of botan_pubkey_destroy which took the wrong type and was + not usable. + +* The TLS client would erronously reject any server key exchange + packet smaller than 6 bytes. This prevented negotiating a plain PSK + TLS ciphersuite with an empty identity hint. ECDHE_PSK and DHE_PSK + suites were not affected. + +* Fixed a bug that would cause the TLS client to occasionally reject a + valid server key exchange message as having an invalid signature. + This only affected DHE ciphersuites. + +* Support for negotiating use of SHA-224 in TLS has been disabled in the + default policy. + +* Added `remove_all` function to the `TLS::Session_Manager` interface + +Version 1.11.24, 2015-11-04 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* When the bugs affecting X.509 path validation were fixed in 1.11.23, a check + in Credentials_Manager::verify_certificate_chain was accidentally removed + which caused path validation failures not to be signaled to the TLS layer. + Thus in 1.11.23 certificate authentication in TLS is bypassed. + Reported by Florent Le Coz in GH #324 + * Fixed an endian dependency in McEliece key generation which caused keys to be generated differently on big and little endian systems, even when using a deterministic PRNG with the same seed. @@ -26,7 +62,7 @@ Version 1.11.23, 2015-10-26 * CVE-2015-7826: X.509 path validation violated RFC 6125 and would accept certificates which should not validate under those rules. In particular botan would accept wildcard certificates as matching in situations where it should - not (for example it would erronously accept '*.example.com' as a valid + not (for example it would erroneously accept '*.example.com' as a valid wildcard for 'foo.bar.example.com') * CVE-2015-7827: The routines for decoding PKCS #1 encryption and OAEP blocks @@ -60,7 +96,7 @@ Version 1.11.23, 2015-10-26 deriving the next value by squaring the previous ones. The reinitializion interval can be controlled by the build.h parameter BOTAN_BLINDING_REINIT_INTERVAL. -* A bug decoding DTLS client hellos prevented session resumption for suceeding. +* A bug decoding DTLS client hellos prevented session resumption for succeeding. * DL_Group now prohibits creating a group smaller than 1024 bits. diff --git a/doc/security.rst b/doc/security.rst index 192571829..84d8d49d8 100644 --- a/doc/security.rst +++ b/doc/security.rst @@ -19,6 +19,17 @@ Advisories 2015 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +* 2015-11-04: TLS certificate authentication bypass + + When the bugs affecting X.509 path validation were fixed in 1.11.22, a check + in Credentials_Manager::verify_certificate_chain was accidentally removed + which caused path validation failures not to be signaled to the TLS layer. So + for affected versions, certificate authentication in TLS is bypassed. As a + workaround, applications can override the call and implement the correct + check. Reported by Florent Le Coz in GH #324 + + Introduced in 1.11.22, fixed in 1.11.24 + * 2015-10-26 (CVE-2015-7824): Padding oracle attack on TLS A padding oracle attack was possible against TLS CBC ciphersuites because if a diff --git a/readme.rst b/readme.rst index 928efab35..1a0ec1e4a 100644 --- a/readme.rst +++ b/readme.rst @@ -36,7 +36,10 @@ inclusion into external build systems. If you need help or have questions, send a mail to the `mailing list <http://lists.randombit.net/mailman/listinfo/botan-devel/>`_ or open a ticket on -`GitHub Issues <https://github.com/randombit/botan/issues>`_. +`GitHub Issues <https://github.com/randombit/botan/issues>`_. If you +think you've found a security bug, read the +`security page <http://botan.randombit.net/security.html>`_ +for contact information and procedures. The `GitHub wiki <https://github.com/randombit/botan/wiki>`_ and `Doxygen docs <https://botan.randombit.net/doxygen>`_ @@ -87,7 +90,7 @@ Botan may already be included in your favorite distribution, such as `EPEL <http://dl.fedoraproject.org/pub/epel/7/SRPMS/repoview/botan.html>`_ (for RHEL/CentOS), `Debian <http://packages.debian.org/search?keywords=libbotan>`_, `Ubuntu <http://packages.ubuntu.com/search?keywords=botan>`_, -`Gentoo <http://packages.gentoo.org/package/botan>`_, +`Gentoo <https://packages.gentoo.org/packages/dev-libs/botan>`_, `Arch <http://www.archlinux.org/packages/community/x86_64/botan/>`_, `Slackbuild <http://slackbuilds.org/result/?search=Botan>`_, `FreeBSD ports <http://www.freshports.org/security/botan110>`_, or @@ -103,9 +106,9 @@ later, Clang 3.4 and later, and MSVC 2013 are regularly tested. A new development release is made on the first Monday of every month. The latest development release is -`1.11.23 <http://botan.randombit.net/releases/Botan-1.11.23.tgz>`_ -`(sig) <http://botan.randombit.net/releases/Botan-1.11.23.tgz.asc>`_ -released on 2015-10-26 +`1.11.24 <http://botan.randombit.net/releases/Botan-1.11.24.tgz>`_ +`(sig) <http://botan.randombit.net/releases/Botan-1.11.24.tgz.asc>`_ +released on 2015-11-04 Old Stable Series (1.10) ---------------------------------------- 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() << "<"; - break; - case '&': - stream() << "&"; - break; - case '\"': - stream() << """; - 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 ¤t : 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 ¤t : 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 +} |