2018-12-27 18:50:45 +03:00
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
# include "gtest/gtest.h"
# include <cstdint>
# include "common/base58.cpp"
# include "currency_core/currency_format_utils.h"
# include "serialization/binary_utils.h"
# include "currency_core/currency_basic.h"
using namespace tools ;
# define MAKE_STR(arr) std::string(arr, sizeof(arr) - 1)
namespace
{
void do_test_uint_8be_to_64 ( uint64_t expected , const uint8_t * data , size_t size )
{
uint64_t val = base58 : : uint_8be_to_64 ( data , size ) ;
ASSERT_EQ ( val , expected ) ;
}
void do_test_uint_64_to_8be ( uint64_t num , const std : : string & expected_str )
{
std : : string data ( expected_str . size ( ) , ' \x0 ' ) ;
base58 : : uint_64_to_8be ( num , data . size ( ) , reinterpret_cast < uint8_t * > ( & data [ 0 ] ) ) ;
ASSERT_EQ ( data , expected_str ) ;
}
void do_test_encode_block ( const std : : string & block , const std : : string & expected )
{
ASSERT_TRUE ( 1 < = block . size ( ) & & block . size ( ) < = base58 : : full_block_size ) ;
std : : string enc ( base58 : : encoded_block_sizes [ block . size ( ) ] , base58 : : alphabet [ 0 ] ) ;
base58 : : encode_block ( block . data ( ) , block . size ( ) , & enc [ 0 ] ) ;
ASSERT_EQ ( enc , expected ) ;
std : : string dec ( block . size ( ) , ' \0 ' ) ;
ASSERT_TRUE ( base58 : : decode_block ( enc . data ( ) , enc . size ( ) , & dec [ 0 ] ) ) ;
ASSERT_EQ ( block , dec ) ;
}
void do_test_decode_block_pos ( const std : : string & enc , const std : : string & expected )
{
std : : string data ( base58 : : decoded_block_sizes : : instance ( enc . size ( ) ) , ' \0 ' ) ;
ASSERT_TRUE ( base58 : : decode_block ( enc . data ( ) , enc . size ( ) , & data [ 0 ] ) ) ;
ASSERT_EQ ( data , expected ) ;
}
void do_test_decode_block_neg ( const std : : string & enc )
{
std : : string data ( base58 : : full_block_size , ' \0 ' ) ;
ASSERT_FALSE ( base58 : : decode_block ( enc . data ( ) , enc . size ( ) , & data [ 0 ] ) ) ;
}
void do_test_encode ( const std : : string & data , const std : : string & expected )
{
std : : string enc = base58 : : encode ( data ) ;
ASSERT_EQ ( enc , expected ) ;
std : : string dec ;
ASSERT_TRUE ( base58 : : decode ( enc , dec ) ) ;
ASSERT_EQ ( dec , data ) ;
}
void do_test_decode_pos ( const std : : string & enc , const std : : string & expected )
{
std : : string dec ;
ASSERT_TRUE ( base58 : : decode ( enc , dec ) ) ;
ASSERT_EQ ( dec , expected ) ;
}
void do_test_decode_neg ( const std : : string & enc )
{
std : : string dec ;
ASSERT_FALSE ( base58 : : decode ( enc , dec ) ) ;
}
void do_test_encode_decode_addr ( uint64_t tag , const std : : string & data , const std : : string & expected )
{
std : : string addr = base58 : : encode_addr ( tag , data ) ;
ASSERT_EQ ( addr , expected ) ;
uint64_t dec_tag ;
std : : string dec_data ;
ASSERT_TRUE ( base58 : : decode_addr ( addr , dec_tag , dec_data ) ) ;
ASSERT_EQ ( tag , dec_tag ) ;
ASSERT_EQ ( data , dec_data ) ;
}
}
# define TEST_uint_8be_to_64(expected, str) \
TEST ( base58_uint_8be_to_64 , handles_bytes_ # # expected ) \
{ \
std : : string data = str ; \
do_test_uint_8be_to_64 ( expected , reinterpret_cast < const uint8_t * > ( data . data ( ) ) , data . size ( ) ) ; \
}
TEST_uint_8be_to_64 ( 0x0000000000000001 , " \ x1 " ) ;
TEST_uint_8be_to_64 ( 0x0000000000000102 , " \ x1 \ x2 " ) ;
TEST_uint_8be_to_64 ( 0x0000000000010203 , " \ x1 \ x2 \ x3 " ) ;
TEST_uint_8be_to_64 ( 0x0000000001020304 , " \ x1 \ x2 \ x3 \ x4 " ) ;
TEST_uint_8be_to_64 ( 0x0000000102030405 , " \ x1 \ x2 \ x3 \ x4 \ x5 " ) ;
TEST_uint_8be_to_64 ( 0x0000010203040506 , " \ x1 \ x2 \ x3 \ x4 \ x5 \ x6 " ) ;
TEST_uint_8be_to_64 ( 0x0001020304050607 , " \ x1 \ x2 \ x3 \ x4 \ x5 \ x6 \ x7 " ) ;
TEST_uint_8be_to_64 ( 0x0102030405060708 , " \ x1 \ x2 \ x3 \ x4 \ x5 \ x6 \ x7 \ x8 " ) ;
# define TEST_uint_64_to_8be(num, expected_str) \
TEST ( base58_uint_64_to_8be , handles_bytes_ # # num ) \
{ \
do_test_uint_64_to_8be ( num , expected_str ) ; \
}
TEST_uint_64_to_8be ( 0x0000000000000001 , " \ x1 " ) ;
TEST_uint_64_to_8be ( 0x0000000000000102 , " \ x1 \ x2 " ) ;
TEST_uint_64_to_8be ( 0x0000000000010203 , " \ x1 \ x2 \ x3 " ) ;
TEST_uint_64_to_8be ( 0x0000000001020304 , " \ x1 \ x2 \ x3 \ x4 " ) ;
TEST_uint_64_to_8be ( 0x0000000102030405 , " \ x1 \ x2 \ x3 \ x4 \ x5 " ) ;
TEST_uint_64_to_8be ( 0x0000010203040506 , " \ x1 \ x2 \ x3 \ x4 \ x5 \ x6 " ) ;
TEST_uint_64_to_8be ( 0x0001020304050607 , " \ x1 \ x2 \ x3 \ x4 \ x5 \ x6 \ x7 " ) ;
TEST_uint_64_to_8be ( 0x0102030405060708 , " \ x1 \ x2 \ x3 \ x4 \ x5 \ x6 \ x7 \ x8 " ) ;
TEST ( reverse_alphabet , is_correct )
{
ASSERT_EQ ( - 1 , base58 : : reverse_alphabet : : instance ( 0 ) ) ;
ASSERT_EQ ( - 1 , base58 : : reverse_alphabet : : instance ( std : : numeric_limits < char > : : min ( ) ) ) ;
ASSERT_EQ ( - 1 , base58 : : reverse_alphabet : : instance ( std : : numeric_limits < char > : : max ( ) ) ) ;
ASSERT_EQ ( - 1 , base58 : : reverse_alphabet : : instance ( ' 1 ' - 1 ) ) ;
ASSERT_EQ ( - 1 , base58 : : reverse_alphabet : : instance ( ' z ' + 1 ) ) ;
ASSERT_EQ ( - 1 , base58 : : reverse_alphabet : : instance ( ' 0 ' ) ) ;
ASSERT_EQ ( - 1 , base58 : : reverse_alphabet : : instance ( ' I ' ) ) ;
ASSERT_EQ ( - 1 , base58 : : reverse_alphabet : : instance ( ' O ' ) ) ;
ASSERT_EQ ( - 1 , base58 : : reverse_alphabet : : instance ( ' l ' ) ) ;
ASSERT_EQ ( 0 , base58 : : reverse_alphabet : : instance ( ' 1 ' ) ) ;
ASSERT_EQ ( 8 , base58 : : reverse_alphabet : : instance ( ' 9 ' ) ) ;
ASSERT_EQ ( base58 : : alphabet_size - 1 , base58 : : reverse_alphabet : : instance ( ' z ' ) ) ;
}
# define TEST_encode_block(block, expected) \
TEST ( base58_encode_block , handles_ # # expected ) \
{ \
do_test_encode_block ( MAKE_STR ( block ) , # expected ) ; \
}
TEST_encode_block ( " \x00 " , 11 ) ;
TEST_encode_block ( " \x39 " , 1 z ) ;
TEST_encode_block ( " \xFF " , 5 Q ) ;
TEST_encode_block ( " \x00 \x00 " , 111 ) ;
TEST_encode_block ( " \x00 \x39 " , 11 z ) ;
TEST_encode_block ( " \x01 \x00 " , 15 R ) ;
TEST_encode_block ( " \xFF \xFF " , LUv ) ;
TEST_encode_block ( " \x00 \x00 \x00 " , 11111 ) ;
TEST_encode_block ( " \x00 \x00 \x39 " , 1111 z ) ;
TEST_encode_block ( " \x01 \x00 \x00 " , 11LU w ) ;
TEST_encode_block ( " \xFF \xFF \xFF " , 2U zHL ) ;
TEST_encode_block ( " \x00 \x00 \x00 \x39 " , 11111 z ) ;
TEST_encode_block ( " \xFF \xFF \xFF \xFF " , 7 YXq9G ) ;
TEST_encode_block ( " \x00 \x00 \x00 \x00 \x39 " , 111111 z ) ;
TEST_encode_block ( " \xFF \xFF \xFF \xFF \xFF " , VtB5VXc ) ;
TEST_encode_block ( " \x00 \x00 \x00 \x00 \x00 \x39 " , 11111111 z ) ;
TEST_encode_block ( " \xFF \xFF \xFF \xFF \xFF \xFF " , 3 CUsUpv9t ) ;
TEST_encode_block ( " \x00 \x00 \x00 \x00 \x00 \x00 \x39 " , 111111111 z ) ;
TEST_encode_block ( " \xFF \xFF \xFF \xFF \xFF \xFF \xFF " , Ahg1opVcGW ) ;
TEST_encode_block ( " \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x39 " , 1111111111 z ) ;
TEST_encode_block ( " \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF " , jpXCZedGfVQ ) ;
TEST_encode_block ( " \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " , 11111111111 ) ;
TEST_encode_block ( " \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x01 " , 11111111112 ) ;
TEST_encode_block ( " \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x08 " , 11111111119 ) ;
TEST_encode_block ( " \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x09 " , 1111111111 A ) ;
TEST_encode_block ( " \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x3A " , 11111111121 ) ;
TEST_encode_block ( " \x00 \xFF \xFF \xFF \xFF \xFF \xFF \xFF " , 1 Ahg1opVcGW ) ;
TEST_encode_block ( " \x06 \x15 \x60 \x13 \x76 \x28 \x79 \xF7 " , 22222222222 ) ;
TEST_encode_block ( " \x05 \xE0 \x22 \xBA \x37 \x4B \x2A \x00 " , 1 z111111111 ) ;
# define TEST_decode_block_pos(enc, expected) \
TEST ( base58_decode_block , handles_pos_ # # enc ) \
{ \
do_test_decode_block_pos ( # enc , MAKE_STR ( expected ) ) ; \
}
# define TEST_decode_block_neg(enc) \
TEST ( base58_decode_block , handles_neg_ # # enc ) \
{ \
do_test_decode_block_neg ( # enc ) ; \
}
// 1-byte block
TEST_decode_block_neg ( 1 ) ;
TEST_decode_block_neg ( z ) ;
// 2-bytes block
TEST_decode_block_pos ( 11 , " \x00 " ) ;
TEST_decode_block_pos ( 5 Q , " \xFF " ) ;
TEST_decode_block_neg ( 5 R ) ;
TEST_decode_block_neg ( zz ) ;
// 3-bytes block
TEST_decode_block_pos ( 111 , " \x00 \x00 " ) ;
TEST_decode_block_pos ( LUv , " \xFF \xFF " ) ;
TEST_decode_block_neg ( LUw ) ;
TEST_decode_block_neg ( zzz ) ;
// 4-bytes block
TEST_decode_block_neg ( 1111 ) ;
TEST_decode_block_neg ( zzzz ) ;
// 5-bytes block
TEST_decode_block_pos ( 11111 , " \x00 \x00 \x00 " ) ;
TEST_decode_block_pos ( 2U zHL , " \xFF \xFF \xFF " ) ;
TEST_decode_block_neg ( 2U zHM ) ;
TEST_decode_block_neg ( zzzzz ) ;
// 6-bytes block
TEST_decode_block_pos ( 111111 , " \x00 \x00 \x00 \x00 " ) ;
TEST_decode_block_pos ( 7 YXq9G , " \xFF \xFF \xFF \xFF " ) ;
TEST_decode_block_neg ( 7 YXq9H ) ;
TEST_decode_block_neg ( zzzzzz ) ;
// 7-bytes block
TEST_decode_block_pos ( 1111111 , " \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_decode_block_pos ( VtB5VXc , " \xFF \xFF \xFF \xFF \xFF " ) ;
TEST_decode_block_neg ( VtB5VXd ) ;
TEST_decode_block_neg ( zzzzzzz ) ;
// 8-bytes block
TEST_decode_block_neg ( 11111111 ) ;
TEST_decode_block_neg ( zzzzzzzz ) ;
// 9-bytes block
TEST_decode_block_pos ( 111111111 , " \x00 \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_decode_block_pos ( 3 CUsUpv9t , " \xFF \xFF \xFF \xFF \xFF \xFF " ) ;
TEST_decode_block_neg ( 3 CUsUpv9u ) ;
TEST_decode_block_neg ( zzzzzzzzz ) ;
// 10-bytes block
TEST_decode_block_pos ( 1111111111 , " \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_decode_block_pos ( Ahg1opVcGW , " \xFF \xFF \xFF \xFF \xFF \xFF \xFF " ) ;
TEST_decode_block_neg ( Ahg1opVcGX ) ;
TEST_decode_block_neg ( zzzzzzzzzz ) ;
// 11-bytes block
TEST_decode_block_pos ( 11111111111 , " \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_decode_block_pos ( jpXCZedGfVQ , " \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF " ) ;
TEST_decode_block_neg ( jpXCZedGfVR ) ;
TEST_decode_block_neg ( zzzzzzzzzzz ) ;
// Invalid symbols
TEST_decode_block_neg ( 01111111111 ) ;
TEST_decode_block_neg ( 11111111110 ) ;
TEST_decode_block_neg ( 11111011111 ) ;
TEST_decode_block_neg ( I1111111111 ) ;
TEST_decode_block_neg ( O1111111111 ) ;
TEST_decode_block_neg ( l1111111111 ) ;
TEST_decode_block_neg ( _1111111111 ) ;
# define TEST_encode(expected, data) \
TEST ( base58_encode , handles_ # # expected ) \
{ \
do_test_encode ( MAKE_STR ( data ) , # expected ) ; \
}
TEST_encode ( 11 , " \x00 " ) ;
TEST_encode ( 111 , " \x00 \x00 " ) ;
TEST_encode ( 11111 , " \x00 \x00 \x00 " ) ;
TEST_encode ( 111111 , " \x00 \x00 \x00 \x00 " ) ;
TEST_encode ( 1111111 , " \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_encode ( 111111111 , " \x00 \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_encode ( 1111111111 , " \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_encode ( 11111111111 , " \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_encode ( 1111111111111 , " \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_encode ( 11111111111111 , " \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_encode ( 1111111111111111 , " \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_encode ( 11111111111111111 , " \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_encode ( 111111111111111111 , " \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_encode ( 11111111111111111111 , " \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_encode ( 111111111111111111111 , " \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_encode ( 1111111111111111111111 , " \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_encode ( 22222222222 VtB5VXc , " \x06 \x15 \x60 \x13 \x76 \x28 \x79 \xF7 \xFF \xFF \xFF \xFF \xFF " ) ;
# define TEST_decode_pos(enc, expected) \
TEST ( base58_decode_pos , handles_pos_ # # enc ) \
{ \
do_test_decode_pos ( # enc , MAKE_STR ( expected ) ) ; \
}
# define TEST_decode_neg(enc) \
TEST ( base58_decode_neg , handles_neg_ # # enc ) \
{ \
do_test_decode_neg ( # enc ) ; \
}
TEST_decode_pos ( , " " ) ;
TEST_decode_pos ( 5 Q , " \xFF " ) ;
TEST_decode_pos ( LUv , " \xFF \xFF " ) ;
TEST_decode_pos ( 2U zHL , " \xFF \xFF \xFF " ) ;
TEST_decode_pos ( 7 YXq9G , " \xFF \xFF \xFF \xFF " ) ;
TEST_decode_pos ( VtB5VXc , " \xFF \xFF \xFF \xFF \xFF " ) ;
TEST_decode_pos ( 3 CUsUpv9t , " \xFF \xFF \xFF \xFF \xFF \xFF " ) ;
TEST_decode_pos ( Ahg1opVcGW , " \xFF \xFF \xFF \xFF \xFF \xFF \xFF " ) ;
TEST_decode_pos ( jpXCZedGfVQ , " \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF " ) ;
TEST_decode_pos ( jpXCZedGfVQ5Q , " \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF " ) ;
TEST_decode_pos ( jpXCZedGfVQLUv , " \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF " ) ;
TEST_decode_pos ( jpXCZedGfVQ2UzHL , " \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF " ) ;
TEST_decode_pos ( jpXCZedGfVQ7YXq9G , " \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF " ) ;
TEST_decode_pos ( jpXCZedGfVQVtB5VXc , " \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF " ) ;
TEST_decode_pos ( jpXCZedGfVQ3CUsUpv9t , " \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF " ) ;
TEST_decode_pos ( jpXCZedGfVQAhg1opVcGW , " \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF " ) ;
TEST_decode_pos ( jpXCZedGfVQjpXCZedGfVQ , " \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF " ) ;
// Invalid length
TEST_decode_neg ( 1 ) ;
TEST_decode_neg ( z ) ;
TEST_decode_neg ( 1111 ) ;
TEST_decode_neg ( zzzz ) ;
TEST_decode_neg ( 11111111 ) ;
TEST_decode_neg ( zzzzzzzz ) ;
TEST_decode_neg ( 123456789 AB1 ) ;
TEST_decode_neg ( 123456789 ABz ) ;
TEST_decode_neg ( 123456789 AB1111 ) ;
TEST_decode_neg ( 123456789 ABzzzz ) ;
TEST_decode_neg ( 123456789 AB11111111 ) ;
TEST_decode_neg ( 123456789 ABzzzzzzzz ) ;
// Overflow
TEST_decode_neg ( 5 R ) ;
TEST_decode_neg ( zz ) ;
TEST_decode_neg ( LUw ) ;
TEST_decode_neg ( zzz ) ;
TEST_decode_neg ( 2U zHM ) ;
TEST_decode_neg ( zzzzz ) ;
TEST_decode_neg ( 7 YXq9H ) ;
TEST_decode_neg ( zzzzzz ) ;
TEST_decode_neg ( VtB5VXd ) ;
TEST_decode_neg ( zzzzzzz ) ;
TEST_decode_neg ( 3 CUsUpv9u ) ;
TEST_decode_neg ( zzzzzzzzz ) ;
TEST_decode_neg ( Ahg1opVcGX ) ;
TEST_decode_neg ( zzzzzzzzzz ) ;
TEST_decode_neg ( jpXCZedGfVR ) ;
TEST_decode_neg ( zzzzzzzzzzz ) ;
TEST_decode_neg ( 123456789 AB5R ) ;
TEST_decode_neg ( 123456789 ABzz ) ;
TEST_decode_neg ( 123456789 ABLUw ) ;
TEST_decode_neg ( 123456789 ABzzz ) ;
TEST_decode_neg ( 123456789 AB2UzHM ) ;
TEST_decode_neg ( 123456789 ABzzzzz ) ;
TEST_decode_neg ( 123456789 AB7YXq9H ) ;
TEST_decode_neg ( 123456789 ABzzzzzz ) ;
TEST_decode_neg ( 123456789 ABVtB5VXd ) ;
TEST_decode_neg ( 123456789 ABzzzzzzz ) ;
TEST_decode_neg ( 123456789 AB3CUsUpv9u ) ;
TEST_decode_neg ( 123456789 ABzzzzzzzzz ) ;
TEST_decode_neg ( 123456789 ABAhg1opVcGX ) ;
TEST_decode_neg ( 123456789 ABzzzzzzzzzz ) ;
TEST_decode_neg ( 123456789 ABjpXCZedGfVR ) ;
TEST_decode_neg ( 123456789 ABzzzzzzzzzzz ) ;
TEST_decode_neg ( zzzzzzzzzzz11 ) ;
// Invalid symbols
TEST_decode_neg ( 10 ) ;
TEST_decode_neg ( 11 I ) ;
TEST_decode_neg ( 11 O11 ) ;
TEST_decode_neg ( 11l 111 ) ;
TEST_decode_neg ( 11 _11111111 ) ;
TEST_decode_neg ( 1101111111111 ) ;
TEST_decode_neg ( 11 I11111111111111 ) ;
TEST_decode_neg ( 11 O1111111111111111111 ) ;
TEST_decode_neg ( 1111111111110 ) ;
TEST_decode_neg ( 111111111111l 1111 ) ;
TEST_decode_neg ( 111111111111 _111111111 ) ;
# define TEST_encode_decode_addr(addr, tag, data) \
TEST ( base58_encode_decode_addr , handles_ # # addr ) \
{ \
do_test_encode_decode_addr ( UINT64_C ( tag ) , MAKE_STR ( data ) , # addr ) ; \
}
TEST_encode_decode_addr ( 21 D35quxec71111111111111111111111111111111111111111111111111111111111111111111111111111116Q5tCH , 6 ,
" \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 "
" \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_encode_decode_addr ( 2 Aui6ejTFscjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQVqegMoV , 6 ,
" \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF "
" \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF " ) ;
TEST_encode_decode_addr ( 1119 XrkPuSmLzdHXgVgrZKjepg5hZAxffLzdHXgVgrZKjepg5hZAxffLzdHXgVgrZKjepg5hZAxffLzdHXgVgrZKVphZRvn , 0 ,
" \x00 \x11 \x22 \x33 \x44 \x55 \x66 \x77 \x88 \x99 \xAA \xBB \xCC \xDD \xEE \xFF \x00 \x11 \x22 \x33 \x44 \x55 \x66 \x77 \x88 \x99 \xAA \xBB \xCC \xDD \xEE \xFF "
" \x00 \x11 \x22 \x33 \x44 \x55 \x66 \x77 \x88 \x99 \xAA \xBB \xCC \xDD \xEE \xFF \x00 \x11 \x22 \x33 \x44 \x55 \x66 \x77 \x88 \x99 \xAA \xBB \xCC \xDD \xEE \xFF " ) ;
TEST_encode_decode_addr ( 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111115 TXfiA , 0 ,
" \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 "
" \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_encode_decode_addr ( PuT7GAdgbA83qvSEivPLYo11111111111111111111111111111111111111111111111111111111111111111111111111111169tWrH , 0x1122334455667788 ,
" \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 "
" \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ) ;
TEST_encode_decode_addr ( PuT7GAdgbA841d7FXjswpJjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQVq4LL1v , 0x1122334455667788 ,
" \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF "
" \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF \xFF " ) ;
TEST_encode_decode_addr ( PuT7GAdgbA819VwdWVDP , 0x1122334455667788 , " \x11 " ) ;
TEST_encode_decode_addr ( PuT7GAdgbA81efAfdCjPg , 0x1122334455667788 , " \x22 \x22 " ) ;
TEST_encode_decode_addr ( PuT7GAdgbA83sryEt3YC8Q , 0x1122334455667788 , " \x33 \x33 \x33 " ) ;
TEST_encode_decode_addr ( PuT7GAdgbA83tWUuc54PFP3b , 0x1122334455667788 , " \x44 \x44 \x44 \x44 " ) ;
TEST_encode_decode_addr ( PuT7GAdgbA83u9zaKrtRKZ1J6 , 0x1122334455667788 , " \x55 \x55 \x55 \x55 \x55 " ) ;
TEST_encode_decode_addr ( PuT7GAdgbA83uoWF3eanGG1aRoG , 0x1122334455667788 , " \x66 \x66 \x66 \x66 \x66 \x66 " ) ;
TEST_encode_decode_addr ( PuT7GAdgbA83vT1umSHMYJ4oNVdu , 0x1122334455667788 , " \x77 \x77 \x77 \x77 \x77 \x77 \x77 " ) ;
TEST_encode_decode_addr ( PuT7GAdgbA83w6XaVDyvpoGQBEWbB , 0x1122334455667788 , " \x88 \x88 \x88 \x88 \x88 \x88 \x88 \x88 " ) ;
TEST_encode_decode_addr ( PuT7GAdgbA83wk3FD1gW7J2KVGofA1r , 0x1122334455667788 , " \x99 \x99 \x99 \x99 \x99 \x99 \x99 \x99 \x99 " ) ;
TEST_encode_decode_addr ( 15 p2yAV , 0 , " " ) ;
TEST_encode_decode_addr ( FNQ3D6A , 0x7F , " " ) ;
TEST_encode_decode_addr ( 26 k9QWweu , 0x80 , " " ) ;
TEST_encode_decode_addr ( 3 BzAD7n3y , 0xFF , " " ) ;
TEST_encode_decode_addr ( 11 efCaY6UjG7JrxuB , 0 , " \x11 \x22 \x33 \x44 \x55 \x66 \x77 " ) ;
TEST_encode_decode_addr ( 21 rhHRT48LN4PriP9 , 6 , " \x11 \x22 \x33 \x44 \x55 \x66 \x77 " ) ;
# define TEST_decode_addr_neg(addr, test_name) \
TEST ( base58_decode_addr_neg , test_name ) \
{ \
uint64_t tag ; \
std : : string data ; \
ASSERT_FALSE ( base58 : : decode_addr ( MAKE_STR ( addr ) , tag , data ) ) ; \
}
TEST_decode_addr_neg ( " zuT7GAdgbA819VwdWVDP " , decode_fails_due_overflow ) ;
TEST_decode_addr_neg ( " 0uT7GAdgbA819VwdWVDP " , decode_fails_due_invalid_char_0 ) ;
TEST_decode_addr_neg ( " IuT7GAdgbA819VwdWVDP " , decode_fails_due_invalid_char_I ) ;
TEST_decode_addr_neg ( " OuT7GAdgbA819VwdWVDP " , decode_fails_due_invalid_char_O ) ;
TEST_decode_addr_neg ( " luT7GAdgbA819VwdWVDP " , decode_fails_due_invalid_char_l ) ;
TEST_decode_addr_neg ( " \0 uT7GAdgbA819VwdWVDP " , decode_fails_due_invalid_char_00 ) ;
TEST_decode_addr_neg ( " PuT7GAdgbA819VwdWVD " , decode_fails_due_invalid_lenght ) ;
TEST_decode_addr_neg ( " 11efCaY6UjG7JrxuC " , handles_invalid_checksum ) ;
TEST_decode_addr_neg ( " jerj2e4mESo " , handles_non_correct_tag ) ; // "jerj2e4mESo" == "\xFF\x00\xFF\xFF\x5A\xD9\xF1\x1C"
TEST_decode_addr_neg ( " 1 " , decode_fails_due_invalid_block_len_0 ) ;
TEST_decode_addr_neg ( " 1111 " , decode_fails_due_invalid_block_len_1 ) ;
TEST_decode_addr_neg ( " 11 " , decode_fails_due_address_too_short_0 ) ;
TEST_decode_addr_neg ( " 111 " , decode_fails_due_address_too_short_1 ) ;
TEST_decode_addr_neg ( " 11111 " , decode_fails_due_address_too_short_2 ) ;
TEST_decode_addr_neg ( " 111111 " , decode_fails_due_address_too_short_3 ) ;
TEST_decode_addr_neg ( " 999999 " , decode_fails_due_address_too_short_4 ) ;
TEST_decode_addr_neg ( " ZZZZZZ " , decode_fails_due_address_too_short_5 ) ;
namespace
{
std : : string test_serialized_keys = MAKE_STR (
" \xf7 \x24 \xbc \x5c \x6c \xfb \xb9 \xd9 \x76 \x02 \xc3 \x00 \x42 \x3a \x2f \x28 "
" \x64 \x18 \x74 \x51 \x3a \x03 \x57 \x78 \xa0 \xc1 \x77 \x8d \x83 \x32 \x01 \xe9 "
" \x22 \x09 \x39 \x68 \x9e \xdf \x1a \xbd \x5b \xc1 \xd0 \x31 \xf7 \x3e \xcd \x6c "
2020-05-28 19:38:47 +03:00
" \x99 \x3a \xdd \x66 \xd6 \x80 \x88 \x70 \x45 \x6a \xfe \xb8 \xe7 \xee \xb6 \x8d "
" \x00 " ) ;
2018-12-27 18:50:45 +03:00
std : : string test_keys_addr_str = " ZxDqHy6WnyYY5yQcdApjMb8tVPik5BC3LFdaevfbGq7X1KY5vdsWmUi5UQgse2GBZFbMsb47TFqBmPpdFHDDwDxR2ZuZ6zX4W " ; // correct str address depends on CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX value
}
TEST ( get_account_address_as_str , works_correctly )
{
currency : : account_public_address addr ;
ASSERT_TRUE ( serialization : : parse_binary ( test_serialized_keys , addr ) ) ;
std : : string addr_str = currency : : get_account_address_as_str ( addr ) ;
ASSERT_EQ ( addr_str , test_keys_addr_str ) ;
}
TEST ( get_account_address_from_str , handles_valid_address )
{
currency : : account_public_address addr ;
ASSERT_TRUE ( currency : : get_account_address_from_str ( addr , test_keys_addr_str ) ) ;
std : : string blob ;
ASSERT_TRUE ( serialization : : dump_binary ( addr , blob ) ) ;
ASSERT_EQ ( blob , test_serialized_keys ) ;
}
TEST ( get_account_address_from_str , fails_on_invalid_address_format )
{
currency : : account_public_address addr ;
std : : string addr_str = test_keys_addr_str ;
addr_str [ 0 ] = ' 0 ' ;
ASSERT_FALSE ( currency : : get_account_address_from_str ( addr , addr_str ) ) ;
}
TEST ( get_account_address_from_str , fails_on_invalid_address_prefix )
{
std : : string addr_str = base58 : : encode_addr ( 0 , test_serialized_keys ) ;
currency : : account_public_address addr ;
ASSERT_FALSE ( currency : : get_account_address_from_str ( addr , addr_str ) ) ;
}
TEST ( get_account_address_from_str , fails_on_invalid_address_content )
{
std : : string addr_str = base58 : : encode_addr ( CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX , test_serialized_keys . substr ( 1 ) ) ;
currency : : account_public_address addr ;
ASSERT_FALSE ( currency : : get_account_address_from_str ( addr , addr_str ) ) ;
}
TEST ( get_account_address_from_str , fails_on_invalid_address_spend_key )
{
std : : string serialized_keys_copy = test_serialized_keys ;
serialized_keys_copy [ 0 ] = ' \0 ' ;
std : : string addr_str = base58 : : encode_addr ( CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX , serialized_keys_copy ) ;
currency : : account_public_address addr ;
ASSERT_FALSE ( currency : : get_account_address_from_str ( addr , addr_str ) ) ;
}
TEST ( get_account_address_from_str , fails_on_invalid_address_view_key )
{
std : : string serialized_keys_copy = test_serialized_keys ;
2020-05-28 19:38:47 +03:00
serialized_keys_copy [ serialized_keys_copy . size ( ) - 2 ] = ' \x01 ' ;
2018-12-27 18:50:45 +03:00
std : : string addr_str = base58 : : encode_addr ( CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX , serialized_keys_copy ) ;
currency : : account_public_address addr ;
ASSERT_FALSE ( currency : : get_account_address_from_str ( addr , addr_str ) ) ;
}
// integrated addresses
TEST ( integ_address , payment_id_sizes )
{
size_t pid_size_max = BC_PAYMENT_ID_SERVICE_SIZE_MAX ;
for ( size_t pid_size = 0 ; pid_size < = pid_size_max ; + + pid_size )
{
std : : string payment_id ( pid_size , ' ' ) ;
if ( pid_size > 0 )
crypto : : generate_random_bytes ( pid_size , & payment_id . front ( ) ) ;
2020-07-08 19:25:30 +03:00
currency : : account_public_address addr = AUTO_VAL_INIT_T ( currency : : account_public_address ) ;
2020-04-23 14:56:03 +03:00
addr . spend_public_key = currency : : keypair : : generate ( ) . pub ;
addr . view_public_key = currency : : keypair : : generate ( ) . pub ;
2018-12-27 18:50:45 +03:00
std : : string addr_str = currency : : get_account_address_and_payment_id_as_str ( addr , payment_id ) ;
2020-07-08 19:25:30 +03:00
currency : : account_public_address addr2 = AUTO_VAL_INIT_T ( currency : : account_public_address ) ;
2018-12-27 18:50:45 +03:00
std : : string integrated_payment_id ;
ASSERT_TRUE ( currency : : get_account_address_and_payment_id_from_str ( addr2 , integrated_payment_id , addr_str ) ) ;
ASSERT_EQ ( addr2 , addr ) ;
ASSERT_EQ ( integrated_payment_id , payment_id ) ;
}
// test max size exceeding
size_t pid_size = BC_PAYMENT_ID_SERVICE_SIZE_MAX + 1 ;
std : : string payment_id ( pid_size , ' ' ) ;
if ( pid_size > 0 )
crypto : : generate_random_bytes ( pid_size , & payment_id . front ( ) ) ;
2020-07-08 19:25:30 +03:00
currency : : account_public_address addr = AUTO_VAL_INIT_T ( currency : : account_public_address ) ;
2020-04-23 14:56:03 +03:00
addr . spend_public_key = currency : : keypair : : generate ( ) . pub ;
addr . view_public_key = currency : : keypair : : generate ( ) . pub ;
2018-12-27 18:50:45 +03:00
// the following line is expected to handle oversized payment id well
std : : string addr_str = currency : : get_account_address_and_payment_id_as_str ( addr , payment_id ) ;
2020-07-08 19:25:30 +03:00
currency : : account_public_address addr2 = AUTO_VAL_INIT_T ( currency : : account_public_address ) ;
2018-12-27 18:50:45 +03:00
std : : string integrated_payment_id ;
ASSERT_FALSE ( currency : : get_account_address_and_payment_id_from_str ( addr2 , integrated_payment_id , addr_str ) ) ;
}
2020-04-30 18:50:22 +03:00
struct addr_entry_t
{
std : : string address ;
std : : string view_pub_key ;
std : : string spend_pub_key ;
std : : string payment_id_hex ;
uint8_t flags ;
} ;
addr_entry_t addr_entries [ ] =
{
{
// classic normal address
" ZxD5aoLDPTdcaRx4uCpyW4XiLfEXejepAVz8cSY2fwHNEiJNu6NmpBBDLGTJzCsUvn3acCVDVDPMV8yQXdPooAp338Se7AxeH " , // address
" a3f208c8f9ba49bab28eed62b35b0f6be0a297bcd85c2faa1eb1820527bcf7e3 " , // view_pub_key
" 9f5e1fa93630d4b281b18bb67a3db79e9622fc703cc3ad4a453a82e0a36d51fa " , // spend_pub_key
" " , // payment_id_hex
0 // flags
} ,
{
// classic integrated address
" iZ2Zi6RmTWwcaRx4uCpyW4XiLfEXejepAVz8cSY2fwHNEiJNu6NmpBBDLGTJzCsUvn3acCVDVDPMV8yQXdPooAp3iTqEsjvJoco1aLSZXS6T " , // address
" a3f208c8f9ba49bab28eed62b35b0f6be0a297bcd85c2faa1eb1820527bcf7e3 " , // view_pub_key
" 9f5e1fa93630d4b281b18bb67a3db79e9622fc703cc3ad4a453a82e0a36d51fa " , // spend_pub_key
" 87440d0b9acc42f1 " , // payment_id_hex
0 // flags
} ,
{
// new format normal address with custom flags
" ZxD5aoLDPTdcaRx4uCpyW4XiLfEXejepAVz8cSY2fwHNEiJNu6NmpBBDLGTJzCsUvn3acCVDVDPMV8yQXdPooAp3APrDvRoL5C " , // address
" a3f208c8f9ba49bab28eed62b35b0f6be0a297bcd85c2faa1eb1820527bcf7e3 " , // view_pub_key
" 9f5e1fa93630d4b281b18bb67a3db79e9622fc703cc3ad4a453a82e0a36d51fa " , // spend_pub_key
" " , // payment_id_hex
0xfe // flags
} ,
{
// new format integrated address with custom flags
" iZ4mBxubNfqcaRx4uCpyW4XiLfEXejepAVz8cSY2fwHNEiJNu6NmpBBDLGTJzCsUvn3acCVDVDPMV8yQXdPooAp3iTrG7nU5rRCWmcozLaMoY95sAbo6 " , // address
" a3f208c8f9ba49bab28eed62b35b0f6be0a297bcd85c2faa1eb1820527bcf7e3 " , // view_pub_key
" 9f5e1fa93630d4b281b18bb67a3db79e9622fc703cc3ad4a453a82e0a36d51fa " , // spend_pub_key
" 3ba0527bcfb1fa93630d28eed6 " , // payment_id
0xfe // flags
} ,
{
// normal auditable address
" aZxb9Et6FhP9AinRwcPqSqBKjckre7PgoZjK3q5YG2fUKHYWFZMWjB6YAEAdw4yDDUGEQ7CGEgbqhGRKeadGV1jLYcEJMEmqQFn " , // address
" a3f208c8f9ba49bab28eed62b35b0f6be0a297bcd85c2faa1eb1820527bcf7e3 " , // view_pub_key
" 9f5e1fa93630d4b281b18bb67a3db79e9622fc703cc3ad4a453a82e0a36d51fa " , // spend_pub_key
" " , // payment_id
ACCOUNT_PUBLIC_ADDRESS_FLAG_AUDITABLE // flags
} ,
{
// auditable integrated address
" aiZXDondHWu9AinRwcPqSqBKjckre7PgoZjK3q5YG2fUKHYWFZMWjB6YAEAdw4yDDUGEQ7CGEgbqhGRKeadGV1jLYcEJM9xJH8EbjuRiMJgFmPRATsEV9 " , // address
" a3f208c8f9ba49bab28eed62b35b0f6be0a297bcd85c2faa1eb1820527bcf7e3 " , // view_pub_key
" 9f5e1fa93630d4b281b18bb67a3db79e9622fc703cc3ad4a453a82e0a36d51fa " , // spend_pub_key
" 3ba0527bcfb1fa93630d28eed6 " , // payment_id
ACCOUNT_PUBLIC_ADDRESS_FLAG_AUDITABLE // flags
}
} ;
void check_add_entry ( const addr_entry_t & ae )
{
std : : string payment_id , payment_id_hex ;
currency : : account_public_address addr = AUTO_VAL_INIT ( addr ) ;
ASSERT_TRUE ( currency : : get_account_address_and_payment_id_from_str ( addr , payment_id , ae . address ) ) ;
payment_id_hex = epee : : string_tools : : buff_to_hex_nodelimer ( payment_id ) ;
ASSERT_EQ ( ae . flags , addr . flags ) ;
ASSERT_EQ ( ae . payment_id_hex , payment_id_hex ) ;
ASSERT_EQ ( ae . view_pub_key , epee : : string_tools : : pod_to_hex ( addr . view_public_key ) ) ;
ASSERT_EQ ( ae . spend_pub_key , epee : : string_tools : : pod_to_hex ( addr . spend_public_key ) ) ;
}
TEST ( auditable_addresses , basic )
{
/*
currency : : account_keys keys = AUTO_VAL_INIT ( keys ) ;
epee : : string_tools : : parse_tpod_from_hex_string ( " 248b019d145d485576ecb0367d92b5a12e8aa15084b59ef15014a7a22d1f3b0c " , keys . spend_secret_key ) ;
dependent_key ( keys . spend_secret_key , keys . view_secret_key ) ;
crypto : : secret_key_to_public_key ( keys . view_secret_key , keys . account_address . view_public_key ) ;
crypto : : secret_key_to_public_key ( keys . spend_secret_key , keys . account_address . spend_public_key ) ;
keys . account_address . flags = 0xfe ;
std : : string payment_id ;
epee : : string_tools : : parse_hexstr_to_binbuff ( std : : string ( " 3ba0527bcfb1fa93630d28eed6 " ) , payment_id ) ;
std : : cout < < currency : : get_account_address_as_str ( keys . account_address ) < < " " < < epee : : string_tools : : pod_to_hex ( keys . account_address . view_public_key ) < < " " < < epee : : string_tools : : pod_to_hex ( keys . account_address . spend_public_key ) < < ENDL ;
std : : cout < < currency : : get_account_address_and_payment_id_as_str ( keys . account_address , payment_id ) < < " " < < epee : : string_tools : : pod_to_hex ( keys . account_address . view_public_key ) < < " " < < epee : : string_tools : : pod_to_hex ( keys . account_address . spend_public_key ) < < ENDL ;
*/
for ( size_t i = 0 ; i < sizeof addr_entries / sizeof addr_entries [ 0 ] ; + + i )
check_add_entry ( addr_entries [ i ] ) ;
}