From 9065c4f9daaf947d8d37d63d91c0dd755c1262d2 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Fri, 9 Feb 2018 18:20:30 -0500 Subject: [PATCH] still working on crypto tests --- contracts/eosiolib/crypto.h | 63 ++++- contracts/eosiolib/print.hpp | 11 +- contracts/eosiolib/types.h | 8 +- contracts/eosiolib/types.hpp | 6 + contracts/test_api/test_api.cpp | 12 + contracts/test_api/test_api.hpp | 12 + contracts/test_api/test_crypto.cpp | 326 ++++++++++++++++++++++-- contracts/test_api/test_transaction.cpp | 4 +- libraries/chain/wasm_interface.cpp | 19 ++ tests/api_tests/api_tests.cpp | 69 ++++- 10 files changed, 501 insertions(+), 29 deletions(-) diff --git a/contracts/eosiolib/crypto.h b/contracts/eosiolib/crypto.h index 7f7e50104..7d2c151ce 100644 --- a/contracts/eosiolib/crypto.h +++ b/contracts/eosiolib/crypto.h @@ -14,10 +14,69 @@ extern "C" { * * This method is optimized to a NO-OP when in fast evaluation mode */ -void eos_assert_sha256( char* data, uint32_t length, const checksum* hash ); +void eos_assert_sha256( char* data, uint32_t length, const checksum_base* hash ); + +/** + * This method is implemented as: + * + * checksum calc_hash; + * sha1( data, length, &calc_hash ); + * eos_assert( calc_hash == hash, "invalid hash" ); + * + * This method is optimized to a NO-OP when in fast evaluation mode + */ +void eos_assert_sha1( char* data, uint32_t length, const checksum_base* hash ); + +/** + * This method is implemented as: + * + * checksum calc_hash; + * sha512( data, length, &calc_hash ); + * eos_assert( calc_hash == hash, "invalid hash" ); + * + * This method is optimized to a NO-OP when in fast evaluation mode + */ +void eos_assert_sha512( char* data, uint32_t length, const checksum_base* hash ); + +/** + * This method is implemented as: + * + * checksum calc_hash; + * ripemd160( data, length, &calc_hash ); + * eos_assert( calc_hash == hash, "invalid hash" ); + * + * This method is optimized to a NO-OP when in fast evaluation mode + */ +void eos_assert_ripemd160( char* data, uint32_t length, const checksum_base* hash ); /** * Calculates sha256( data,length) and stores result in memory pointed to by hash + * `hash` should be checksum<256> + */ +void sha256( char* data, uint32_t length, checksum_base* hash ); + +/** + * Calculates sha1( data,length) and stores result in memory pointed to by hash + * `hash` should be checksum<160> */ -void sha256( char* data, uint32_t length, checksum* hash ); +void sha1( char* data, uint32_t length, checksum_base* hash ); + +/** + * Calculates sha512( data,length) and stores result in memory pointed to by hash + * `hash` should be checksum<512> + */ +void sha512( char* data, uint32_t length, checksum_base* hash ); + +/** + * Calculates ripemd160( data,length) and stores result in memory pointed to by hash + * `hash` should be checksum<160> + */ +void ripemd160( char* data, uint32_t length, checksum_base* hash ); + +/** + * Calculates the public key used for a given signature and hash used to create a message + * `digest` should be checksum<256> + */ +int recover_key( checksum_base* digest, const char* sig, size_t siglen, char* pub, size_t publen ); + } diff --git a/contracts/eosiolib/print.hpp b/contracts/eosiolib/print.hpp index 6271a5ca0..9366c258f 100644 --- a/contracts/eosiolib/print.hpp +++ b/contracts/eosiolib/print.hpp @@ -87,6 +87,12 @@ namespace eosio { prints(val?"true":"false"); } + template + inline void print( T&& t ) { + t.print(); + } + + inline void print_f( const char* s ) { prints(s); } @@ -104,11 +110,6 @@ namespace eosio { } } - template - inline void print( T&& t ) { - t.print(); - } - /** * @defgroup consoleCppapi Console C++ API diff --git a/contracts/eosiolib/types.h b/contracts/eosiolib/types.h index e4b3149b6..030fe4d68 100644 --- a/contracts/eosiolib/types.h +++ b/contracts/eosiolib/types.h @@ -6,6 +6,10 @@ #include #include +/* +struct checksum_base { +}; +*/ extern "C" { @@ -43,8 +47,8 @@ struct signature { uint8_t data[65]; }; -struct checksum { - uint64_t hash[4]; +struct checksum_base { + uint8_t hash[1]; }; struct fixed_string16 { diff --git a/contracts/eosiolib/types.hpp b/contracts/eosiolib/types.hpp index 4c9976cfb..9822c109f 100644 --- a/contracts/eosiolib/types.hpp +++ b/contracts/eosiolib/types.hpp @@ -104,4 +104,10 @@ namespace eosio { struct true_type { enum _value { value = 1 }; }; struct false_type { enum _value { value = 0 }; }; + template < uint16_t digest_size > + struct checksum : checksum_base { + static_assert( digest_size % 8 == 0, "checksum template argument must be divisible by 8" ); + uint8_t hash[(digest_size/8)-1]; + }; + } // namespace eos diff --git a/contracts/test_api/test_api.cpp b/contracts/test_api/test_api.cpp index 3ed831f19..786f3ace8 100644 --- a/contracts/test_api/test_api.cpp +++ b/contracts/test_api/test_api.cpp @@ -79,11 +79,23 @@ extern "C" { //test crypto WASM_TEST_HANDLER(test_crypto, test_recover_key); + WASM_TEST_HANDLER(test_crypto, test_sha1); WASM_TEST_HANDLER(test_crypto, test_sha256); + WASM_TEST_HANDLER(test_crypto, test_sha512); + WASM_TEST_HANDLER(test_crypto, test_ripemd160); + WASM_TEST_HANDLER(test_crypto, sha1_no_data); WASM_TEST_HANDLER(test_crypto, sha256_no_data); + WASM_TEST_HANDLER(test_crypto, sha512_no_data); + WASM_TEST_HANDLER(test_crypto, ripemd160_no_data); WASM_TEST_HANDLER(test_crypto, sha256_null); WASM_TEST_HANDLER(test_crypto, assert_sha256_false); WASM_TEST_HANDLER(test_crypto, assert_sha256_true); + WASM_TEST_HANDLER(test_crypto, assert_sha1_false); + WASM_TEST_HANDLER(test_crypto, assert_sha1_true); + WASM_TEST_HANDLER(test_crypto, assert_sha512_false); + WASM_TEST_HANDLER(test_crypto, assert_sha512_true); + WASM_TEST_HANDLER(test_crypto, assert_ripemd160_false); + WASM_TEST_HANDLER(test_crypto, assert_ripemd160_true); //test transaction WASM_TEST_HANDLER(test_transaction, test_tapos_block_num); diff --git a/contracts/test_api/test_api.hpp b/contracts/test_api/test_api.hpp index 9634652a7..dbb096f99 100644 --- a/contracts/test_api/test_api.hpp +++ b/contracts/test_api/test_api.hpp @@ -126,11 +126,23 @@ struct test_db { struct test_crypto { static void test_recover_key(); + static void test_sha1(); static void test_sha256(); + static void test_sha512(); + static void test_ripemd160(); + static void sha1_no_data(); static void sha256_no_data(); + static void sha512_no_data(); + static void ripemd160_no_data(); static void sha256_null(); static void assert_sha256_false(); + static void assert_sha1_false(); + static void assert_sha512_false(); + static void assert_ripemd160_false(); static void assert_sha256_true(); + static void assert_sha1_true(); + static void assert_sha512_true(); + static void assert_ripemd160_true(); }; struct test_transaction { diff --git a/contracts/test_api/test_crypto.cpp b/contracts/test_api/test_crypto.cpp index ee47a554f..59d908eb6 100644 --- a/contracts/test_api/test_crypto.cpp +++ b/contracts/test_api/test_crypto.cpp @@ -10,45 +10,160 @@ #define WASM_TEST_FAIL 1 static const char test1[] = "abc"; -static const unsigned char test1_ok[] = { +static const unsigned char test1_ok_1[] = { + 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, + 0x6a, 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, + 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d +}; + +static const unsigned char test1_ok_256[] = { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad }; +static const unsigned char test1_ok_512[] = { + 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, + 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, + 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, + 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, + 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, + 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, + 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, + 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f +}; + +static const unsigned char test1_ok_ripe[] = { + 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, + 0x9b, 0x04, 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, + 0xf1, 0x5a, 0x0b, 0xfc +}; + const char test2[] = ""; -const unsigned char test2_ok[] = { +static const unsigned char test2_ok_1[] = { + 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, + 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, + 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09 +}; + +const unsigned char test2_ok_256[] = { 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 }; +const unsigned char test2_ok_512[] = { + 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd, + 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07, + 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc, + 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce, + 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0, + 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f, + 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81, + 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e +}; + +const unsigned char test2_ok_ripe[] = { + 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, + 0x61, 0x28, 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, + 0xb2, 0x25, 0x8d, 0x31 +}; + static const char test3[] = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; -static const unsigned char test3_ok[] = { +static const unsigned char test3_ok_1[] = { + 0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2, + 0x6e, 0xba, 0xae, 0x4a, 0xa1, 0xf9, 0x51, + 0x29, 0xe5, 0xe5, 0x46, 0x70, 0xf1 +}; + +static const unsigned char test3_ok_256[] = { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 }; +static const unsigned char test3_ok_512[] = { + 0x20, 0x4a, 0x8f, 0xc6, 0xdd, 0xa8, 0x2f, 0x0a, + 0x0c, 0xed, 0x7b, 0xeb, 0x8e, 0x08, 0xa4, 0x16, + 0x57, 0xc1, 0x6e, 0xf4, 0x68, 0xb2, 0x28, 0xa8, + 0x27, 0x9b, 0xe3, 0x31, 0xa7, 0x03, 0xc3, 0x35, + 0x96, 0xfd, 0x15, 0xc1, 0x3b, 0x1b, 0x07, 0xf9, + 0xaa, 0x1d, 0x3b, 0xea, 0x57, 0x78, 0x9c, 0xa0, + 0x31, 0xad, 0x85, 0xc7, 0xa7, 0x1d, 0xd7, 0x03, + 0x54, 0xec, 0x63, 0x12, 0x38, 0xca, 0x34, 0x45 +}; + +static const unsigned char test3_ok_ripe[] = { + 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, + 0xe4, 0x05, 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, + 0xda, 0x62, 0xeb, 0x2b +}; + static const char test4[] = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; -static const unsigned char test4_ok[] = { +static const unsigned char test4_ok_1[] = { + 0xa4, 0x9b, 0x24, 0x46, 0xa0, 0x2c, 0x64, + 0x5b, 0xf4, 0x19, 0xf9, 0x95, 0xb6, 0x70, + 0x91, 0x25, 0x3a, 0x04, 0xa2, 0x59 +}; + +static const unsigned char test4_ok_256[] = { 0xcf, 0x5b, 0x16, 0xa7, 0x78, 0xaf, 0x83, 0x80, 0x03, 0x6c, 0xe5, 0x9e, 0x7b, 0x04, 0x92, 0x37, 0x0b, 0x24, 0x9b, 0x11, 0xe8, 0xf0, 0x7a, 0x51, 0xaf, 0xac, 0x45, 0x03, 0x7a, 0xfe, 0xe9, 0xd1 }; +static const unsigned char test4_ok_512[] = { + 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda, + 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f, + 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1, + 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18, + 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4, + 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a, + 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54, + 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 +}; + +static const unsigned char test4_ok_ripe[] = { + 0x6f, 0x3f, 0xa3, 0x9b, 0x6b, 0x50, 0x3c, 0x38, + 0x4f, 0x91, 0x9a, 0x49, 0xa7, 0xaa, 0x5c, 0x2c, + 0x08, 0xbd, 0xfb, 0x45 +}; + static const char test5[] = "message digest"; -static const unsigned char test5_ok[] = { +static const unsigned char test5_ok_1[] = { + 0xc1, 0x22, 0x52, 0xce, 0xda, 0x8b, 0xe8, + 0x99, 0x4d, 0x5f, 0xa0, 0x29, 0x0a, 0x47, + 0x23, 0x1c, 0x1d, 0x16, 0xaa, 0xe3 +}; + +static const unsigned char test5_ok_256[] = { 0xf7, 0x84, 0x6f, 0x55, 0xcf, 0x23, 0xe1, 0x4e, 0xeb, 0xea, 0xb5, 0xb4, 0xe1, 0x55, 0x0c, 0xad, 0x5b, 0x50, 0x9e, 0x33, 0x48, 0xfb, 0xc4, 0xef, 0xa3, 0xa1, 0x41, 0x3d, 0x39, 0x3c, 0xb6, 0x50 }; +static const unsigned char test5_ok_512[] = { + 0x10, 0x7d, 0xbf, 0x38, 0x9d, 0x9e, 0x9f, 0x71, + 0xa3, 0xa9, 0x5f, 0x6c, 0x05, 0x5b, 0x92, 0x51, + 0xbc, 0x52, 0x68, 0xc2, 0xbe, 0x16, 0xd6, 0xc1, + 0x34, 0x92, 0xea, 0x45, 0xb0, 0x19, 0x9f, 0x33, + 0x09, 0xe1, 0x64, 0x55, 0xab, 0x1e, 0x96, 0x11, + 0x8e, 0x8a, 0x90, 0x5d, 0x55, 0x97, 0xb7, 0x20, + 0x38, 0xdd, 0xb3, 0x72, 0xa8, 0x98, 0x26, 0x04, + 0x6d, 0xe6, 0x66, 0x87, 0xbb, 0x42, 0x0e, 0x7c +}; + +static const unsigned char test5_ok_ripe[] = { + 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, + 0x72, 0xb8, 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, + 0x21, 0x59, 0x5f, 0x36 +}; + extern "C" { uint32_t my_strlen(const char *str) { uint32_t len = 0; @@ -70,45 +185,139 @@ extern "C" { } +struct sig_hash { + char sig[72]; + checksum<256> hash; +}; + void test_crypto::test_recover_key() { + sig_hash sh; + read_action( (char*)&sh, sizeof(sh) ); + char a[40]; + int recovered = recover_key( &sh.hash, (const char*)&sh.sig, sizeof(sh.sig), a, 40 ); + prints("S "); + printi(recovered); + prints("\n"); + checksum<256> tmp; + sha256( (char*)&sh, sizeof(sh), &tmp); + prints("SSS "); + printhex((char*)&tmp, sizeof(tmp)); + prints("\nPK "); + printhex(a, 40); + prints("\n"); +} + +void test_crypto::test_sha1() { + checksum<160> tmp; + + sha1( (char *)test1, my_strlen(test1), &tmp ); + eos_assert( my_memcmp((void *)test1_ok_1, &tmp, sizeof(checksum<160>)), "sha1 test1" ); + + sha1( (char *)test3, my_strlen(test3), &tmp ); + eos_assert( my_memcmp((void *)test3_ok_1, &tmp, sizeof(checksum<160>)), "sha1 test3" ); + + sha1( (char *)test4, my_strlen(test4), &tmp ); + eos_assert( my_memcmp((void *)test4_ok_1, &tmp, sizeof(checksum<160>)), "sha1 test4" ); + + sha1( (char *)test5, my_strlen(test5), &tmp ); + eos_assert( my_memcmp((void *)test5_ok_1, &tmp, sizeof(checksum<160>)), "sha1 test5" ); } void test_crypto::test_sha256() { - checksum tmp; + checksum<256> tmp; sha256( (char *)test1, my_strlen(test1), &tmp ); - eos_assert( my_memcmp((void *)test1_ok, &tmp, sizeof(checksum)), "sha256 test1" ); + eos_assert( my_memcmp((void *)test1_ok_256, &tmp, sizeof(checksum<256>)), "sha256 test1" ); sha256( (char *)test3, my_strlen(test3), &tmp ); - eos_assert( my_memcmp((void *)test3_ok, &tmp, sizeof(checksum)), "sha256 test3" ); + eos_assert( my_memcmp((void *)test3_ok_256, &tmp, sizeof(checksum<256>)), "sha256 test3" ); sha256( (char *)test4, my_strlen(test4), &tmp ); - eos_assert( my_memcmp((void *)test4_ok, &tmp, sizeof(checksum)), "sha256 test4" ); + eos_assert( my_memcmp((void *)test4_ok_256, &tmp, sizeof(checksum<256>)), "sha256 test4" ); sha256( (char *)test5, my_strlen(test5), &tmp ); - eos_assert( my_memcmp((void *)test5_ok, &tmp, sizeof(checksum)), "sha256 test5" ); + eos_assert( my_memcmp((void *)test5_ok_256, &tmp, sizeof(checksum<256>)), "sha256 test5" ); +} + +void test_crypto::test_sha512() { + + checksum<512> tmp; + + sha512( (char *)test1, my_strlen(test1), &tmp ); + eos_assert( my_memcmp((void *)test1_ok_512, &tmp, sizeof(checksum<512>)), "sha512 test1" ); + + sha512( (char *)test3, my_strlen(test3), &tmp ); + eos_assert( my_memcmp((void *)test3_ok_512, &tmp, sizeof(checksum<512>)), "sha512 test3" ); + + sha512( (char *)test4, my_strlen(test4), &tmp ); + eos_assert( my_memcmp((void *)test4_ok_512, &tmp, sizeof(checksum<512>)), "sha512 test4" ); + + sha512( (char *)test5, my_strlen(test5), &tmp ); + eos_assert( my_memcmp((void *)test5_ok_512, &tmp, sizeof(checksum<512>)), "sha512 test5" ); +} + +void test_crypto::test_ripemd160() { + + checksum<160> tmp; + + ripemd160( (char *)test1, my_strlen(test1), &tmp ); + eos_assert( my_memcmp((void *)test1_ok_ripe, &tmp, sizeof(checksum<160>)), "ripemd160 test1" ); + + ripemd160( (char *)test3, my_strlen(test3), &tmp ); + eos_assert( my_memcmp((void *)test3_ok_ripe, &tmp, sizeof(checksum<160>)), "ripemd160 test3" ); + + ripemd160( (char *)test4, my_strlen(test4), &tmp ); + eos_assert( my_memcmp((void *)test4_ok_ripe, &tmp, sizeof(checksum<160>)), "ripemd160 test4" ); + + ripemd160( (char *)test5, my_strlen(test5), &tmp ); + eos_assert( my_memcmp((void *)test5_ok_ripe, &tmp, sizeof(checksum<160>)), "ripemd160 test5" ); } void test_crypto::sha256_null() { - checksum tmp; + checksum<256> tmp; int a = 3; int* b = &a; sha256(nullptr, 100, &tmp); //eos_assert(false, "should've thrown an error"); } +void test_crypto::sha1_no_data() { + + checksum<160> tmp; + + sha1( (char *)test2, my_strlen(test2), &tmp ); + eos_assert( my_memcmp((void *)test2_ok_1, &tmp, sizeof(checksum<160>)), "sha1 test2" ); +} + void test_crypto::sha256_no_data() { - checksum tmp; + checksum<256> tmp; sha256( (char *)test2, my_strlen(test2), &tmp ); - eos_assert( my_memcmp((void *)test2_ok, &tmp, sizeof(checksum)), "sha256 test2" ); + eos_assert( my_memcmp((void *)test2_ok_256, &tmp, sizeof(checksum<256>)), "sha256 test2" ); +} + +void test_crypto::sha512_no_data() { + + checksum<512> tmp; + + sha512( (char *)test2, my_strlen(test2), &tmp ); + eos_assert( my_memcmp((void *)test2_ok_512, &tmp, sizeof(checksum<512>)), "sha512 test2" ); +} + +void test_crypto::ripemd160_no_data() { + + checksum<160> tmp; + + ripemd160( (char *)test2, my_strlen(test2), &tmp ); + eos_assert( my_memcmp((void *)test2_ok_ripe, &tmp, sizeof(checksum<160>)), "ripemd160 test2" ); } + void test_crypto::assert_sha256_false() { - checksum tmp; + checksum<256> tmp; sha256( (char *)test1, my_strlen(test1), &tmp ); tmp.hash[0] ^= (uint64_t)(-1); @@ -119,7 +328,7 @@ void test_crypto::assert_sha256_false() { void test_crypto::assert_sha256_true() { - checksum tmp; + checksum<256> tmp; sha256( (char *)test1, my_strlen(test1), &tmp ); eos_assert_sha256( (char *)test1, my_strlen(test1), &tmp); @@ -133,3 +342,90 @@ void test_crypto::assert_sha256_true() { sha256( (char *)test5, my_strlen(test5), &tmp ); eos_assert_sha256( (char *)test5, my_strlen(test5), &tmp); } + +void test_crypto::assert_sha1_false() { + + checksum<160> tmp; + + sha1( (char *)test1, my_strlen(test1), &tmp ); + tmp.hash[0] ^= (uint64_t)(-1); + eos_assert_sha1( (char *)test1, my_strlen(test1), &tmp); + + eos_assert(false, "should have failed"); +} + + +void test_crypto::assert_sha1_true() { + + checksum<160> tmp; + + sha1( (char *)test1, my_strlen(test1), &tmp ); + eos_assert_sha1( (char *)test1, my_strlen(test1), &tmp); + + sha1( (char *)test3, my_strlen(test3), &tmp ); + eos_assert_sha1( (char *)test3, my_strlen(test3), &tmp); + + sha1( (char *)test4, my_strlen(test4), &tmp ); + eos_assert_sha1( (char *)test4, my_strlen(test4), &tmp); + + sha1( (char *)test5, my_strlen(test5), &tmp ); + eos_assert_sha1( (char *)test5, my_strlen(test5), &tmp); +} + +void test_crypto::assert_sha512_false() { + + checksum<512> tmp; + + sha512( (char *)test1, my_strlen(test1), &tmp ); + tmp.hash[0] ^= (uint64_t)(-1); + eos_assert_sha512( (char *)test1, my_strlen(test1), &tmp); + + eos_assert(false, "should have failed"); +} + + +void test_crypto::assert_sha512_true() { + + checksum<512> tmp; + + sha512( (char *)test1, my_strlen(test1), &tmp ); + eos_assert_sha512( (char *)test1, my_strlen(test1), &tmp); + + sha512( (char *)test3, my_strlen(test3), &tmp ); + eos_assert_sha512( (char *)test3, my_strlen(test3), &tmp); + + sha512( (char *)test4, my_strlen(test4), &tmp ); + eos_assert_sha512( (char *)test4, my_strlen(test4), &tmp); + + sha512( (char *)test5, my_strlen(test5), &tmp ); + eos_assert_sha512( (char *)test5, my_strlen(test5), &tmp); +} + +void test_crypto::assert_ripemd160_false() { + + checksum<160> tmp; + + ripemd160( (char *)test1, my_strlen(test1), &tmp ); + tmp.hash[0] ^= (uint64_t)(-1); + eos_assert_ripemd160( (char *)test1, my_strlen(test1), &tmp); + + eos_assert(false, "should have failed"); +} + + +void test_crypto::assert_ripemd160_true() { + + checksum<160> tmp; + + ripemd160( (char *)test1, my_strlen(test1), &tmp ); + eos_assert_ripemd160( (char *)test1, my_strlen(test1), &tmp); + + ripemd160( (char *)test3, my_strlen(test3), &tmp ); + eos_assert_ripemd160( (char *)test3, my_strlen(test3), &tmp); + + ripemd160( (char *)test4, my_strlen(test4), &tmp ); + eos_assert_ripemd160( (char *)test4, my_strlen(test4), &tmp); + + ripemd160( (char *)test5, my_strlen(test5), &tmp ); + eos_assert_ripemd160( (char *)test5, my_strlen(test5), &tmp); +} diff --git a/contracts/test_api/test_transaction.cpp b/contracts/test_api/test_transaction.cpp index 67521c630..b23fea1fe 100644 --- a/contracts/test_api/test_transaction.cpp +++ b/contracts/test_api/test_transaction.cpp @@ -136,12 +136,12 @@ void test_transaction::test_tapos_block_num() { void test_transaction::test_read_transaction() { - checksum h; + checksum<256> h; transaction t; char* p = (char*)&t; uint64_t read = read_transaction( (char*)&t, sizeof(t) ); sha256(p, read, &h); - eosio::print_f( "%%%%", h.hash[0], h.hash[1], h.hash[2], h.hash[3] ); + printhex( &h, sizeof(h) ); } void test_transaction::test_transaction_size() { diff --git a/libraries/chain/wasm_interface.cpp b/libraries/chain/wasm_interface.cpp index 07deebd04..6af1a5134 100644 --- a/libraries/chain/wasm_interface.cpp +++ b/libraries/chain/wasm_interface.cpp @@ -591,6 +591,22 @@ class crypto_api : public context_aware_api { FC_ASSERT( result == hash_val, "hash miss match" ); } + void eos_assert_sha1(array_ptr data, size_t datalen, const fc::sha1& hash_val) { + auto result = fc::sha1::hash( data, datalen ); + FC_ASSERT( result == hash_val, "hash miss match" ); + } + + void eos_assert_sha512(array_ptr data, size_t datalen, const fc::sha512& hash_val) { + auto result = fc::sha512::hash( data, datalen ); + FC_ASSERT( result == hash_val, "hash miss match" ); + } + + void eos_assert_ripemd160(array_ptr data, size_t datalen, const fc::ripemd160& hash_val) { + auto result = fc::ripemd160::hash( data, datalen ); + FC_ASSERT( result == hash_val, "hash miss match" ); + } + + void sha1(array_ptr data, size_t datalen, fc::sha1& hash_val) { hash_val = fc::sha1::hash( data, datalen ); } @@ -1343,6 +1359,9 @@ REGISTER_INTRINSICS(crypto_api, (assert_recover_key, void(int, int, int, int, int)) (recover_key, int(int, int, int, int, int)) (eos_assert_sha256, void(int, int, int)) + (eos_assert_sha1, void(int, int, int)) + (eos_assert_sha512, void(int, int, int)) + (eos_assert_ripemd160, void(int, int, int)) (sha1, void(int, int, int)) (sha256, void(int, int, int)) (sha512, void(int, int, int)) diff --git a/tests/api_tests/api_tests.cpp b/tests/api_tests/api_tests.cpp index c9d730ebe..1b7a46732 100644 --- a/tests/api_tests/api_tests.cpp +++ b/tests/api_tests/api_tests.cpp @@ -27,6 +27,7 @@ //#include #include +#include #include #include @@ -64,6 +65,8 @@ struct test_api_action { } }; +public_key_type CALL_TEST_FUNC_PUB_KEY; + FC_REFLECT_TEMPLATE((uint64_t T), test_api_action, BOOST_PP_SEQ_NIL); @@ -128,7 +131,9 @@ void CallFunction(tester& test, T ac, const vector& data, const vector keys = trx.get_signature_keys(chain_id_type() ); + CALL_TEST_FUNC_PUB_KEY = *(keys.begin()); auto res = test.push_transaction(trx); BOOST_CHECK_EQUAL(res.status, transaction_receipt::executed); test.produce_block(); @@ -499,7 +504,8 @@ BOOST_FIXTURE_TEST_CASE(transaction_tests, tester) { try { // this is a bit rough, but I couldn't figure out a better way to compare the hashes CAPTURE( cerr, CALL_TEST_FUNCTION( *this, "test_transaction", "test_read_transaction", {} ) ); BOOST_CHECK_EQUAL( capture.size(), 7 ); - BOOST_CHECK_EQUAL(capture[3] == string("397038167369840490149603063590195796751189838240299566290311734324271874205372"), true); + string sha_expect = "6af759101c9082051b2961d45eaf9dcf37b05054c18b1fa5bc664e10c1b1d8a200"; + BOOST_CHECK_EQUAL(capture[3] == sha_expect, true); CALL_TEST_FUNCTION(*this, "test_transaction", "test_tapos_block_num", fc::raw::pack(control->head_block_num()) ); CALL_TEST_FUNCTION(*this, "test_transaction", "test_tapos_block_prefix", fc::raw::pack(control->head_block_id()._hash[1]) ); @@ -626,10 +632,35 @@ BOOST_FIXTURE_TEST_CASE(crypto_tests, tester) { try { produce_blocks(1000); set_code(N(testapi), test_api_wast); produce_blocks(1000); + { + signed_transaction trx; + + auto pl = vector{{N(testapi), config::active_name}}; + + action act(pl, test_api_action{}); + auto signatures = trx.sign(get_private_key(N(testapi), "active"), chain_id_type()); + + produce_block(); + + std::vector payload = fc::raw::pack( signatures ); + auto act_hash = fc::sha256::hash( (char*)&act, sizeof(act)); + auto pk = get_public_key(N(testapi), "active"); + + auto pk_ = fc::crypto::public_key(signatures, act_hash, false); + BOOST_TEST_MESSAGE( "PUB " << fc::to_hex((char*)&pk, sizeof(pk)) << "\n"); + BOOST_TEST_MESSAGE( "PUB " << fc::to_hex((char*)&pk_, sizeof(pk_)) << "\n"); + CALL_TEST_FUNCTION( *this, "test_crypto", "test_recover_key", payload); + } + + CALL_TEST_FUNCTION( *this, "test_crypto", "test_sha1", {} ); CALL_TEST_FUNCTION( *this, "test_crypto", "test_sha256", {} ); + CALL_TEST_FUNCTION( *this, "test_crypto", "test_sha512", {} ); + CALL_TEST_FUNCTION( *this, "test_crypto", "test_ripemd160", {} ); + CALL_TEST_FUNCTION( *this, "test_crypto", "sha1_no_data", {} ); CALL_TEST_FUNCTION( *this, "test_crypto", "sha256_no_data", {} ); - CALL_TEST_FUNCTION( *this, "test_crypto", "test_recover_key", {} ); + CALL_TEST_FUNCTION( *this, "test_crypto", "sha512_no_data", {} ); + CALL_TEST_FUNCTION( *this, "test_crypto", "ripemd160_no_data", {} ); // TODO need a way to represent nullptr #if 0 @@ -648,6 +679,38 @@ BOOST_FIXTURE_TEST_CASE(crypto_tests, tester) { try { CALL_TEST_FUNCTION( *this, "test_crypto", "assert_sha256_true", {} ); + BOOST_CHECK_EXCEPTION(CALL_TEST_FUNCTION( *this, "test_crypto", "assert_sha1_false", {} ), fc::assert_exception, + [](const fc::assert_exception& e) { + return expect_assert_message(e, "hash miss match"); + } + ); + + CALL_TEST_FUNCTION( *this, "test_crypto", "assert_sha1_true", {} ); + + BOOST_CHECK_EXCEPTION(CALL_TEST_FUNCTION( *this, "test_crypto", "assert_sha1_false", {} ), fc::assert_exception, + [](const fc::assert_exception& e) { + return expect_assert_message(e, "hash miss match"); + } + ); + + CALL_TEST_FUNCTION( *this, "test_crypto", "assert_sha1_true", {} ); + + BOOST_CHECK_EXCEPTION(CALL_TEST_FUNCTION( *this, "test_crypto", "assert_sha512_false", {} ), fc::assert_exception, + [](const fc::assert_exception& e) { + return expect_assert_message(e, "hash miss match"); + } + ); + + CALL_TEST_FUNCTION( *this, "test_crypto", "assert_sha512_true", {} ); + + BOOST_CHECK_EXCEPTION(CALL_TEST_FUNCTION( *this, "test_crypto", "assert_ripemd160_false", {} ), fc::assert_exception, + [](const fc::assert_exception& e) { + return expect_assert_message(e, "hash miss match"); + } + ); + + CALL_TEST_FUNCTION( *this, "test_crypto", "assert_ripemd160_true", {} ); + } FC_LOG_AND_RETHROW() } -- GitLab