11 #include <boost/assert.hpp> 25 #include "scale/scale.hpp" 28 template <
typename... Args>
30 auto msg = fmt::format(fmt_args...);
32 throw std::runtime_error(msg);
38 const auto *p =
reinterpret_cast<const char *
>(&key_type);
39 std::string key_type_str(p, p +
sizeof(key_type));
41 log->warn(
"key type <ascii: {}, hex: {:08x}> is not officially supported",
50 namespace sr25519_constants = crypto::constants::sr25519;
51 namespace ed25519_constants = crypto::constants::ed25519;
52 namespace ecdsa_constants = crypto::constants::ecdsa;
53 namespace secp256k1 = crypto::secp256k1;
64 std::shared_ptr<const runtime::MemoryProvider> memory_provider,
65 std::shared_ptr<const crypto::Sr25519Provider> sr25519_provider,
66 std::shared_ptr<const crypto::EcdsaProvider> ecdsa_provider,
67 std::shared_ptr<const crypto::Ed25519Provider> ed25519_provider,
68 std::shared_ptr<const crypto::Secp256k1Provider> secp256k1_provider,
69 std::shared_ptr<const crypto::Hasher> hasher,
70 std::shared_ptr<crypto::CryptoStore> crypto_store,
71 std::shared_ptr<const crypto::Bip39Provider> bip39_provider)
72 : memory_provider_(
std::move(memory_provider)),
73 sr25519_provider_(
std::move(sr25519_provider)),
74 ecdsa_provider_(
std::move(ecdsa_provider)),
75 ed25519_provider_(
std::move(ed25519_provider)),
76 secp256k1_provider_(
std::move(secp256k1_provider)),
77 hasher_(
std::move(hasher)),
78 crypto_store_(
std::move(crypto_store)),
79 bip39_provider_(
std::move(bip39_provider)),
86 BOOST_ASSERT(
hasher_ !=
nullptr);
89 BOOST_ASSERT(
logger_ !=
nullptr);
98 auto hash =
hasher_->keccak_256(buf);
109 auto hash =
hasher_->sha2_256(buf);
119 auto hash =
hasher_->blake2b_128(buf);
129 auto hash =
hasher_->blake2b_256(buf);
139 auto hash =
hasher_->twox_64(buf);
149 auto hash =
hasher_->twox_128(buf);
159 auto hash =
hasher_->twox_256(buf);
177 using ResultType = std::vector<crypto::Ed25519PublicKey>;
178 static const auto error_result(scale::encode(ResultType{}).value());
182 checkIfKeyIsSupported(key_type_id,
logger_);
184 auto public_keys =
crypto_store_->getEd25519PublicKeys(key_type_id);
185 if (not public_keys) {
187 "error loading public keys: {}",
188 public_keys.error().message());
190 common::Buffer buffer{scale::encode(public_keys.value()).value()};
202 SL_DEBUG(
logger_,
"failed to unhex seed, try parse mnemonic");
208 logger_,
"failed to parse mnemonic {}", mnemonic.error().message());
211 auto &&entropy =
bip39_provider_->calculateEntropy(mnemonic.value().words);
214 logger_,
"failed to calculate entropy {}", entropy.error().message());
221 logger_,
"failed to generate seed {}", big_seed.error().message());
224 auto big_span = gsl::span<uint8_t>(big_seed.value());
230 BOOST_UNREACHABLE_RETURN({});
239 checkIfKeyIsSupported(key_type_id,
logger_);
243 auto seed_res = scale::decode<std::optional<std::string>>(seed_buffer);
245 throw_with_error(
logger_,
"failed to decode seed");
247 auto &&seed_opt = seed_res.value();
249 outcome::result<crypto::Ed25519Keypair> kp_res{{}};
250 if (seed_opt.has_value()) {
252 crypto_store_->generateEd25519Keypair(key_type_id, seed_opt.value());
254 kp_res =
crypto_store_->generateEd25519KeypairOnDisk(key_type_id);
258 "failed to generate ed25519 key pair: {}",
259 kp_res.error().message());
261 auto &key_pair = kp_res.value();
264 return res_span.combine();
271 using ResultType = std::optional<crypto::Ed25519Signature>;
275 checkIfKeyIsSupported(key_type_id,
logger_);
281 auto pk = crypto::Ed25519PublicKey::fromSpan(public_buffer);
283 BOOST_UNREACHABLE_RETURN({});
285 auto key_pair =
crypto_store_->findEd25519Keypair(key_type_id, pk.value());
287 logger_->error(
"failed to find required key");
288 auto error_result = scale::encode(ResultType(std::nullopt)).value();
295 "failed to sign message, error = {}",
296 sign.error().message());
299 logger_, sign.value(), key_pair.value().public_key, msg_buffer);
300 auto buffer = scale::encode(ResultType(sign.value())).value();
313 auto signature_res = crypto::Ed25519Signature::fromSpan(sig_bytes);
314 if (!signature_res) {
317 auto &&signature = signature_res.value();
322 auto pubkey_res = crypto::Ed25519PublicKey::fromSpan(pubkey_bytes);
326 auto pubkey = pubkey_res.value();
338 using ResultType = std::vector<crypto::Sr25519PublicKey>;
339 static const auto error_result(scale::encode(ResultType{}).value());
343 checkIfKeyIsSupported(key_type_id,
logger_);
345 auto public_keys =
crypto_store_->getSr25519PublicKeys(key_type_id);
346 if (not public_keys) {
348 "error loading public keys: {}",
349 public_keys.error().message());
352 auto buffer = scale::encode(public_keys.value()).value();
362 checkIfKeyIsSupported(key_type_id,
logger_);
366 auto seed_res = scale::decode<std::optional<std::string>>(seed_buffer);
368 throw_with_error(
logger_,
"failed to decode seed");
371 outcome::result<crypto::Sr25519Keypair> kp_res{{}};
372 auto bip39_seed = seed_res.value();
373 if (bip39_seed.has_value()) {
377 kp_res =
crypto_store_->generateSr25519KeypairOnDisk(key_type_id);
381 "failed to generate sr25519 key pair: {}",
382 kp_res.error().message());
384 auto &key_pair = kp_res.value();
398 using ResultType = std::optional<crypto::Sr25519Signature>;
399 static const auto error_result =
400 scale::encode(ResultType(std::nullopt)).value();
404 checkIfKeyIsSupported(key_type_id,
logger_);
410 auto pk = crypto::Sr25519PublicKey::fromSpan(public_buffer);
413 BOOST_UNREACHABLE_RETURN({});
415 auto key_pair =
crypto_store_->findSr25519Keypair(key_type_id, pk.value());
417 logger_->error(
"failed to find required key: {}",
418 key_pair.error().message());
425 "failed to sign message, error = {}",
426 sign.error().message());
429 logger_, sign.value(), key_pair.value().public_key, msg_buffer);
430 auto buffer = scale::encode(ResultType(sign.value())).value();
442 auto signature_buffer =
447 auto key_res = crypto::Sr25519PublicKey::fromSpan(pubkey_buffer);
451 auto &&key = key_res.value();
453 crypto::Sr25519Signature signature{};
454 std::copy_n(signature_buffer.begin(),
471 "delegated to ext_crypto_sr25519_verify_version_1");
476 template <
typename T>
478 decltype(outcome::result<std::decay_t<T>>(T{}).as_failure());
487 const outcome::result<void> res = failure;
488 if (res == outcome::failure(Secp256k1ProviderError::INVALID_V_VALUE)) {
492 == outcome::failure(Secp256k1ProviderError::INVALID_R_OR_S_VALUE)) {
504 boost::variant<secp256k1::PublicKey, Secp256k1VerifyError>;
506 constexpr
auto signature_size = RSVSignature::size();
507 constexpr
auto message_size = MessageHash::size();
512 auto signature = RSVSignature::fromSpan(sig_buffer).value();
513 auto message = MessageHash::fromSpan(msg_buffer).value();
518 logger_->error(
"failed to recover uncompressed secp256k1 public key: {}",
519 public_key.error().message());
522 convertFailureToError<UncompressedPublicKey>(public_key.as_failure());
524 scale::encode(static_cast<ResultType>(error_code)).value();
533 auto truncated_span = gsl::span<uint8_t>(public_key.value()).subspan(1, 64);
534 auto truncated_public_key =
535 secp256k1::PublicKey::fromSpan(truncated_span).value();
537 auto buffer = scale::encode(ResultType(truncated_public_key)).value();
545 boost::variant<CompressedPublicKey, Secp256k1VerifyError>;
547 constexpr
auto signature_size = RSVSignature::size();
548 constexpr
auto message_size = MessageHash::size();
553 auto signature = RSVSignature::fromSpan(sig_buffer).value();
554 auto message = MessageHash::fromSpan(msg_buffer).value();
559 logger_->error(
"failed to recover uncompressed secp256k1 public key: {}",
560 public_key.error().message());
563 convertFailureToError<CompressedPublicKey>(public_key.as_failure());
565 scale::encode(static_cast<ResultType>(error_code)).value();
569 auto buffer = scale::encode(ResultType(public_key.value())).value();
575 using ResultType = std::vector<crypto::EcdsaPublicKey>;
576 static const auto error_result(scale::encode(ResultType{}).value());
580 checkIfKeyIsSupported(key_type_id,
logger_);
582 auto public_keys =
crypto_store_->getEcdsaPublicKeys(key_type_id);
583 if (not public_keys) {
585 "error loading public keys: {}",
586 public_keys.error().message());
589 auto buffer = scale::encode(public_keys.value()).value();
599 using ResultType = std::optional<crypto::EcdsaSignature>;
603 checkIfKeyIsSupported(key_type_id,
logger_);
605 auto public_buffer =
getMemory().
loadN(key,
sizeof(crypto::EcdsaPublicKey));
609 crypto::EcdsaPublicKey pk;
610 std::copy(public_buffer.begin(), public_buffer.end(), pk.begin());
611 auto key_pair =
crypto_store_->findEcdsaKeypair(key_type_id, pk);
613 logger_->error(
"failed to find required key");
614 auto error_result = scale::encode(ResultType(std::nullopt)).value();
618 auto sign =
ecdsa_provider_->sign(msg_buffer, key_pair.value().secret_key);
621 "failed to sign message, error = {}",
622 sign.error().message());
625 logger_, sign.value(), key_pair.value().public_key, msg_buffer);
626 auto buffer = scale::encode(ResultType(sign.value())).value();
634 using ResultType = std::optional<crypto::EcdsaSignature>;
638 checkIfKeyIsSupported(key_type_id,
logger_);
640 auto public_buffer =
getMemory().
loadN(key,
sizeof(crypto::EcdsaPublicKey));
644 crypto::EcdsaPublicKey pk;
645 std::copy(public_buffer.begin(), public_buffer.end(), pk.begin());
646 auto key_pair =
crypto_store_->findEcdsaKeypair(key_type_id, pk);
648 logger_->error(
"failed to find required key");
649 auto error_result = scale::encode(ResultType(std::nullopt)).value();
654 std::copy(msg_buffer.begin(), msg_buffer.end(), digest.begin());
659 "failed to sign message, error = {}",
660 sign.error().message());
663 logger_, sign.value(), key_pair.value().public_key, msg_buffer);
664 auto buffer = scale::encode(ResultType(sign.value())).value();
672 checkIfKeyIsSupported(key_type_id,
logger_);
676 auto seed_res = scale::decode<std::optional<std::string>>(seed_buffer);
678 throw_with_error(
logger_,
"failed to decode seed");
681 outcome::result<crypto::EcdsaKeypair> kp_res{{}};
682 auto bip39_seed = seed_res.value();
683 if (bip39_seed.has_value()) {
685 crypto_store_->generateEcdsaKeypair(key_type_id, bip39_seed.value());
687 kp_res =
crypto_store_->generateEcdsaKeypairOnDisk(key_type_id);
691 "failed to generate ecdsa key pair: {}",
692 kp_res.error().message());
694 auto &key_pair = kp_res.value();
715 auto key_res = crypto::EcdsaPublicKey::fromSpan(pubkey_buffer);
719 auto &&pubkey = key_res.value();
740 auto key_res = crypto::EcdsaPublicKey::fromSpan(pubkey_buffer);
744 auto &&pubkey = key_res.value();
747 std::copy(msg.begin(), msg.end(), digest.begin());
int32_t ext_crypto_ecdsa_verify_version_1(runtime::WasmPointer sig, runtime::WasmSpan msg, runtime::WasmPointer key) const
static constexpr uint32_t kVerifySuccess
common::Blob< 32 > deriveSeed(std::string_view content)
Class represents arbitrary (including empty) byte buffer.
int32_t ext_crypto_sr25519_verify_version_2(runtime::WasmPointer sig, runtime::WasmSpan msg, runtime::WasmPointer pubkey_data)
CryptoExtension(std::shared_ptr< const runtime::MemoryProvider > memory_provider, std::shared_ptr< const crypto::Sr25519Provider > sr25519_provider, std::shared_ptr< const crypto::EcdsaProvider > ecdsa_provider, std::shared_ptr< const crypto::Ed25519Provider > ed25519_provider, std::shared_ptr< const crypto::Secp256k1Provider > secp256k1_provider, std::shared_ptr< const crypto::Hasher > hasher, std::shared_ptr< crypto::CryptoStore > crypto_store, std::shared_ptr< const crypto::Bip39Provider > bip39_provider)
runtime::WasmPointer ext_crypto_ed25519_generate_version_1(runtime::WasmSize key_type, runtime::WasmSpan seed)
uint32_t WasmSize
Size type is uint32_t because we are working in 32 bit address space.
std::shared_ptr< const crypto::Ed25519Provider > ed25519_provider_
WasmPointer ptr
address of buffer
runtime::WasmPointer ext_crypto_sr25519_generate_version_1(runtime::WasmSize key_type, runtime::WasmSpan seed)
std::shared_ptr< const crypto::Secp256k1Provider > secp256k1_provider_
runtime::WasmSize ext_crypto_ed25519_verify_version_1(runtime::WasmPointer sig, runtime::WasmSpan msg, runtime::WasmPointer pubkey_data)
runtime::Memory & getMemory() const
#define SL_TRACE_FUNC_CALL(logger, ret,...)
int32_t ext_crypto_ecdsa_verify_prehashed_version_1(runtime::WasmPointer sig, runtime::WasmSpan msg, runtime::WasmPointer key) const
runtime::WasmPointer ext_hashing_blake2_128_version_1(runtime::WasmSpan data)
static constexpr uint32_t kVerifyFail
common::Blob< constants::kCompressedPublicKeySize > CompressedPublicKey
virtual common::Buffer loadN(WasmPointer addr, WasmSize n) const =0
void ext_crypto_start_batch_verify_version_1()
virtual uint32_t load32u(WasmPointer addr) const =0
runtime::WasmSpan ext_crypto_ecdsa_public_keys_version_1(runtime::WasmSize key_type)
uint8_t Secp256k1VerifyError
runtime::WasmSpan ext_crypto_secp256k1_ecdsa_recover_version_1(runtime::WasmPointer sig, runtime::WasmPointer msg)
uint32_t KeyTypeId
Key type identifier.
runtime::WasmPointer ext_hashing_keccak_256_version_1(runtime::WasmSpan data)
runtime::WasmPointer ext_hashing_twox_64_version_1(runtime::WasmSpan data)
common::Blob< constants::kUncompressedPublicKeySize > UncompressedPublicKey
runtime::WasmSpan ext_crypto_sr25519_sign_version_1(runtime::WasmSize key_type, runtime::WasmPointer key, runtime::WasmSpan msg)
std::shared_ptr< crypto::CryptoStore > crypto_store_
runtime::WasmPointer ext_crypto_ecdsa_generate_version_1(runtime::WasmSize key_type_id, runtime::WasmSpan seed) const
int32_t ext_crypto_sr25519_verify_version_1(runtime::WasmPointer sig, runtime::WasmSpan msg, runtime::WasmPointer pubkey_data)
static constexpr Secp256k1VerifyError kInvalidRS
static constexpr Secp256k1VerifyError kInvalidV
static outcome::result< Mnemonic > parse(std::string_view phrase)
parse mnemonic from phrase
common::Blob< constants::kCompactSignatureSize > RSVSignature
libp2p::crypto::ecdsa::PrehashedMessage EcdsaPrehashedMessage
runtime::WasmPointer ext_hashing_twox_128_version_1(runtime::WasmSpan data)
std::shared_ptr< soralog::Logger > Logger
runtime::WasmSpan ext_crypto_ed25519_sign_version_1(runtime::WasmSize key_type, runtime::WasmPointer key, runtime::WasmSpan msg)
static outcome::result< Blob< size_ > > fromSpan(const gsl::span< const uint8_t > &span)
runtime::WasmSize ext_crypto_finish_batch_verify_version_1()
uint64_t WasmSpan
combination of pointer and size, where less significant part represents wasm pointer, and most significant represents size
runtime::WasmSpan ext_crypto_sr25519_public_keys_version_1(runtime::WasmSize key_type)
static constexpr uint32_t kVerifyBatchSuccess
std::shared_ptr< const crypto::Sr25519Provider > sr25519_provider_
uint32_t WasmPointer
type of wasm memory is 32 bit integer
std::shared_ptr< const crypto::Bip39Provider > bip39_provider_
runtime::WasmPointer ext_hashing_twox_256_version_1(runtime::WasmSpan data)
runtime::WasmSpan ext_crypto_ecdsa_sign_version_1(runtime::WasmSize key_type, runtime::WasmPointer key, runtime::WasmSpan msg)
static constexpr size_t size()
std::string encodeKeyTypeIdToStr(KeyTypeId key_type_id)
makes string representation of KeyTypeId
runtime::WasmSpan ext_crypto_secp256k1_ecdsa_recover_compressed_version_1(runtime::WasmPointer sig, runtime::WasmPointer msg)
runtime::WasmSpan ext_crypto_ed25519_public_keys_version_1(runtime::WasmSize key_type)
virtual void storeBuffer(WasmPointer addr, gsl::span< const uint8_t > value)=0
runtime::WasmPointer ext_hashing_blake2_256_version_1(runtime::WasmSpan data)
common::Hash256 MessageHash
Logger createLogger(const std::string &tag)
bool isSupportedKeyType(KeyTypeId k)
checks whether key type value is supported
std::shared_ptr< const crypto::EcdsaProvider > ecdsa_provider_
static constexpr Secp256k1VerifyError kInvalidSignature
runtime::WasmPointer ext_hashing_sha2_256_version_1(runtime::WasmSpan data)
runtime::WasmSpan ext_crypto_ecdsa_sign_prehashed_version_1(runtime::WasmSize key_type, runtime::WasmPointer key, runtime::WasmSpan msg)
std::shared_ptr< const runtime::MemoryProvider > memory_provider_
std::vector< uint8_t > toVector()&
std::shared_ptr< const crypto::Hasher > hasher_