From e97b5856591958dfd39edbaa1a76970e46a84d8d Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 2 Aug 2024 12:00:35 +0200 Subject: [PATCH] crypto: eth_secret_key_to_public_key() implemented, other useful stuff for eth sig added --- src/crypto/crypto-sugar.h | 10 +++++++++ src/crypto/eth_signature.cpp | 41 ++++++++++++++++++++++++++++++++++-- src/crypto/eth_signature.h | 27 ++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/crypto/crypto-sugar.h b/src/crypto/crypto-sugar.h index 846e4572..3738d118 100644 --- a/src/crypto/crypto-sugar.h +++ b/src/crypto/crypto-sugar.h @@ -8,6 +8,7 @@ #include #include #include "crypto.h" +#include "eth_signature.h" namespace crypto { @@ -1209,6 +1210,15 @@ namespace crypto m_elements.emplace_back(pk); } + void add_eth_pub_key(const crypto::eth_public_key& epk) + { + static_assert(sizeof epk.data == 33, "unexpected size of eth_public_key"); + m_elements.emplace_back(c_scalar_0); + m_elements.emplace_back(c_scalar_0); + char* p = m_elements[m_elements.size() - 2].c; // pointer to the first of the two added items + memcpy_s(p, 2 * sizeof(item_t), &epk.data, sizeof epk.data); + } + void add_key_image(const crypto::key_image& ki) { m_elements.emplace_back(ki); diff --git a/src/crypto/eth_signature.cpp b/src/crypto/eth_signature.cpp index 3aaec568..0e33c47f 100644 --- a/src/crypto/eth_signature.cpp +++ b/src/crypto/eth_signature.cpp @@ -6,6 +6,7 @@ #include "bitcoin-secp256k1/include/secp256k1.h" #include "random.h" #include "misc_language.h" +#include namespace crypto @@ -50,6 +51,32 @@ namespace crypto } } + bool eth_secret_key_to_public_key(const eth_secret_key& sec_key, eth_public_key& pub_key) noexcept + { + try + { + // TODO: do we need this? consider using static context + secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + auto slh = epee::misc_utils::create_scope_leave_handler([&ctx](){ + secp256k1_context_destroy(ctx); + ctx = nullptr; + }); + + secp256k1_pubkey uncompressed_pub_key{}; + if (!secp256k1_ec_pubkey_create(ctx, &uncompressed_pub_key, sec_key.data)) + return false; + + size_t output_len = sizeof pub_key; + if (!secp256k1_ec_pubkey_serialize(ctx, pub_key.data, &output_len, &uncompressed_pub_key, SECP256K1_EC_COMPRESSED)) + return false; + + return true; + } + catch(...) + { + return false; + } + } // generates secp256k1 ECDSA signature bool generate_eth_signature(const hash& m, const eth_secret_key& sec_key, eth_signature& sig) noexcept @@ -91,8 +118,8 @@ namespace crypto secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); auto slh = epee::misc_utils::create_scope_leave_handler([&ctx](){ - secp256k1_context_destroy(ctx); - ctx = nullptr; + secp256k1_context_destroy(ctx); + ctx = nullptr; }); uint8_t randomness[32]; @@ -121,5 +148,15 @@ namespace crypto } } + std::ostream& operator<<(std::ostream& o, const eth_secret_key& v) + { + return o << epee::string_tools::pod_to_hex(v); + } + + std::ostream& operator<<(std::ostream& o, const eth_public_key& v) + { + return o << epee::string_tools::pod_to_hex(v); + } + } // namespace crypto diff --git a/src/crypto/eth_signature.h b/src/crypto/eth_signature.h index c0434525..b186114a 100644 --- a/src/crypto/eth_signature.h +++ b/src/crypto/eth_signature.h @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #pragma once #include +#include #include "hash.h" namespace crypto @@ -29,6 +30,9 @@ namespace crypto // generates secp256k1 keypair bool generate_eth_key_pair(eth_secret_key& sec_key, eth_public_key& pub_key) noexcept; + // converts eth_secret_key to eth_public_key + bool eth_secret_key_to_public_key(const eth_secret_key& sec_key, eth_public_key& pub_key) noexcept; + // generates secp256k1 ECDSA signature bool generate_eth_signature(const hash& m, const eth_secret_key& sec_key, eth_signature& sig) noexcept; @@ -36,4 +40,27 @@ namespace crypto bool verify_eth_signature(const hash& m, const eth_public_key& pub_key, const eth_signature& sig) noexcept; + inline bool operator==(const eth_public_key& lhs, const eth_public_key& rhs) + { + return memcmp(lhs.data, rhs.data, sizeof lhs.data) == 0; + } + + inline bool operator!=(const eth_public_key& lhs, const eth_public_key& rhs) + { + return !(lhs == rhs); + } + + inline bool operator==(const eth_secret_key& lhs, const eth_secret_key& rhs) + { + return memcmp(lhs.data, rhs.data, sizeof lhs.data) == 0; + } + + inline bool operator!=(const eth_secret_key& lhs, const eth_secret_key& rhs) + { + return !(lhs == rhs); + } + + std::ostream& operator<<(std::ostream& o, const eth_secret_key& v); + std::ostream& operator<<(std::ostream& o, const eth_public_key& v); + } // namespace crypto