1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-05 04:50:57 +00:00

crypto: return parity when tweaking public key

This commit is contained in:
Andrew Toth 2024-09-05 13:41:52 -04:00
parent 748a19ac5d
commit 2ffb0d374c
No known key found for this signature in database
GPG Key ID: 60007AFC8938B018
8 changed files with 21 additions and 11 deletions

View File

@ -164,9 +164,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorcrypto_bip340_verify_obj,
/// def tweak_public_key(
/// public_key: bytes,
/// root_hash: bytes | None = None,
/// ) -> bytes:
/// ) -> tuple[int, bytes]:
/// """
/// Tweaks the public key with the specified root_hash.
/// First element of tuple is the parity, second is the tweaked public key.
/// """
STATIC mp_obj_t mod_trezorcrypto_bip340_tweak_public_key(size_t n_args,
const mp_obj_t *args) {
@ -188,13 +189,19 @@ STATIC mp_obj_t mod_trezorcrypto_bip340_tweak_public_key(size_t n_args,
vstr_t tpk = {0};
vstr_init_len(&tpk, 32);
int parity = 0;
int ret = zkp_bip340_tweak_public_key((const uint8_t *)pk.buf, rh_ptr,
(uint8_t *)tpk.buf);
(uint8_t *)tpk.buf, &parity);
if (ret != 0) {
vstr_clear(&tpk);
mp_raise_ValueError("Failed to tweak public key");
}
return mp_obj_new_str_from_vstr(&mp_type_bytes, &tpk);
mp_obj_t result[2];
result[0] = mp_obj_new_int(parity);
result[1] = mp_obj_new_str_from_vstr(&mp_type_bytes, &tpk);
return mp_obj_new_tuple(2, result);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(

View File

@ -153,7 +153,7 @@ def _address_p2tr(pubkey: bytes, coin: CoinInfo) -> str:
from trezor.crypto.curve import bip340
assert coin.bech32_prefix is not None
output_pubkey = bip340.tweak_public_key(pubkey[1:])
_, output_pubkey = bip340.tweak_public_key(pubkey[1:])
return encode_bech32_address(coin.bech32_prefix, 1, output_pubkey)

View File

@ -1167,7 +1167,7 @@ int fuzz_zkp_bip340_tweak_keys(void) {
// IDEA act on return values
zkp_bip340_tweak_private_key(internal_priv, root_hash, result);
zkp_bip340_tweak_public_key(internal_pub, root_hash, result);
zkp_bip340_tweak_public_key(internal_pub, root_hash, result, NULL);
return 0;
}

View File

@ -10587,7 +10587,7 @@ START_TEST(test_zkp_bip340_tweak) {
ck_assert_int_eq(res, 0);
ck_assert_mem_eq(output_priv, result, 32);
res = zkp_bip340_tweak_public_key(internal_pub, root_hash, result);
res = zkp_bip340_tweak_public_key(internal_pub, root_hash, result, NULL);
ck_assert_int_eq(res, 0);
ck_assert_mem_eq(output_pub, result, 32);
}

View File

@ -209,10 +209,11 @@ int zkp_bip340_verify_publickey(const uint8_t *public_key_bytes) {
// internal_public_key has 32 bytes
// root_hash has 32 bytes or is empty (NULL)
// output_public_key has 32 bytes
// pk_parity will be set to the parity if not NULL
// returns 0 on success
int zkp_bip340_tweak_public_key(const uint8_t *internal_public_key,
const uint8_t *root_hash,
uint8_t *output_public_key) {
uint8_t *output_public_key, int *pk_parity) {
int result = 0;
uint8_t tweak[SHA256_DIGEST_LENGTH] = {0};
@ -250,7 +251,7 @@ int zkp_bip340_tweak_public_key(const uint8_t *internal_public_key,
secp256k1_xonly_pubkey xonly_output_pubkey = {0};
if (result == 0) {
if (secp256k1_xonly_pubkey_from_pubkey(context_read_only,
&xonly_output_pubkey, NULL,
&xonly_output_pubkey, pk_parity,
&output_pubkey) != 1) {
result = -1;
}

View File

@ -14,7 +14,8 @@ int zkp_bip340_verify_digest(const uint8_t *public_key_bytes,
int zkp_bip340_verify_publickey(const uint8_t *public_key_bytes);
int zkp_bip340_tweak_public_key(const uint8_t *internal_public_key,
const uint8_t *root_hash,
uint8_t *output_public_key);
uint8_t *output_public_key,
int *pk_parity);
int zkp_bip340_tweak_private_key(const uint8_t *internal_private_key,
const uint8_t *root_hash,
uint8_t *output_private_key);

View File

@ -2834,7 +2834,7 @@ static bool signing_verify_orig_nonlegacy_input(TxInputType *orig_input) {
signing_hash_bip341(&orig_info, idx1, hash_type & 0xff, hash);
uint8_t output_public_key[32] = {0};
valid = (zkp_bip340_tweak_public_key(node.public_key + 1, NULL,
output_public_key) == 0) &&
output_public_key, NULL) == 0) &&
(zkp_bip340_verify_digest(output_public_key, sig, hash) == 0);
} else {
#if !BITCOIN_ONLY

View File

@ -196,7 +196,8 @@ bool compute_address(const CoinInfo *coin, InputScriptType script_type,
return 0;
}
uint8_t tweaked_pubkey[32];
zkp_bip340_tweak_public_key(node->public_key + 1, NULL, tweaked_pubkey);
zkp_bip340_tweak_public_key(node->public_key + 1, NULL, tweaked_pubkey,
NULL);
if (!segwit_addr_encode(address, coin->bech32_prefix, SEGWIT_VERSION_1,
tweaked_pubkey, 32)) {
return 0;