2021-06-18 22:28:49 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2021 ,  Peter  Bocan   < me @ pbocan . net > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibCrypto/BigInt/Algorithms/UnsignedBigIntegerAlgorithms.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibCrypto/BigInt/SignedBigInteger.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibCrypto/BigInt/UnsignedBigInteger.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibCrypto/NumberTheory/ModularFunctions.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibTest/TestCase.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <cstring> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  Crypto : : UnsignedBigInteger  bigint_fibonacci ( size_t  n )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1 ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2 ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  n ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Crypto : : UnsignedBigInteger  t  =  num1 . plus ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        num2  =  num1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        num1  =  t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  num1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  Crypto : : SignedBigInteger  bigint_signed_fibonacci ( size_t  n )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num1 ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num2 ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  n ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Crypto : : SignedBigInteger  t  =  num1 . plus ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        num2  =  num1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        num1  =  t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  num1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_fib500 )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < u32 >  result  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        315178285 ,  505575602 ,  1883328078 ,  125027121 ,  3649625763 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        347570207 ,  74535262 ,  3832543808 ,  2472133297 ,  1600064941 ,  65273441 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( bigint_fibonacci ( 500 ) . words ( ) ,  result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_addition_initialization )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2 ( 70 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num3  =  num1 . plus ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  pass  =  ( num3  = =  num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pass  & =  ( num1  = =  Crypto : : UnsignedBigInteger ( 0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT ( pass ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_addition_borrow_with_zero )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1 ( {  UINT32_MAX  -  3 ,  UINT32_MAX  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2 ( {  UINT32_MAX  -  2 ,  0  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < u32 >  expected_result  {  4294967289 ,  0 ,  1  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . plus ( num2 ) . words ( ) ,  expected_result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_basic_add_to_accumulator )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1 ( 10 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2 ( 70 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigIntegerAlgorithms : : add_into_accumulator_without_allocation ( num1 ,  num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . words ( ) ,  Vector < u32 >  {  80  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_basic_add_to_empty_accumulator )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1 ( { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2 ( 10 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigIntegerAlgorithms : : add_into_accumulator_without_allocation ( num1 ,  num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . words ( ) ,  Vector < u32 >  {  10  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_basic_add_to_smaller_accumulator )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1 ( 10 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2 ( {  10 ,  10  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigIntegerAlgorithms : : add_into_accumulator_without_allocation ( num1 ,  num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < u32 >  expected_result  {  20 ,  10  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . words ( ) ,  expected_result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_add_to_accumulator_with_multiple_carry_levels )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1 ( {  UINT32_MAX  -  2 ,  UINT32_MAX  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2 ( 5 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigIntegerAlgorithms : : add_into_accumulator_without_allocation ( num1 ,  num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < u32 >  expected_result  {  2 ,  0 ,  1  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . words ( ) ,  expected_result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_add_to_accumulator_with_leading_zero )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1 ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2 ( {  1 ,  0  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigIntegerAlgorithms : : add_into_accumulator_without_allocation ( num1 ,  num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . words ( ) ,  Vector < u32 >  {  2  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_add_to_accumulator_with_carry_and_leading_zero )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1 ( {  UINT32_MAX ,  0 ,  0 ,  0  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2 ( {  1 ,  0  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigIntegerAlgorithms : : add_into_accumulator_without_allocation ( num1 ,  num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < u32 >  expected_result  {  0 ,  1 ,  0 ,  0  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . words ( ) ,  expected_result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_simple_subtraction )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1 ( 80 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2 ( 70 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . minus ( num2 ) ,  Crypto : : UnsignedBigInteger ( 10 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_simple_subtraction_invalid )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1 ( 50 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2 ( 70 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT ( num1 . minus ( num2 ) . is_invalid ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_simple_subtraction_with_borrow )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1 ( UINT32_MAX ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2 ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num3  =  num1 . plus ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  result  =  num3 . minus ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result ,  num1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_subtraction_with_large_numbers )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1  =  bigint_fibonacci ( 343 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2  =  bigint_fibonacci ( 218 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  result  =  num1 . minus ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < u32 >  expected_result  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        811430588 ,  2958904896 ,  1130908877 ,  2830569969 ,  3243275482 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        3047460725 ,  774025231 ,  7990 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . plus ( num2 ) ,  num1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . words ( ) ,  expected_result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_subtraction_with_large_numbers2 )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1 ( Vector < u32 >  {  1483061863 ,  446680044 ,  1123294122 ,  191895498 ,  3347106536 ,  16 ,  0 ,  0 ,  0  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2 ( Vector < u32 >  {  4196414175 ,  1117247942 ,  1123294122 ,  191895498 ,  3347106536 ,  16  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  result  =  num1 . minus ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // this test only verifies that we don't crash on an assertion
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_subtraction_regression_1 )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num  =  Crypto : : UnsignedBigInteger  {  1  } . shift_left ( 256 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < u32 >  expected_result  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        4294967295 ,  4294967295 ,  4294967295 ,  4294967295 ,  4294967295 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        4294967295 ,  4294967295 ,  4294967295 ,  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num . minus ( 1 ) . words ( ) ,  expected_result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_simple_multiplication )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1 ( 8 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2 ( 251 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  result  =  num1 . multiplied_by ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . words ( ) ,  Vector < u32 >  {  2008  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_multiplication_with_big_numbers1 )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1  =  bigint_fibonacci ( 200 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2 ( 12345678 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  result  =  num1 . multiplied_by ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < u32 >  expected_result  {  669961318 ,  143970113 ,  4028714974 ,  3164551305 ,  1589380278 ,  2  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . words ( ) ,  expected_result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_multiplication_with_big_numbers2 )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1  =  bigint_fibonacci ( 200 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2  =  bigint_fibonacci ( 341 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  result  =  num1 . multiplied_by ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < u32 >  expected_result  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        3017415433 ,  2741793511 ,  1957755698 ,  3731653885 ,  3154681877 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        785762127 ,  3200178098 ,  4260616581 ,  529754471 ,  3632684436 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        1073347813 ,  2516430 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . words ( ) ,  expected_result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_simple_division )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1 ( 27194 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2 ( 251 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  result  =  num1 . divided_by ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedDivisionResult  expected  =  {  Crypto : : UnsignedBigInteger ( 108 ) ,  Crypto : : UnsignedBigInteger ( 86 )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . quotient ,  expected . quotient ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . remainder ,  expected . remainder ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_division_with_big_numbers )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num1  =  bigint_fibonacci ( 386 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  num2  =  bigint_fibonacci ( 238 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  result  =  num1 . divided_by ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedDivisionResult  expected  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Crypto : : UnsignedBigInteger ( Vector < u32 >  {  2300984486 ,  2637503534 ,  2022805584 ,  107  } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Crypto : : UnsignedBigInteger ( Vector < u32 >  {  1483061863 ,  446680044 ,  1123294122 ,  191895498 ,  3347106536 ,  16 ,  0 ,  0 ,  0  } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . quotient ,  expected . quotient ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . remainder ,  expected . remainder ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_division_combined_test )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num1  =  bigint_fibonacci ( 497 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num2  =  bigint_fibonacci ( 238 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  div_result  =  num1 . divided_by ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( div_result . quotient . multiplied_by ( num2 ) . plus ( div_result . remainder ) ,  num1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_base10_from_string )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-29 17:51:52 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  result  =  Crypto : : UnsignedBigInteger : : from_base ( 10 ,  " 57195071295721390579057195715793 " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 22:28:49 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    Vector < u32 >  expected_result  {  3806301393 ,  954919431 ,  3879607298 ,  721  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . words ( ) ,  expected_result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_unsigned_bigint_base10_to_string )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  result  =  Crypto : : UnsignedBigInteger  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Vector < u32 >  {  3806301393 ,  954919431 ,  3879607298 ,  721  } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-29 17:51:52 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } . to_base ( 10 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 22:28:49 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result ,  " 57195071295721390579057195715793 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_modular_inverse )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  result  =  Crypto : : NumberTheory : : ModularInverse ( 7 ,  87 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result ,  25 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_even_simple_modular_power )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  base  {  7  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  exponent  {  2  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  modulo  {  10  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  result  =  Crypto : : NumberTheory : : ModularPower ( base ,  exponent ,  modulo ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . words ( ) ,  Vector < u32 >  {  9  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_odd_simple_modular_power )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  base  {  10  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  exponent  {  2  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  modulo  {  9  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  result  =  Crypto : : NumberTheory : : ModularPower ( base ,  exponent ,  modulo ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . words ( ) ,  Vector < u32 >  {  1  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_large_even_fibonacci_modular_power )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  base  =  bigint_fibonacci ( 200 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  exponent  =  bigint_fibonacci ( 100 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  modulo  =  bigint_fibonacci ( 150 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Result according to Wolfram Alpha : 7195284628716783672927396027925
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  result  =  Crypto : : NumberTheory : : ModularPower ( base ,  exponent ,  modulo ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < u32 >  expected_result  {  2042093077 ,  1351416233 ,  3510104665 ,  90  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . words ( ) ,  expected_result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_large_odd_fibonacci_modular_power )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  base  =  bigint_fibonacci ( 200 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  exponent  =  bigint_fibonacci ( 100 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  modulo  =  bigint_fibonacci ( 149 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Result according to Wolfram Alpha : 1136278609611966596838389694992
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  result  =  Crypto : : NumberTheory : : ModularPower ( base ,  exponent ,  modulo ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < u32 >  expected_result  {  2106049040 ,  2169509253 ,  1468244710 ,  14  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . words ( ) ,  expected_result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_large_odd_fibonacci_with_carry_modular_power )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  base  =  bigint_fibonacci ( 200 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  exponent  =  bigint_fibonacci ( 100 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : UnsignedBigInteger  modulo  =  bigint_fibonacci ( 185 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Result according to Wolfram Alpha : 55094573983071006678665780782730672080
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  result  =  Crypto : : NumberTheory : : ModularPower ( base ,  exponent ,  modulo ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < u32 >  expected_result  {  1988720592 ,  2097784252 ,  347129583 ,  695391288  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . words ( ) ,  expected_result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_modular_power_extra_tests )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Crypto : : UnsignedBigInteger  base ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Crypto : : UnsignedBigInteger  exp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Crypto : : UnsignedBigInteger  mod ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Crypto : : UnsignedBigInteger  expected ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  mod_pow_tests [ ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 2988348162058574136915891421498819466320163312926952423791023078876139 " _bigint ,  " 2351399303373464486466122544523690094744975233415544072992656881240319 " _bigint ,  " 10000 " _bigint ,  " 3059 " _bigint  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 24231 " _bigint ,  " 12448 " _bigint ,  " 14679 " _bigint ,  " 4428 " _bigint  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 1005404 " _bigint ,  " 8352654 " _bigint ,  " 8161408 " _bigint ,  " 2605696 " _bigint  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 3665005778 " _bigint ,  " 3244425589 " _bigint ,  " 565668506 " _bigint ,  " 524766494 " _bigint  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 10662083169959689657 " _bigint ,  " 11605678468317533000 " _bigint ,  " 1896834583057209739 " _bigint ,  " 1292743154593945858 " _bigint  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 99667739213529524852296932424683448520 " _bigint ,  " 123394910770101395416306279070921784207 " _bigint ,  " 238026722756504133786938677233768788719 " _bigint ,  " 197165477545023317459748215952393063201 " _bigint  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 49368547511968178788919424448914214709244872098814465088945281575062739912239 " _bigint ,  " 25201856190991298572337188495596990852134236115562183449699512394891190792064 " _bigint ,  " 45950460777961491021589776911422805972195170308651734432277141467904883064645 " _bigint ,  " 39917885806532796066922509794537889114718612292469285403012781055544152450051 " _bigint  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 48399385336454791246880286907257136254351739111892925951016159217090949616810 " _bigint ,  " 5758661760571644379364752528081901787573279669668889744323710906207949658569 " _bigint ,  " 32812120644405991429173950312949738783216437173380339653152625840449006970808 " _bigint ,  " 7948464125034399875323770213514649646309423451213282653637296324080400293584 " _bigint  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  test_case  :  mod_pow_tests )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  actual  =  Crypto : : NumberTheory : : ModularPower ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            test_case . base ,  test_case . exp ,  test_case . mod ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        EXPECT_EQ ( actual ,  test_case . expected ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_primality_test )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Crypto : : UnsignedBigInteger  candidate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bool  expected_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  primality_tests [ ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 1180591620717411303424 " _bigint ,  false  } ,                   // 2**70
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 620448401733239439360000 " _bigint ,  false  } ,                 // 25!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 953962166440690129601298432 " _bigint ,  false  } ,              // 12**25
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 620448401733239439360000 " _bigint ,  false  } ,                 // 25!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 147926426347074375 " _bigint ,  false  } ,                       // 35! / 2**32
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 340282366920938429742726440690708343523 " _bigint ,  false  } ,  // 2 factors near 2^64
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 73 " _bigint ,  true  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 6967 " _bigint ,  true  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 787649 " _bigint ,  true  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 73513949 " _bigint ,  true  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 6691236901 " _bigint ,  true  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 741387182759 " _bigint ,  true  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 67466615915827 " _bigint ,  true  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 9554317039214687 " _bigint ,  true  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 533344522150170391 " _bigint ,  true  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 18446744073709551557 " _bigint ,  true  } ,  // just below 2**64
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  test_case  :  primality_tests )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bool  actual_result  =  Crypto : : NumberTheory : : is_probably_prime ( test_case . candidate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        EXPECT_EQ ( test_case . expected_result ,  actual_result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_random_number_generation )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Crypto : : UnsignedBigInteger  min ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Crypto : : UnsignedBigInteger  max ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  random_number_tests [ ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 1 " _bigint ,  " 1000000 " _bigint  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 10000000000 " _bigint ,  " 20000000000 " _bigint  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 1000 " _bigint ,  " 200000000000000000 " _bigint  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  " 200000000000000000 " _bigint ,  " 200000000000010000 " _bigint  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  test_case  :  random_number_tests )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  actual_result  =  Crypto : : NumberTheory : : random_number ( test_case . min ,  test_case . max ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        EXPECT ( ! ( actual_result  <  test_case . min ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        EXPECT ( actual_result  <  test_case . max ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_random_distribution )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  actual_result  =  Crypto : : NumberTheory : : random_number ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        " 1 " _bigint , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        " 100000000000000000000000000000 " _bigint ) ;          // 10**29
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( actual_result  <  " 100000000000000000000 " _bigint )  {  // 10**20
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        FAIL ( " Too small " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-29 17:51:52 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        outln ( " The generated number {} is extremely small. This *can* happen by pure chance, but should happen only once in a billion times. So it's probably an error. " ,  actual_result . to_base ( 10 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 22:28:49 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( " 99999999900000000000000000000 " _bigint  <  actual_result )  {  // 10**29 - 10**20
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        FAIL ( " Too large " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-29 17:51:52 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        outln ( " The generated number {} is extremely large. This *can* happen by pure chance, but should happen only once in a billion times. So it's probably an error. " ,  actual_result . to_base ( 10 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 22:28:49 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_import_big_endian_decode_encode_roundtrip )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    u8  random_bytes [ 128 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    u8  target_buffer [ 128 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fill_with_random ( random_bytes ,  128 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  encoded  =  Crypto : : UnsignedBigInteger : : import_data ( random_bytes ,  128 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    encoded . export_data ( {  target_buffer ,  128  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT ( memcmp ( target_buffer ,  random_bytes ,  128 )  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_import_big_endian_encode_decode_roundtrip )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    u8  target_buffer [ 128 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  encoded  =  " 12345678901234567890 " _bigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  size  =  encoded . export_data ( {  target_buffer ,  128  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  decoded  =  Crypto : : UnsignedBigInteger : : import_data ( target_buffer ,  size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( encoded ,  decoded ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_big_endian_import )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  number  =  Crypto : : UnsignedBigInteger : : import_data ( " hello " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( number ,  " 448378203247 " _bigint ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_big_endian_export )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  number  =  " 448378203247 " _bigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    char  exported [ 8 ]  {  0  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  exported_length  =  number . export_data ( {  exported ,  8  } ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( exported_length ,  5u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT ( memcmp ( exported  +  3 ,  " hello " ,  5 )  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 08:46:42 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_one_based_index_of_highest_set_bit )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num1  =  " 1234567 " _bigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num2  =  " 1234567 " _bigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( " 0 " _bigint . one_based_index_of_highest_set_bit ( ) ,  0u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( " 1 " _bigint . one_based_index_of_highest_set_bit ( ) ,  1u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( " 7 " _bigint . one_based_index_of_highest_set_bit ( ) ,  3u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( " 4294967296 " _bigint . one_based_index_of_highest_set_bit ( ) ,  33u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_signed_bigint_bitwise_not_fill_to_one_based_index )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( " 0 " _bigint . bitwise_not_fill_to_one_based_index ( 0 ) ,  " 0 " _bigint ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( " 0 " _bigint . bitwise_not_fill_to_one_based_index ( 1 ) ,  " 1 " _bigint ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( " 0 " _bigint . bitwise_not_fill_to_one_based_index ( 2 ) ,  " 3 " _bigint ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( " 0 " _bigint . bitwise_not_fill_to_one_based_index ( 4 ) ,  " 15 " _bigint ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( " 0 " _bigint . bitwise_not_fill_to_one_based_index ( 32 ) ,  " 4294967295 " _bigint ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( " 0 " _bigint . bitwise_not_fill_to_one_based_index ( 33 ) ,  " 8589934591 " _bigint ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 22:28:49 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_bitwise_or )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num1  =  " 1234567 " _bigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num2  =  " 1234567 " _bigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . bitwise_or ( num2 ) ,  num1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_bitwise_or_different_lengths )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num1  =  " 1234567 " _bigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num2  =  " 123456789012345678901234567890 " _bigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  expected  =  " 123456789012345678901234622167 " _bigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  result  =  num1 . bitwise_or ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result ,  expected ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-01 01:38:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								TEST_CASE ( test_signed_bigint_bitwise_or )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num1  =  " -1234567 " _sbigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num2  =  " 1234567 " _sbigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . bitwise_or ( num1 ) ,  num1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 08:46:42 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . bitwise_or ( num2 ) ,  " -1 " _sbigint ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num2 . bitwise_or ( num1 ) ,  " -1 " _sbigint ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-01 01:38:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    EXPECT_EQ ( num2 . bitwise_or ( num2 ) ,  num2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 08:46:42 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( " 0 " _sbigint . bitwise_or ( " -1 " _sbigint ) ,  " -1 " _sbigint ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-01 01:38:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 22:28:49 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_bitwise_and )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num1  =  " 1234567 " _bigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num2  =  " 1234561 " _bigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . bitwise_and ( num2 ) ,  " 1234561 " _bigint ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_bitwise_and_different_lengths )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num1  =  " 1234567 " _bigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num2  =  " 123456789012345678901234567890 " _bigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . bitwise_and ( num2 ) ,  " 1180290 " _bigint ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-17 12:22:51 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								TEST_CASE ( test_signed_bigint_bitwise_not )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( " 3 " _sbigint . bitwise_not ( ) ,  " -4 " _sbigint ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( " -1 " _sbigint . bitwise_not ( ) ,  " 0 " _sbigint ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-01 01:38:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								TEST_CASE ( test_signed_bigint_bitwise_and )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num1  =  " -1234567 " _sbigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num2  =  " 1234567 " _sbigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . bitwise_and ( num1 ) ,  num1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-17 19:54:02 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . bitwise_and ( num2 ) ,  " 1 " _sbigint ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num2 . bitwise_and ( num1 ) ,  " 1 " _sbigint ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-01 01:38:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    EXPECT_EQ ( num2 . bitwise_and ( num2 ) ,  num2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-17 19:54:02 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( " -3 " _sbigint . bitwise_and ( " -2 " _sbigint ) ,  " -4 " _sbigint ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-01 01:38:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 22:28:49 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_bitwise_xor )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num1  =  " 1234567 " _bigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num2  =  " 1234561 " _bigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . bitwise_xor ( num2 ) ,  6 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_bigint_bitwise_xor_different_lengths )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num1  =  " 1234567 " _bigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num2  =  " 123456789012345678901234567890 " _bigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . bitwise_xor ( num2 ) ,  " 123456789012345678901233441877 " _bigint ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-01 01:38:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								TEST_CASE ( test_signed_bigint_bitwise_xor )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num1  =  " -3 " _sbigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num2  =  " 1 " _sbigint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . bitwise_xor ( num1 ) ,  " 0 " _sbigint ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . bitwise_xor ( num2 ) ,  " -2 " _sbigint ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num2 . bitwise_xor ( num1 ) ,  " -2 " _sbigint ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num2 . bitwise_xor ( num2 ) ,  " 0 " _sbigint ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 22:28:49 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_signed_bigint_fibo500 )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < u32 >  expected_result  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        315178285 ,  505575602 ,  1883328078 ,  125027121 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        3649625763 ,  347570207 ,  74535262 ,  3832543808 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        2472133297 ,  1600064941 ,  65273441 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  result  =  bigint_signed_fibonacci ( 500 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . unsigned_value ( ) . words ( ) ,  expected_result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_signed_addition_edgecase_borrow_with_zero )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num1  {  Crypto : : UnsignedBigInteger  {  {  UINT32_MAX  -  3 ,  UINT32_MAX  }  } ,  false  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num2  {  Crypto : : UnsignedBigInteger  {  UINT32_MAX  -  2  } ,  false  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < u32 >  expected_result  {  4294967289 ,  0 ,  1  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . plus ( num2 ) . unsigned_value ( ) . words ( ) ,  expected_result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_signed_addition_edgecase_addition_to_other_sign )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num1  =  INT32_MAX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num2  =  num1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    num2 . negate ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . plus ( num2 ) ,  Crypto : : SignedBigInteger  {  0  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_signed_subtraction_simple_subtraction_positive_result )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num1 ( 80 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num2 ( 70 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . minus ( num2 ) ,  Crypto : : SignedBigInteger ( 10 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_signed_subtraction_simple_subtraction_negative_result )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num1 ( 50 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num2 ( 70 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . minus ( num2 ) ,  Crypto : : SignedBigInteger  {  - 20  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-16 09:17:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								TEST_CASE ( test_signed_subtraction_both_negative )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num1 ( - 50 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num2 ( - 70 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num1 . minus ( num2 ) ,  Crypto : : SignedBigInteger  {  20  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( num2 . minus ( num1 ) ,  Crypto : : SignedBigInteger  {  - 20  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 22:28:49 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_signed_subtraction_simple_subtraction_with_borrow )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num1 ( Crypto : : UnsignedBigInteger  {  UINT32_MAX  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num2 ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num3  =  num1 . plus ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  result  =  num2 . minus ( num3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    num1 . negate ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result ,  num1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_signed_subtraction_with_large_numbers )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num1  =  bigint_signed_fibonacci ( 343 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num2  =  bigint_signed_fibonacci ( 218 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  result  =  num2 . minus ( num1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  expected  =  Crypto : : UnsignedBigInteger  {  Vector < u32 >  {  811430588 ,  2958904896 ,  1130908877 ,  2830569969 ,  3243275482 ,  3047460725 ,  774025231 ,  7990  }  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . plus ( num1 ) ,  num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . unsigned_value ( ) ,  expected ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_signed_subtraction_with_large_numbers_check_for_assertion )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num1 ( Crypto : : UnsignedBigInteger  {  Vector < u32 >  {  1483061863 ,  446680044 ,  1123294122 ,  191895498 ,  3347106536 ,  16 ,  0 ,  0 ,  0  }  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num2 ( Crypto : : UnsignedBigInteger  {  Vector < u32 >  {  4196414175 ,  1117247942 ,  1123294122 ,  191895498 ,  3347106536 ,  16  }  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  result  =  num1 . minus ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // this test only verifies that we don't crash on an assertion
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_signed_multiplication_with_negative_number )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num1 ( 8 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num2 ( - 251 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  result  =  num1 . multiplied_by ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result ,  Crypto : : SignedBigInteger  {  - 2008  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_signed_multiplication_with_big_number )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num1  =  bigint_signed_fibonacci ( 200 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num2 ( - 12345678 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  result  =  num1 . multiplied_by ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < u32 >  expected_result  {  669961318 ,  143970113 ,  4028714974 ,  3164551305 ,  1589380278 ,  2  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . unsigned_value ( ) . words ( ) ,  expected_result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT ( result . is_negative ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_CASE ( test_signed_multiplication_with_two_big_numbers )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num1  =  bigint_signed_fibonacci ( 200 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  num2  =  bigint_signed_fibonacci ( 341 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    num1 . negate ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  result  =  num1 . multiplied_by ( num2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < u32 >  expected_results  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        3017415433 ,  2741793511 ,  1957755698 ,  3731653885 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        3154681877 ,  785762127 ,  3200178098 ,  4260616581 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        529754471 ,  3632684436 ,  1073347813 ,  2516430 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT_EQ ( result . unsigned_value ( ) . words ( ) ,  expected_results ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EXPECT ( result . is_negative ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}