diff --git a/src/crypto/crypto-sugar.h b/src/crypto/crypto-sugar.h index 14c168e8..4752d81b 100644 --- a/src/crypto/crypto-sugar.h +++ b/src/crypto/crypto-sugar.h @@ -88,6 +88,49 @@ namespace crypto return ss.str(); } + template + bool parse_tpod_from_hex_string(const std::string& hex_str, t_pod_type& t_pod) + { + static const int16_t char_map[256] = { // 0-9, a-f, A-F is only allowed + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x00 - 0x1F + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, // 0x20 - 0x3F + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x40 - 0x5F + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x60 - 0x7F + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x80 - 0x9F + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0xA0 - 0xBF + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0xC0 - 0xDF + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; // 0xE0 - 0xFF + + size_t pod_size = sizeof t_pod; + uint8_t *p = reinterpret_cast(&t_pod); + + if (hex_str.size() != 2 * pod_size) + return false; + + for (size_t i = 0; i < pod_size; ++i) + { + int16_t hi = char_map[static_cast(hex_str[2 * i])]; + int16_t lo = char_map[static_cast(hex_str[2 * i + 1])]; + if (hi < 0 || lo < 0) + { + // invalid characters in hex_str + memset(p, 0, pod_size); + return false; + } + p[i] = static_cast(hi * 16 + lo); // write byte to pod + } + return true; + } + + template + t_pod_type parse_tpod_from_hex_string(const std::string& hex_str) + { + t_pod_type t_pod = AUTO_VAL_INIT(t_pod); + parse_tpod_from_hex_string(hex_str, t_pod); + return t_pod; + } + + // // scalar_t - holds a 256-bit scalar, normally in [0..L-1] diff --git a/tests/functional_tests/crypto_tests.cpp b/tests/functional_tests/crypto_tests.cpp index 25ceb2ee..775e9b93 100644 --- a/tests/functional_tests/crypto_tests.cpp +++ b/tests/functional_tests/crypto_tests.cpp @@ -1385,6 +1385,20 @@ TEST(ml2s, sig_verif_performance_2) } +TEST(crypto, hex_tools) +{ + ASSERT_EQ(parse_tpod_from_hex_string("00"), 0x00); + ASSERT_EQ(parse_tpod_from_hex_string("01"), 0x01); + ASSERT_EQ(parse_tpod_from_hex_string("f1"), 0xf1); + ASSERT_EQ(parse_tpod_from_hex_string("fe"), 0xfe); + ASSERT_EQ(parse_tpod_from_hex_string("efcdab8967452301"), 0x0123456789abcdef); + ASSERT_EQ(parse_tpod_from_hex_string("0123456789abcdef"), 0xefcdab8967452301); + ASSERT_EQ(parse_tpod_from_hex_string("ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f"), c_scalar_Pm1); + ASSERT_EQ(parse_tpod_from_hex_string("792fdce229e50661d0da1c7db39dd30700000000000000000000000000000006"), c_scalar_1div8); + + return true; +} + // // test's runner //