diff options
Diffstat (limited to 'src/tests')
78 files changed, 8688 insertions, 21664 deletions
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..07158fee1 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,265 @@ #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"); + + const size_t ITERATIONS = 1000; + + for(size_t range_min : { 0, 10, 100 }) + { + for(size_t range_max : { 0, 10, 100 }) + { + 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_failure("random_integer distribution" + std::to_string(dev)); + } + } + } + } + + 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..74b91d0ed 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> @@ -34,15 +21,18 @@ #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 +40,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 +69,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 +118,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.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); + 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); 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::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 +158,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,9 +221,9 @@ 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); req_file.write((char*)der.data(), der.size()); @@ -214,34 +235,30 @@ void test_enc_gen_req(RandomNumberGenerator& rng) 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"); 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,25 +266,24 @@ 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); 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::vector<byte> ado_der(ado.BER_encode()); @@ -275,15 +291,17 @@ void test_cvc_ado_creation(RandomNumberGenerator& rng) 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"); + 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,38 +309,38 @@ 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"); + result.confirm("ADOs should not be equal", ado != ado2); // std::ofstream ado_file(CVC_TEST_DATA_DIR "/ado"); // std::vector<byte> ado_der(ado.BER_encode()); // ado_file.write((char*)ado_der.data(), ado_der.size()); @@ -334,185 +352,182 @@ void test_cvc_ado_comparison(RandomNumberGenerator& rng) // //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(CVC_TEST_DATA_DIR "/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() { + Test::Result result("CVC"); + EAC1_1_CVC cert_in(CVC_TEST_DATA_DIR "/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); + + result.confirm("same cert", cert_in == cert_cp); + result.confirm("same cert", 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" 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_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; + Test::Result result("CVC"); + try { EAC1_1_CVC(CVC_TEST_DATA_DIR "/cvca_illegal_chars.cv.crt"); - + result.test_failure("Accepted invalid EAC 1.1 CVC"); } - catch (Decoding_Error) - { - exc = true; - } - CHECK(exc); + catch (Decoding_Error) {} - bool exc2 = false; try { EAC1_1_CVC(CVC_TEST_DATA_DIR "/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); + EAC1_1_CVC cvca_cert = DE_EAC::create_cvca(cvca_privk, hash, car, true, true, 12, Test::rng()); std::ofstream cvca_file(CVC_TEST_DATA_DIR "/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); link12_file.write((char*)link12_sv.data(), link12_sv.size()); link12_file.close(); // verify the link - CHECK(link12.check_signature(cvca_privk)); + result.confirm("signature valid", 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"); 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); + 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(CVC_TEST_DATA_DIR "/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"); + 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, CVC_TEST_DATA_DIR "/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); + 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(CVC_TEST_DATA_DIR "/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); + ASN1_Car(dvca_cert1.get_chr().iso_8859()), Test::rng()); helper_write_file(dvca_ado2, CVC_TEST_DATA_DIR "/cvc_chain_dvca_ado2.cer"); // verify the ado and sign the request too @@ -521,66 +536,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 + 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()); + result.confirm("files match", 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, 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); + 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, CVC_TEST_DATA_DIR "/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"); + 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, CVC_TEST_DATA_DIR "/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..7ce972a33 100644 --- a/src/tests/test_fuzzer.cpp +++ b/src/tests/test_fuzzer.cpp @@ -6,74 +6,84 @@ #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; + } - try - { - for(auto vec_file: get_files_recursive(TEST_DATA_DIR_FUZZ_X509)) + private: + +#if defined(BOTAN_HAS_X509_CERTIFICATES) + Test::Result test_x509_fuzz() { - ++tests; + const std::string TEST_DATA_DIR_FUZZ_X509 = TEST_DATA_DIR "/fuzz/x509"; + + 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..4bbeabbfc --- /dev/null +++ b/src/tests/test_main.cpp @@ -0,0 +1,242 @@ +/* +* (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/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 << "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..2a49be840 100644 --- a/src/tests/test_pubkey.cpp +++ b/src/tests/test_pubkey.cpp @@ -1,405 +1,254 @@ /* -* (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> +namespace Botan_Tests { -using namespace Botan; - -namespace { - -void dump_data(const std::vector<byte>& out, - const std::vector<byte>& expected) +void check_invalid_signatures(Test::Result& result, + Botan::PK_Verifier& verifier, + const std::vector<uint8_t>& message, + const std::vector<uint8_t>& signature) { - std::cout << "Got: " << hex_encode(out) << std::endl; - std::cout << "Exp: " << hex_encode(expected) << std::endl; - } + 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 validate_save_and_load(const Private_Key* priv_key, - RandomNumberGenerator& rng) - { - std::string name = priv_key->algo_name(); + std::vector<uint8_t> bad_sig = signature; - size_t fails = 0; - std::string pub_pem = X509::PEM_encode(*priv_key); - - 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)); -} + std::unique_ptr<Botan::RandomNumberGenerator> rng; + if(vars.count("Nonce")) + { + rng.reset(new Fixed_Output_RNG(get_req_bin(vars, "Nonce"))); + } -#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) - { - std::cout << "FAILED (encrypt): " << algo << std::endl; - dump_data(ctext, expected); - ++fails; - } + Botan::PK_Signer signer(*privkey, padding); + Botan::PK_Verifier verifier(*pubkey, padding); - std::vector<byte> decrypted = unlock(d.decrypt(ctext)); + const std::vector<uint8_t> generated_signature = signer.sign_message(message, rng ? *rng : Test::rng()); + result.test_eq("generated signature matches KAT", generated_signature, signature); - if(decrypted != message) - { - std::cout << "FAILED (decrypt): " << algo << std::endl; - dump_data(decrypted, message); - ++fails; - } + result.test_eq("generated signature valid", verifier.verify_message(message, generated_signature), true); + check_invalid_signatures(result, verifier, message, signature); + result.test_eq("correct signature valid", verifier.verify_message(message, signature), true); - if(algo.find("/Raw") == std::string::npos) - { - auto& rng = test_rng(); + return result; + } - for(size_t i = 0; i != ctext.size(); ++i) - { - std::vector<byte> bad_ctext = ctext; +Test::Result +PK_Signature_Verification_Test::run_one_test(const std::string&, const VarMap& vars) + { + 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); - bad_ctext[i] ^= nonzero_byte(rng); + Test::Result result(algo_name() + "/" + padding + " signature verification"); - BOTAN_ASSERT(bad_ctext != ctext, "Made them different"); + Botan::PK_Verifier verifier(*pubkey, padding); - 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; - } - catch(...) {} - } - } + result.test_eq("correct signature valid", verifier.verify_message(message, signature), true); - return fails; - } + check_invalid_signatures(result, verifier, message, signature); -size_t validate_signature(PK_Verifier& v, PK_Signer& s, const std::string& algo, - const std::string& input, - RandomNumberGenerator& rng, - const std::string& exp) - { - return validate_signature(v, s, algo, input, rng, rng, exp); + 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::unique_ptr<Botan::RandomNumberGenerator> kat_rng; + if(vars.count("Nonce")) { - std::cout << "FAILED (sign): " << algo << std::endl; - dump_data(sig, expected); - ++fails; + kat_rng.reset(new Fixed_Output_RNG(get_req_bin(vars, "Nonce"))); } - PK_TEST(v.verify_message(message, sig), "Correct signature is valid"); + Test::Result result(algo_name() + "/" + padding + " decryption"); - for(size_t i = 0; i != 5; ++i) - { - auto bad_sig = sig; + std::unique_ptr<Botan::Private_Key> privkey = load_private_key(vars); - const size_t idx = (test_rng.next_byte() * 256 + test_rng.next_byte()) % sig.size(); - bad_sig[idx] ^= nonzero_byte(test_rng); + // 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))); - PK_TEST(!v.verify_message(message, bad_sig), "Incorrect signature is invalid"); - } + Botan::PK_Encryptor_EME encryptor(*privkey, padding); + result.test_eq("encryption", encryptor.encrypt(plaintext, kat_rng ? *kat_rng : Test::rng()), ciphertext); - zero_mem(sig.data(), sig.size()); + Botan::PK_Decryptor_EME decryptor(*privkey, padding); + result.test_eq("decryption", decryptor.decrypt(ciphertext), plaintext); - PK_TEST(!v.verify_message(message, sig), "All-zero signature is invalid"); + check_invalid_ciphertexts(result, decryptor, plaintext, ciphertext); - 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& random, - const std::string& exp) +Test::Result PK_Key_Agreement_Test::run_one_test(const std::string&, const VarMap& vars) { - Fixed_Output_RNG fixed_rng(hex_decode(random)); + const std::vector<uint8_t> shared = get_req_bin(vars, "K"); + const std::string kdf = get_opt_str(vars, "KDF", default_kdf(vars)); - return validate_signature(v, s, algo, input, fixed_rng, rng, exp); - } + Test::Result result(algo_name() + "/" + kdf + " key agreement"); -size_t validate_kas(PK_Key_Agreement& kas, const std::string& algo, - const std::vector<byte>& pubkey, const std::string& output, - size_t keylen) - { - std::vector<byte> expected = hex_decode(output); + std::unique_ptr<Botan::Private_Key> privkey = load_our_key(vars); + const std::vector<uint8_t> pubkey = load_their_key(vars); - std::vector<byte> got = unlock(kas.derive_key(keylen, pubkey).bits_of()); + const size_t key_len = get_opt_sz(vars, "OutLen", 0); - size_t fails = 0; + Botan::PK_Key_Agreement kas(*privkey, kdf); - if(got != expected) - { - std::cout << "FAILED: " << algo << std::endl; - dump_data(got, expected); - ++fails; - } + result.test_eq("agreement", kas.derive_key(key_len, pubkey).bits_of(), shared); - return fails; + 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; - size_t tests = 0; - size_t fails = 0; + for(auto&& param : keygen_params()) + { + std::unique_ptr<Botan::Private_Key> key = make_key(Test::rng(), 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); \ - } + const std::string report_name = key->algo_name() + (param.empty() ? param : " " + param); -#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); \ + results.push_back(test_key(report_name, *key)); + } + return results; } -#if defined(BOTAN_HAS_RSA) +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); + + 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..12fdb25c3 100644 --- a/src/tests/test_srp6.cpp +++ b/src/tests/test_srp6.cpp @@ -1,48 +1,49 @@ #include "tests.h" #if defined(BOTAN_HAS_SRP6) + #include <botan/srp6.h> +#endif -#include <botan/srp6.h> -#include <iostream> +namespace Botan_Tests { -size_t test_srp6() - { - using namespace Botan; - - size_t fails = 0; - - 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..704ff36a8 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -5,324 +5,726 @@ */ #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 +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 + "'"); + } + } -using namespace Botan; +void Test::Result::merge(const Result& other) + { + if(who() != other.who()) + throw std::runtime_error("Merging tests from different sources"); -Botan::RandomNumberGenerator& test_rng() + 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()); + } + +void Test::Result::test_note(const std::string& note) { -#if defined(BOTAN_HAS_SYSTEM_RNG) - return Botan::system_rng(); -#else - static Botan::AutoSeeded_RNG rng; - return rng; -#endif + if(note != "") + { + m_log.push_back(who() + " " + note); + } } -size_t run_tests_in_dir(const std::string& dir, std::function<size_t (const std::string&)> fn) +void Test::Result::note_missing(const std::string& whatever) { - size_t fails = 0; + static std::set<std::string> s_already_seen; - try + if(s_already_seen.count(whatever) == 0) { - auto files = get_files_recursive(dir); + test_note("Skipping tests due to missing " + whatever); + s_already_seen.insert(whatever); + } + } - if (files.empty()) - std::cout << "Warning: No test files found in '" << dir << "'" << std::endl; +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) + { + return test_success(what + " threw exception " + e.what()); + } + catch(...) + { + return test_success(what + " threw unknown exception"); + } + } - for(const auto file: files) - fails += fn(file); +bool Test::Result::test_success(const std::string& note) + { + if(Test::log_success()) + { + test_note(note); } - catch(No_Filesystem_Access) + ++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; + } + +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(); + } + +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) + { + if(produced_size == expected_size && Botan::same_mem(produced, expected, expected_size)) + return test_success(); + + std::ostringstream err; + + err << who(); + + if(producer) { - std::cout << "Warning: No filesystem access available to read test files in '" << dir << "'" << std::endl; + err << " producer '" << producer << "'"; } - return fails; + err << " unexpected result"; + + 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 << "Produced: " << Botan::hex_encode(produced, produced_size) << "\n" + << "Expected: " << 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()); + } + +bool Test::Result::test_eq(const char* what, const std::string& produced, const std::string& expected) + { + return test_is_eq(what, produced, expected); + } + +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)); } -size_t run_tests(const std::vector<std::pair<std::string, test_fn>>& tests) +bool Test::Result::test_eq(const char* what, size_t produced, size_t expected) { - size_t fails = 0; + return test_is_eq(what, produced, expected); + } - for(const auto& row : tests) +bool Test::Result::test_lt(const char* what, size_t produced, size_t expected) + { + if(produced >= expected) { - 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; - } + std::ostringstream err; + err << m_who; + if(what) + err << " " << what; + err << " unexpected result " << produced << " >= " << expected; + return test_failure(err.str()); } - // Summary for test suite - std::cout << "===============" << std::endl; - test_report("Tests", 0, fails); + return test_success(); + } + +bool Test::Result::test_gte(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 fails; + return test_success(); } -void test_report(const std::string& name, size_t ran, size_t failed) +#if defined(BOTAN_HAS_BIGINT) +bool Test::Result::test_eq(const char* what, const BigInt& produced, const BigInt& expected) { - std::cout << name; + return test_is_eq(what, produced, expected); + } - if(ran > 0) - std::cout << " " << ran << " tests"; +bool Test::Result::test_ne(const char* what, const BigInt& produced, const BigInt& expected) + { + if(produced != expected) + return test_success(); - if(failed) - std::cout << " " << failed << " FAILs" << std::endl; - else - std::cout << " all ok" << std::endl; + std::ostringstream err; + err << who() << " " << what << " produced " << produced << " prohibited value"; + return test_failure(err.str()); } +#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::Result::test_eq(const char* what, const Botan::PointGFp& a, const Botan::PointGFp& b) { - if(!src.good()) + //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 + +bool Test::Result::test_eq(const char* what, bool produced, bool expected) + { + return test_is_eq(what, produced, expected); + } + +bool Test::Result::test_rc_ok(const char* what, int rc) + { + if(rc != 0) { - 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 << " unexpectedly failed with error code " << rc; + 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(); + } - std::string fixed_name; +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()); + } - while(src.good()) + 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 { - std::string line; - std::getline(src, line); + o << std::setprecision(2) << std::fixed << ns/1000000.0 << " msec"; + } - if(line == "") - continue; + return o.str(); + } - if(line[0] == '#') - continue; +} - if(line[0] == '[' && line[line.size()-1] == ']') +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()); + } - if(key == name_key) - fixed_name.clear(); +//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 == output_key) +//static +std::vector<Test::Result> Test::run_test(const std::string& test_name, bool fail_if_missing) + { + std::vector<Test::Result> results; + + 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 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_dir, + const std::vector<std::string>& required_keys, + const std::vector<std::string>& optional_keys) : + m_data_dir(data_dir) + { + 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_dir, + const std::vector<std::string>& required_keys, + const std::vector<std::string>& optional_keys) : + m_algo(algo), + m_data_dir(data_dir) + { + 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 Text_Based_Test::get_opt_sz(const VarMap& vars, const std::string& key, const size_t def_value) const + { + auto i = vars.find(key); + if(i == vars.end()) + return def_value; + 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) +std::vector<uint8_t> Text_Based_Test::get_opt_bin(const VarMap& vars, + const std::string& key) const { - std::ifstream vec(filename); + auto i = vars.find(key); + if(i == vars.end()) + return std::vector<uint8_t>(); - if(!vec) + try + { + return Botan::hex_decode(i->second); + } + catch(std::exception& e) { - std::cout << "Failure opening " << filename << std::endl; - return 1; + 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) + { + std::vector<std::string> fs = Botan::get_files_recursive(m_data_dir); + + if(fs.empty() && m_data_dir.find(".vec") != std::string::npos) + { + m_srcs.push_back(m_data_dir); + } + else + { + m_srcs.assign(fs.begin(), fs.end()); + } + + 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..c431eb6bd 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,105 +11,340 @@ #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 { -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); +using Botan::byte; -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) +using Botan::BigInt; +#endif -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); +/* +* 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: -size_t run_tests_in_dir(const std::string& dir, std::function<size_t (const std::string&)> fn); + /* + * 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; + } + + void merge(const Result& other); + + void test_note(const std::string& note); + + 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 -// Run a list of tests -typedef std::function<size_t ()> test_fn; +#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(const std::vector<std::pair<std::string, test_fn>>& tests); -void test_report(const std::string& name, size_t ran, size_t failed); + 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; } + + private: + std::string m_who; + 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); + }; -class Test_State - { - public: - void started(const std::string& /*msg*/) { m_tests_run++; } + virtual std::vector<Test::Result> run() = 0; + virtual ~Test() {} + + static std::vector<Test::Result> run_test(const std::string& what, bool fail_if_missing); + + static std::map<std::string, std::unique_ptr<Test>>& global_registry(); - void test_ran(const char* msg); + static std::set<std::string> registered_tests(); - void failure(const char* test, const std::string& what_failed) + static Test* get_test(const std::string& test_name); + + static std::string data_dir(const std::string& what); + static std::string data_file(const std::string& what); + + 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: + static Botan::RandomNumberGenerator* m_test_rng; + static size_t m_soak_level; + static bool m_log_success; + }; + +/* +* Register the test with the runner +*/ +#define BOTAN_REGISTER_TEST(type, Test_Class) namespace { Test::Registration reg_ ## Test_Class ## _tests(type, new Test_Class); } + +/* +* 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: - size_t m_tests_run = 0, m_tests_failed = 0; + std::string m_algo; + std::string m_data_dir; + 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; }; -#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" @@ -116,92 +352,4 @@ class Test_State #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; \ - } \ - -/* - * 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; \ - } \ - #endif diff --git a/src/tests/unit_ecc.cpp b/src/tests/unit_ecc.cpp index bd813b37e..90d966a39 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_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..f47d0ae71 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_DIR_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_DIR_ECC "/root2_SHA256.cer"); + Botan::X509_Certificate link_cert(TEST_DATA_DIR_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_DIR_ECC "/root_SHA1.163.crt"); + Botan::X509_Certificate link_cert(TEST_DATA_DIR_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); + 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); + 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); + 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_OUTDATA_DIR "/dompar_private.pkcs8.pem"); - priv_key << PKCS8::PEM_encode(key); + 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_OUTDATA_DIR "/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_OUTDATA_DIR "/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_OUTDATA_DIR "/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_DIR_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_DIR_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_DIR_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..6c15ec4e9 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,70 @@ 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"); + throw std::runtime_error("No PSK set for " + 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 +154,45 @@ 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("TLS handshake"); 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 { + 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; + { + 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; + 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 +202,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 +233,8 @@ size_t test_tls_handshake(RandomNumberGenerator& rng, if(rounds > 25) { - std::cout << "Still here, something went wrong\n"; - return 1; + result.test_failure("Still here after many rounds, deadlock?"); + break; } if(handshake_done && (client.is_closed() || server.is_closed())) @@ -268,8 +252,7 @@ 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)); @@ -286,58 +269,43 @@ size_t test_tls_handshake(RandomNumberGenerator& rng, * 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); + server.received_data(input.data(), input.size()); } catch(std::exception& e) { - std::cout << "Server error - " << e.what() << std::endl; + result.test_failure("server error", e.what()); continue; } try { - //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); client.received_data(input.data(), input.size()); } catch(std::exception& e) { - std::cout << "Client error - " << e.what() << std::endl; + result.test_failure("client error", e.what()); 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) - { - 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()) @@ -345,16 +313,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 +327,45 @@ size_t test_tls_handshake(RandomNumberGenerator& rng, } catch(std::exception& e) { - std::cout << e.what() << "\n"; - return 1; + result.test_failure("TLS client", e.what()); } } - return 0; + 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("DTLS handshake"); 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; + 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 +375,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 +408,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,18 +422,15 @@ 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); } @@ -489,40 +444,33 @@ size_t test_dtls_handshake(RandomNumberGenerator& rng, * 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) - { - //std::cout << "Corrupting client data\n"; - mutate(input, rng); - } + input = Test::mutate_vec(input); server.received_data(input.data(), input.size()); } catch(std::exception& e) { - std::cout << "Server error - " << e.what() << std::endl; + result.test_failure("server error", e.what()); continue; } try { - //std::cout << "client got " << s2c_traffic.size() << " bytes\n"; std::vector<byte> input; std::swap(s2c_traffic, input); if(corrupt_server_data) - { - //std::cout << "Corrupting server data\n"; - mutate(input, rng); - } + input = Test::mutate_vec(input); + client.received_data(input.data(), input.size()); } catch(std::exception& e) { - std::cout << "Client error - " << e.what() << std::endl; + result.test_failure("client error", e.what()); continue; } @@ -534,20 +482,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 +495,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 +509,72 @@ size_t test_dtls_handshake(RandomNumberGenerator& rng, } catch(std::exception& e) { - std::cout << e.what() << "\n"; - return 1; + result.test_failure("DTLS handshake", e.what()); } } - return 0; + 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)); + + 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)); + return results; + } + }; + +BOTAN_REGISTER_TEST("unit_tls", TLS_Unit_Tests); -#else -size_t test_tls() { return 0; } #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 +} |