From 585cea94725f8303d927b59f46cb27058e433207 Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Fri, 30 Sep 2016 15:44:34 -0400 Subject: [PATCH] sha256: Add inverse log and testing --- include/fc/crypto/sha256.hpp | 2 ++ src/crypto/sha256.cpp | 27 +++++++++++++++++ tests/crypto/log_test.cpp | 58 ++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/include/fc/crypto/sha256.hpp b/include/fc/crypto/sha256.hpp index 2af8a00..a390c4f 100644 --- a/include/fc/crypto/sha256.hpp +++ b/include/fc/crypto/sha256.hpp @@ -92,6 +92,8 @@ class sha256 */ uint32_t approx_log_32()const; + void set_to_inverse_approx_log_32( uint32_t x ); + uint64_t _hash[4]; }; diff --git a/src/crypto/sha256.cpp b/src/crypto/sha256.cpp index 86bd014..73b66fd 100644 --- a/src/crypto/sha256.cpp +++ b/src/crypto/sha256.cpp @@ -123,6 +123,33 @@ namespace fc { return y; } + void sha256::set_to_inverse_approx_log_32( uint32_t x ) + { + uint8_t nzbits = uint8_t( x >> 0x18 ); + _hash[0] = 0; + _hash[1] = 0; + _hash[2] = 0; + _hash[3] = 0; + if( nzbits == 0 ) + return; + uint8_t x0 = uint8_t((x ) & 0xFF); + uint8_t x1 = uint8_t((x >> 0x08) & 0xFF); + uint8_t x2 = uint8_t((x >> 0x10) & 0xFF); + uint8_t* my_bytes = (uint8_t*) data(); + my_bytes[0x1F] = x0; + my_bytes[0x1E] = x1; + my_bytes[0x1D] = x2; + my_bytes[0x1C] = 1; + + if( nzbits <= 0x18 ) + { + (*this) = (*this) >> (0x18 - nzbits); + } + else + (*this) = (*this) << (nzbits - 0x18); + return; + } + uint16_t sha256::clz()const { const uint8_t* my_bytes = (uint8_t*) data(); diff --git a/tests/crypto/log_test.cpp b/tests/crypto/log_test.cpp index ca9621b..fcd67de 100644 --- a/tests/crypto/log_test.cpp +++ b/tests/crypto/log_test.cpp @@ -3,8 +3,30 @@ #include #include +#include #include +uint64_t endian_reverse( uint64_t x ) +{ + uint64_t x0 = ((x ) & 0xFF); + uint64_t x1 = ((x >> 0x08) & 0xFF); + uint64_t x2 = ((x >> 0x10) & 0xFF); + uint64_t x3 = ((x >> 0x18) & 0xFF); + uint64_t x4 = ((x >> 0x20) & 0xFF); + uint64_t x5 = ((x >> 0x28) & 0xFF); + uint64_t x6 = ((x >> 0x30) & 0xFF); + uint64_t x7 = ((x >> 0x38) & 0xFF); + + return (x0 << 0x38) + | (x1 << 0x30) + | (x2 << 0x28) + | (x3 << 0x20) + | (x4 << 0x18) + | (x5 << 0x10) + | (x6 << 0x08) + | (x7 ); +} + int main(int argc, char**argv, char** envp) { std::ifstream infile("log_test.txt"); @@ -33,6 +55,42 @@ int main(int argc, char**argv, char** envp) std::cerr << "got error on log(" << str_h << ")" << std::endl; ++errors; } + h.set_to_inverse_approx_log_32( ref_log ); + if( ref_log != h.approx_log_32() ) + { + std::cerr << "got error on ilog(" << ref_log << ")" << std::endl; + ++errors; + } + if( h != fc::sha256() ) + { + fc::sha256 h_before = h; + if( h._hash[3] == 0 ) + { + if( h._hash[2] == 0 ) + { + if( h._hash[1] == 0 ) + { + h._hash[0] = endian_reverse( endian_reverse( h._hash[0] )-1 ); + } + h._hash[1] = endian_reverse( endian_reverse( h._hash[1] )-1 ); + } + h._hash[2] = endian_reverse( endian_reverse( h._hash[2] )-1 ); + } + h._hash[3] = endian_reverse( endian_reverse( h._hash[3] )-1 ); + bool ok = (h.approx_log_32() < ref_log); + if( !ok ) + { + std::cerr << "got error on logm1 for " << ref_log << std::endl; + std::cerr << "h0:" << str_h << std::endl; + std::cerr << "h1:" << h_before.str() << std::endl; + std::cerr << "h2:" << h.str() << std::endl; + std::cerr << "ref_log:" << std::hex << std::setw(8) << ref_log << std::endl; + std::cerr << "log(h) :" << std::hex << std::setw(8) << h.approx_log_32() << std::endl; + std::cerr << std::endl; + ++errors; + } + } + ++cases; }