diff --git a/legacy/firmware/.changelog.d/1897.changed b/legacy/firmware/.changelog.d/1897.changed new file mode 100644 index 000000000..8ecb09ff3 --- /dev/null +++ b/legacy/firmware/.changelog.d/1897.changed @@ -0,0 +1 @@ +Faster ECDSA signing and verification (using secp256k1-zkp). diff --git a/legacy/firmware/ethereum.c b/legacy/firmware/ethereum.c index a11cbc0e5..437aef573 100644 --- a/legacy/firmware/ethereum.c +++ b/legacy/firmware/ethereum.c @@ -36,6 +36,9 @@ #include "sha3.h" #include "transaction.h" #include "util.h" +#ifdef USE_SECP256K1_ZKP_ECDSA +#include "zkp_ecdsa.h" +#endif /* Maximum chain_id which returns the full signature_v (which must fit into an uint32). chain_ids larger than this will only return one bit and the caller must @@ -944,8 +947,20 @@ int ethereum_message_verify(const EthereumVerifyMessage *msg) { if (v >= 27) { v -= 27; } - if (v >= 2 || ecdsa_recover_pub_from_sig( - &secp256k1, pubkey, msg->signature.bytes, hash, v) != 0) { + + if (v >= 2) { + return 2; + } + + int ret = 0; +#ifdef USE_SECP256K1_ZKP_ECDSA + ret = zkp_ecdsa_recover_pub_from_sig(&secp256k1, pubkey, msg->signature.bytes, + hash, v); +#else + ret = ecdsa_recover_pub_from_sig(&secp256k1, pubkey, msg->signature.bytes, + hash, v); +#endif + if (ret != 0) { return 2; } diff --git a/legacy/firmware/signing.c b/legacy/firmware/signing.c index 90d1ff943..13ad7b858 100644 --- a/legacy/firmware/signing.c +++ b/legacy/firmware/signing.c @@ -30,6 +30,9 @@ #include "protect.h" #include "secp256k1.h" #include "transaction.h" +#ifdef USE_SECP256K1_ZKP_ECDSA +#include "zkp_ecdsa.h" +#endif static uint32_t change_count; static const CoinInfo *coin; @@ -1767,8 +1770,17 @@ static bool signing_check_orig_tx(void) { } } - if (ecdsa_verify_digest(coin->curve->params, node.public_key, sig, hash) != - 0) { + int ret = 0; +#ifdef USE_SECP256K1_ZKP_ECDSA + if (coin->curve->params == &secp256k1) { + ret = zkp_ecdsa_verify_digest(coin->curve->params, node.public_key, sig, + hash); + } else +#endif + { + ret = ecdsa_verify_digest(coin->curve->params, node.public_key, sig, hash); + } + if (ret != 0) { fsm_sendFailure(FailureType_Failure_DataError, _("Invalid signature.")); signing_abort(); return false; @@ -1867,12 +1879,24 @@ static bool signing_sign_hash(TxInputType *txinput, const uint8_t *private_key, resp.serialized.signature_index = idx1; resp.serialized.has_signature = true; resp.serialized.has_serialized_tx = true; - if (ecdsa_sign_digest(coin->curve->params, private_key, hash, sig, NULL, - NULL) != 0) { + + int ret = 0; +#ifdef USE_SECP256K1_ZKP_ECDSA + if (coin->curve->params == &secp256k1) { + ret = zkp_ecdsa_sign_digest(coin->curve->params, private_key, hash, sig, + NULL, NULL); + } else +#endif + { + ret = ecdsa_sign_digest(coin->curve->params, private_key, hash, sig, NULL, + NULL); + } + if (ret != 0) { fsm_sendFailure(FailureType_Failure_ProcessError, _("Signing failed")); signing_abort(); return false; } + resp.serialized.signature.size = ecdsa_sig_to_der(sig, resp.serialized.signature.bytes); diff --git a/legacy/firmware/trezor.c b/legacy/firmware/trezor.c index c21902cf6..d1fe24e34 100644 --- a/legacy/firmware/trezor.c +++ b/legacy/firmware/trezor.c @@ -38,6 +38,23 @@ #include #include "otp.h" #endif +#ifdef USE_SECP256K1_ZKP +#include "zkp_context.h" +#endif + +#ifdef USE_SECP256K1_ZKP +void secp256k1_default_illegal_callback_fn(const char *str, void *data) { + (void)data; + __fatal_error(NULL, str, __FILE__, __LINE__, __func__); + return; +} + +void secp256k1_default_error_callback_fn(const char *str, void *data) { + (void)data; + __fatal_error(NULL, str, __FILE__, __LINE__, __func__); + return; +} +#endif /* Screen timeout */ uint32_t system_millis_lock_start = 0; @@ -143,6 +160,10 @@ int main(void) { collect_hw_entropy(false); } +#ifdef USE_SECP256K1_ZKP + ensure(sectrue * (zkp_context_init() == 0), NULL); +#endif + #if DEBUG_LINK oledSetDebugLink(1); #if !EMULATOR