chore(tron): use pubhash for address derivation.
What changed, and why it matters
This commit changes how Trezor hardware wallets derive TRON addresses. Previously, the code loaded the private key into Python memory and computed the public key from it. Now it uses a precomputed public-key hash already available from the keychain. This is a defensive hardening change that reduces the chance of private-key exposure in the Python layer, but it does not by itself fix a known exploitable vulnerability.
Treat as a low-risk hardening improvement. Review whether any other altcoin apps still call node.private_key() for public-key derivation and consider similar refactoring. No urgent user action is required.
Security signals we found
Reduction of private-key exposure in application-layer Python code
Removal of secp256k1.publickey() derivation from private key in get_address flow
Use of node.ethereum_pubkeyhash() for address derivation
No changelog entry marked by [no changelog], suggesting internal cleanup/hardening
Evidence from the diff
In core/src/apps/tron/get_address.py, the previous implementation called node.private_key() and secp256k1.publickey() in Python to obtain the public key, then hashed it with Keccak-256 to form the TRON address. The patch replaces that with node.ethereum_pubkeyhash(), which returns the Keccak-256 hash of the public key directly from the keychain, and prepends the 0x41 network byte. The removed address_from_public_key helper is moved into the test file only. The change reduces private-key handling in Python and aligns TRON address derivation with the existing Ethereum-style pubkeyhash path.
Changed components
core/src/apps/tron/get_address.pycore/src/apps/tron/helpers.pycore/tests/test_apps.tron.address.pyInspect captured patch +9 / −12
diff --git a/core/src/apps/tron/get_address.py b/core/src/apps/tron/get_address.py
index 911b63dc..6fc78ff5 100644
--- a/core/src/apps/tron/get_address.py
+++ b/core/src/apps/tron/get_address.py
@@ -15,20 +15,18 @@ if TYPE_CHECKING:
)
async def get_address(msg: TronGetAddress, keychain: Keychain) -> TronAddress:
from trezor import TR
- from trezor.crypto.curve import secp256k1
from trezor.messages import TronAddress
from trezor.ui.layouts import show_address
from apps.common import paths
from apps.common.address_mac import get_address_mac
- from .helpers import address_from_public_key
+ from .helpers import get_encoded_address
address_n = msg.address_n
await paths.validate_path(keychain, address_n)
node = keychain.derive(address_n)
- public_key = secp256k1.publickey(node.private_key(), False)
- address = address_from_public_key(public_key)
+ address = get_encoded_address(b"\x41" + node.ethereum_pubkeyhash())
mac = get_address_mac(address, SLIP44_ID, address_n, keychain)
if msg.show_display:
diff --git a/core/src/apps/tron/helpers.py b/core/src/apps/tron/helpers.py
index 98f2be30..05889d4a 100644
--- a/core/src/apps/tron/helpers.py
+++ b/core/src/apps/tron/helpers.py
@@ -7,13 +7,6 @@ if TYPE_CHECKING:
from buffer_types import AnyBytes
-def address_from_public_key(pubkey: bytes) -> str:
- from trezor.crypto.hashlib import sha3_256
-
- address_bytes = b"\x41" + sha3_256(pubkey[1:], keccak=True).digest()[12:]
- return base58.encode_check(address_bytes)
-
-
def get_encoded_address(address_bytes: AnyBytes) -> str:
"""Encodes raw address bytes into Tron format."""
address = base58.encode_check(address_bytes)
diff --git a/core/tests/test_apps.tron.address.py b/core/tests/test_apps.tron.address.py
index b9beb73b..13629575 100644
--- a/core/tests/test_apps.tron.address.py
+++ b/core/tests/test_apps.tron.address.py
@@ -2,7 +2,13 @@
from common import * # isort:skip
if not utils.BITCOIN_ONLY:
- from apps.tron.helpers import address_from_public_key
+ from trezor.crypto.hashlib import sha3_256
+
+ from apps.tron.helpers import get_encoded_address
+
+ def address_from_public_key(pubkey: bytes) -> str:
+ address_bytes = b"\x41" + sha3_256(pubkey[1:], keccak=True).digest()[12:]
+ return get_encoded_address(address_bytes)
@unittest.skipUnless(not utils.BITCOIN_ONLY, "altcoin")
Why this scored 16/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.