1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-04-20 17:19:01 +00:00

refator(core,crypto): rename sign_digest() to sign_digest_recoverable()

[no changelog]
This commit is contained in:
Ondřej Vejpustek 2025-03-21 20:14:12 +01:00
parent fe777474dd
commit 547f1900c0
17 changed files with 99 additions and 82 deletions

View File

@ -932,8 +932,8 @@ optiga_result optiga_set_priv_key(uint16_t oid, const uint8_t priv_key[32]) {
sha256_Update(&context, &sop_cmd1[17], 62);
sha256_Final(&context, digest);
if (0 != ecdsa_sign_digest(&nist256p1, TA_PRIV_KEY, digest, &sop_cmd1[81],
NULL, NULL)) {
if (0 != ecdsa_sign_digest_recoverable(&nist256p1, TA_PRIV_KEY, digest,
&sop_cmd1[81], NULL, NULL)) {
memzero(sop_cmd2, sizeof(sop_cmd2));
return OPTIGA_ERR_PROCESS;
}

View File

@ -56,8 +56,8 @@ optiga_sign_result optiga_sign(uint8_t index, const uint8_t *digest,
}
uint8_t raw_signature[64] = {0};
int ret = ecdsa_sign_digest(&nist256p1, DEVICE_PRIV_KEY, digest,
raw_signature, NULL, NULL);
int ret = ecdsa_sign_digest_recoverable(&nist256p1, DEVICE_PRIV_KEY, digest,
raw_signature, NULL, NULL);
if (ret != 0) {
return OPTIGA_SIGN_ERROR;
}

View File

@ -109,9 +109,9 @@ STATIC mp_obj_t mod_trezorcrypto_nist256p1_sign_recoverable(
vstr_t sig = {0};
vstr_init_len(&sig, 65);
uint8_t pby = 0;
if (0 != ecdsa_sign_digest(&nist256p1, (const uint8_t *)sk.buf,
(const uint8_t *)dig.buf, (uint8_t *)sig.buf + 1,
&pby, NULL)) {
if (0 != ecdsa_sign_digest_recoverable(&nist256p1, (const uint8_t *)sk.buf,
(const uint8_t *)dig.buf,
(uint8_t *)sig.buf + 1, &pby, NULL)) {
vstr_clear(&sig);
mp_raise_ValueError("Signing failed");
}

View File

@ -151,9 +151,9 @@ STATIC mp_obj_t mod_trezorcrypto_secp256k1_sign_recoverable(
vstr_t sig = {0};
vstr_init_len(&sig, 65);
uint8_t pby = 0;
if (0 != ecdsa_sign_digest(&secp256k1, (const uint8_t *)sk.buf,
(const uint8_t *)dig.buf, (uint8_t *)sig.buf + 1,
&pby, is_canonical)) {
if (0 != ecdsa_sign_digest_recoverable(
&secp256k1, (const uint8_t *)sk.buf, (const uint8_t *)dig.buf,
(uint8_t *)sig.buf + 1, &pby, is_canonical)) {
vstr_clear(&sig);
mp_raise_ValueError("Signing failed");
}

View File

@ -609,8 +609,9 @@ int hdnode_sign(HDNode *node, const uint8_t *msg, uint32_t msg_len,
HasherType hasher_sign, uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64])) {
if (node->curve->params) {
return ecdsa_sign(node->curve->params, hasher_sign, node->private_key, msg,
msg_len, sig, pby, is_canonical);
return ecdsa_sign_recoverable(node->curve->params, hasher_sign,
node->private_key, msg, msg_len, sig, pby,
is_canonical);
} else if (node->curve == &curve25519_info) {
return 1; // signatures are not supported
} else {
@ -633,8 +634,8 @@ int hdnode_sign_digest(HDNode *node, const uint8_t *digest, uint8_t *sig,
uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64])) {
if (node->curve->params) {
return ecdsa_sign_digest(node->curve->params, node->private_key, digest,
sig, pby, is_canonical);
return ecdsa_sign_digest_recoverable(node->curve->params, node->private_key,
digest, sig, pby, is_canonical);
} else if (node->curve == &curve25519_info) {
return 1; // signatures are not supported
} else {

View File

@ -662,13 +662,14 @@ int tc_ecdh_multiply(const ecdsa_curve *curve, const uint8_t *priv_key,
// msg is a data to be signed
// msg_len is the message length
int ecdsa_sign(const ecdsa_curve *curve, HasherType hasher_sign,
const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len,
uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64])) {
int ecdsa_sign_recoverable(const ecdsa_curve *curve, HasherType hasher_sign,
const uint8_t *priv_key, const uint8_t *msg,
uint32_t msg_len, uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64])) {
uint8_t hash[32] = {0};
hasher_Raw(hasher_sign, msg, msg_len, hash);
int res = ecdsa_sign_digest(curve, priv_key, hash, sig, pby, is_canonical);
int res = ecdsa_sign_digest_recoverable(curve, priv_key, hash, sig, pby,
is_canonical);
memzero(hash, sizeof(hash));
return res;
}
@ -679,9 +680,10 @@ int ecdsa_sign(const ecdsa_curve *curve, HasherType hasher_sign,
// digest is 32 bytes of digest
// is_canonical is an optional function that checks if the signature
// conforms to additional coin-specific rules.
int tc_ecdsa_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key,
const uint8_t *digest, uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64])) {
int tc_ecdsa_sign_digest_recoverable(
const ecdsa_curve *curve, const uint8_t *priv_key, const uint8_t *digest,
uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64])) {
int i = 0;
curve_point R = {0};
bignum256 k = {0}, z = {0}, randk = {0};
@ -1323,16 +1325,18 @@ int ecdsa_get_public_key65(const ecdsa_curve *curve, const uint8_t *priv_key,
return tc_ecdsa_get_public_key65(curve, priv_key, pub_key);
}
int ecdsa_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key,
const uint8_t *digest, uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64])) {
int ecdsa_sign_digest_recoverable(
const ecdsa_curve *curve, const uint8_t *priv_key, const uint8_t *digest,
uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64])) {
#ifdef USE_SECP256K1_ZKP_ECDSA
if (curve == &secp256k1) {
return zkp_ecdsa_sign_digest(curve, priv_key, digest, sig, pby,
is_canonical);
return zkp_ecdsa_sign_digest_recoverable(curve, priv_key, digest, sig, pby,
is_canonical);
}
#endif
return tc_ecdsa_sign_digest(curve, priv_key, digest, sig, pby, is_canonical);
return tc_ecdsa_sign_digest_recoverable(curve, priv_key, digest, sig, pby,
is_canonical);
}
int ecdsa_verify_digest(const ecdsa_curve *curve, const uint8_t *pub_key,

View File

@ -81,13 +81,14 @@ void uncompress_coords(const ecdsa_curve *curve, uint8_t odd,
int ecdsa_uncompress_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key,
uint8_t *uncompressed);
int ecdsa_sign(const ecdsa_curve *curve, HasherType hasher_sign,
const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len,
uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64]));
int ecdsa_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key,
const uint8_t *digest, uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64]));
int ecdsa_sign_recoverable(const ecdsa_curve *curve, HasherType hasher_sign,
const uint8_t *priv_key, const uint8_t *msg,
uint32_t msg_len, uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64]));
int ecdsa_sign_digest_recoverable(
const ecdsa_curve *curve, const uint8_t *priv_key, const uint8_t *digest,
uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64]));
int ecdsa_get_public_key33(const ecdsa_curve *curve, const uint8_t *priv_key,
uint8_t *pub_key);
int ecdsa_get_public_key65(const ecdsa_curve *curve, const uint8_t *priv_key,

View File

@ -31,9 +31,10 @@ int tc_ecdsa_get_public_key33(const ecdsa_curve *curve, const uint8_t *priv_key,
uint8_t *pub_key);
int tc_ecdsa_get_public_key65(const ecdsa_curve *curve, const uint8_t *priv_key,
uint8_t *pub_key);
int tc_ecdsa_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key,
const uint8_t *digest, uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64]));
int tc_ecdsa_sign_digest_recoverable(
const ecdsa_curve *curve, const uint8_t *priv_key, const uint8_t *digest,
uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64]));
int tc_ecdsa_verify_digest(const ecdsa_curve *curve, const uint8_t *pub_key,
const uint8_t *sig, const uint8_t *digest);
int tc_ecdsa_recover_pub_from_sig(const ecdsa_curve *curve, uint8_t *pub_key,

View File

@ -736,7 +736,7 @@ int fuzz_shamir_interpolate(void) {
return 0;
}
int fuzz_ecdsa_sign_digest_functions(void) {
int fuzz_ecdsa_sign_digest_recoverable_functions(void) {
// bug result reference: https://github.com/trezor/trezor-firmware/pull/1697
uint8_t curve_decider = 0;
@ -765,12 +765,13 @@ int fuzz_ecdsa_sign_digest_functions(void) {
int res = 0;
// IDEA optionally set a function for is_canonical() callback
int res1 = tc_ecdsa_sign_digest(curve, priv_key, digest, sig1, &pby1, NULL);
int res1 = tc_ecdsa_sign_digest_recoverable(curve, priv_key, digest, sig1,
&pby1, NULL);
// the zkp function variant is only defined for a specific curve
if (curve == &secp256k1) {
int res2 =
zkp_ecdsa_sign_digest(curve, priv_key, digest, sig2, &pby2, NULL);
int res2 = zkp_ecdsa_sign_digest_recoverable(curve, priv_key, digest, sig2,
&pby2, NULL);
if ((res1 == 0 && res2 != 0) || (res1 != 0 && res2 == 0)) {
// one variant succeeded where the other did not
crash();
@ -1548,7 +1549,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
#ifdef FUZZ_ALLOW_SLOW
zkp_initialize_context_or_crash();
// slow through expensive bignum operations
target_result = fuzz_ecdsa_sign_digest_functions();
target_result = fuzz_ecdsa_sign_digest_recoverable_functions();
#endif
break;
case 24:

View File

@ -4123,10 +4123,10 @@ START_TEST(test_rfc6979) {
}
END_TEST
static void test_ecdsa_sign_digest_deterministic_helper(
int (*ecdsa_sign_digest_fn)(const ecdsa_curve *, const uint8_t *,
const uint8_t *, uint8_t *, uint8_t *,
int (*)(uint8_t by, uint8_t sig[64]))) {
static void test_ecdsa_sign_digest_deterministic_helper(int (
*ecdsa_sign_digest_recoverable_fn)(const ecdsa_curve *, const uint8_t *,
const uint8_t *, uint8_t *, uint8_t *,
int (*)(uint8_t by, uint8_t sig[64]))) {
static struct {
const char *priv_key;
const char *digest;
@ -4154,20 +4154,21 @@ static void test_ecdsa_sign_digest_deterministic_helper(
memcpy(digest, fromhex(tests[i].digest), 32);
memcpy(expected_sig, fromhex(tests[i].sig), 64);
res =
ecdsa_sign_digest_fn(curve, priv_key, digest, computed_sig, NULL, NULL);
res = ecdsa_sign_digest_recoverable_fn(curve, priv_key, digest,
computed_sig, NULL, NULL);
ck_assert_int_eq(res, 0);
ck_assert_mem_eq(expected_sig, computed_sig, 64);
}
}
START_TEST(test_tc_ecdsa_sign_digest_deterministic) {
test_ecdsa_sign_digest_deterministic_helper(tc_ecdsa_sign_digest);
START_TEST(test_tc_ecdsa_sign_digest_recoverable_deterministic) {
test_ecdsa_sign_digest_deterministic_helper(tc_ecdsa_sign_digest_recoverable);
}
END_TEST
START_TEST(test_zkp_ecdsa_sign_digest_deterministic) {
test_ecdsa_sign_digest_deterministic_helper(zkp_ecdsa_sign_digest);
START_TEST(test_zkp_ecdsa_sign_digest_recoverable_deterministic) {
test_ecdsa_sign_digest_deterministic_helper(
zkp_ecdsa_sign_digest_recoverable);
}
END_TEST
@ -11520,8 +11521,8 @@ Suite *test_suite(void) {
tcase_add_test(tc, test_zkp_ecdh_multiply);
tcase_add_test(tc, test_zkp_ecdsa_tweak_pubkey);
#if USE_RFC6979
tcase_add_test(tc, test_tc_ecdsa_sign_digest_deterministic);
tcase_add_test(tc, test_zkp_ecdsa_sign_digest_deterministic);
tcase_add_test(tc, test_tc_ecdsa_sign_digest_recoverable_deterministic);
tcase_add_test(tc, test_zkp_ecdsa_sign_digest_recoverable_deterministic);
#endif
suite_add_tcase(s, tc);

View File

@ -89,8 +89,8 @@ void openssl_check(unsigned int iterations, int nid, const ecdsa_curve *curve) {
BN_free(K);
// use our ECDSA signer to sign the message with the key
if (ecdsa_sign(curve, HASHER_SHA2, priv_key, msg, msg_len, sig, NULL,
NULL) != 0) {
if (ecdsa_sign_recoverable(curve, HASHER_SHA2, priv_key, msg, msg_len, sig,
NULL, NULL) != 0) {
printf("trezor-crypto signing failed\n");
return;
}

View File

@ -30,7 +30,8 @@ void bench_sign_secp256k1(int iterations) {
32);
for (int i = 0; i < iterations; i++) {
ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL);
ecdsa_sign_recoverable(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig,
&pby, NULL);
}
}
@ -45,7 +46,8 @@ void bench_sign_nist256p1(int iterations) {
32);
for (int i = 0; i < iterations; i++) {
ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL);
ecdsa_sign_recoverable(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig,
&pby, NULL);
}
}
@ -73,7 +75,8 @@ void bench_verify_secp256k1_33(int iterations) {
"\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5",
32);
ecdsa_get_public_key33(curve, priv, pub);
ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL);
ecdsa_sign_recoverable(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby,
NULL);
for (int i = 0; i < iterations; i++) {
ecdsa_verify(curve, HASHER_SHA2, pub, sig, msg, sizeof(msg));
@ -90,7 +93,8 @@ void bench_verify_secp256k1_65(int iterations) {
"\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5",
32);
ecdsa_get_public_key65(curve, priv, pub);
ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL);
ecdsa_sign_recoverable(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby,
NULL);
for (int i = 0; i < iterations; i++) {
ecdsa_verify(curve, HASHER_SHA2, pub, sig, msg, sizeof(msg));
@ -107,7 +111,8 @@ void bench_verify_nist256p1_33(int iterations) {
"\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5",
32);
ecdsa_get_public_key33(curve, priv, pub);
ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL);
ecdsa_sign_recoverable(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby,
NULL);
for (int i = 0; i < iterations; i++) {
ecdsa_verify(curve, HASHER_SHA2, pub, sig, msg, sizeof(msg));
@ -124,7 +129,8 @@ void bench_verify_nist256p1_65(int iterations) {
"\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5",
32);
ecdsa_get_public_key65(curve, priv, pub);
ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL);
ecdsa_sign_recoverable(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby,
NULL);
for (int i = 0; i < iterations; i++) {
ecdsa_verify(curve, HASHER_SHA2, pub, sig, msg, sizeof(msg));

View File

@ -173,7 +173,7 @@ int zkp_ecdsa_get_public_key65(const ecdsa_curve *curve,
// signature_bytes has 64 bytes
// pby is one byte
// returns 0 on success
int zkp_ecdsa_sign_digest(
int zkp_ecdsa_sign_digest_recoverable(
const ecdsa_curve *curve, const uint8_t *private_key_bytes,
const uint8_t *digest, uint8_t *signature_bytes, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t signature_bytes[64])) {

View File

@ -12,11 +12,10 @@ int zkp_ecdsa_get_public_key33(const ecdsa_curve *curve,
int zkp_ecdsa_get_public_key65(const ecdsa_curve *curve,
const uint8_t *private_key_bytes,
uint8_t *public_key_bytes);
int zkp_ecdsa_sign_digest(const ecdsa_curve *curve,
const uint8_t *private_key_bytes,
const uint8_t *digest, uint8_t *signature_bytes,
uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64]));
int zkp_ecdsa_sign_digest_recoverable(
const ecdsa_curve *curve, const uint8_t *private_key_bytes,
const uint8_t *digest, uint8_t *signature_bytes, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64]));
int zkp_ecdsa_recover_pub_from_sig(const ecdsa_curve *curve,
uint8_t *public_key_bytes,
const uint8_t *signature_bytes,

View File

@ -277,8 +277,8 @@ static void send_signature(void) {
}
keccak_Final(&keccak_ctx, hash);
if (ecdsa_sign_digest(&secp256k1, privkey, hash, sig, &v,
ethereum_is_canonic) != 0) {
if (ecdsa_sign_digest_recoverable(&secp256k1, privkey, hash, sig, &v,
ethereum_is_canonic) != 0) {
fsm_sendFailure(FailureType_Failure_ProcessError, _("Signing failed"));
ethereum_signing_abort();
return;
@ -913,8 +913,9 @@ void ethereum_message_sign(const EthereumSignMessage *msg, const HDNode *node,
ethereum_message_hash(msg->message.bytes, msg->message.size, hash);
uint8_t v = 0;
if (ecdsa_sign_digest(&secp256k1, node->private_key, hash,
resp->signature.bytes, &v, ethereum_is_canonic) != 0) {
if (ecdsa_sign_digest_recoverable(&secp256k1, node->private_key, hash,
resp->signature.bytes, &v,
ethereum_is_canonic) != 0) {
fsm_sendFailure(FailureType_Failure_ProcessError, _("Signing failed"));
return;
}
@ -996,8 +997,9 @@ void ethereum_typed_hash_sign(const EthereumSignTypedHash *msg,
msg->has_message_hash, hash);
uint8_t v = 0;
if (ecdsa_sign_digest(&secp256k1, node->private_key, hash,
resp->signature.bytes, &v, ethereum_is_canonic) != 0) {
if (ecdsa_sign_digest_recoverable(&secp256k1, node->private_key, hash,
resp->signature.bytes, &v,
ethereum_is_canonic) != 0) {
fsm_sendFailure(FailureType_Failure_ProcessError, _("Signing failed"));
return;
}

View File

@ -522,7 +522,8 @@ uint32_t serialize_p2tr_witness(const uint8_t *signature,
bool tx_sign_ecdsa(const ecdsa_curve *curve, const uint8_t *private_key,
const uint8_t *hash, uint8_t *out, pb_size_t *size) {
uint8_t signature[64] = {0};
if (ecdsa_sign_digest(curve, private_key, hash, signature, NULL, NULL) != 0) {
if (ecdsa_sign_digest_recoverable(curve, private_key, hash, signature, NULL,
NULL) != 0) {
return false;
}

View File

@ -621,9 +621,9 @@ void u2f_register(const APDU *a) {
memcpy(sig_base.chal, req->chal, U2F_CHAL_SIZE);
memcpy(sig_base.keyHandle, &resp->keyHandleCertSig, KEY_HANDLE_LEN);
memcpy(sig_base.pubKey, &resp->pubKey, U2F_PUBKEY_LEN);
if (ecdsa_sign(&nist256p1, HASHER_SHA2, U2F_ATT_PRIV_KEY,
(uint8_t *)&sig_base, sizeof(sig_base), sig, NULL,
NULL) != 0) {
if (ecdsa_sign_recoverable(&nist256p1, HASHER_SHA2, U2F_ATT_PRIV_KEY,
(uint8_t *)&sig_base, sizeof(sig_base), sig,
NULL, NULL) != 0) {
send_u2f_error(U2F_SW_WRONG_DATA);
return;
}
@ -741,9 +741,9 @@ void u2f_authenticate(const APDU *a) {
sig_base.flags = resp->flags;
memcpy(sig_base.ctr, resp->ctr, 4);
memcpy(sig_base.chal, req->chal, U2F_CHAL_SIZE);
if (ecdsa_sign(&nist256p1, HASHER_SHA2, node->private_key,
(uint8_t *)&sig_base, sizeof(sig_base), sig, NULL,
NULL) != 0) {
if (ecdsa_sign_recoverable(&nist256p1, HASHER_SHA2, node->private_key,
(uint8_t *)&sig_base, sizeof(sig_base), sig,
NULL, NULL) != 0) {
send_u2f_error(U2F_SW_WRONG_DATA);
return;
}