chore(core): use `nist256p1` instead of `secp256k1` for payment request verification [no changelog]
What changed, and why it matters
This commit changes the cryptographic curve used to verify payment requests in Trezor firmware from secp256k1 (used by Bitcoin) to nist256p1 (also known as secp256r1, a standard government/enterprise curve). It also updates the built-in test public key to match the new curve. The change itself is a normal engineering update, but it touches code that protects payment request signatures, so it has minor security relevance.
Treat as a routine cryptographic-curve migration. Review that the new nist256p1 public key is correctly derived for the documented test seed and path, confirm production (non-debug) keys are updated consistently, and ensure regression tests cover payment-request verification with both old and new curve configurations if backward compatibility is required.
Security signals we found
Cryptographic curve change in signature verification path
Hardcoded public key material updated for debug/test seed
Payment-request signature validation is a security boundary
No changelog entry provided
Evidence from the diff
In core/src/apps/common/payment_request.py, the PaymentRequestVerifier class is switched from trezor.crypto.curve.secp256k1 to nist256p1 for signature verification. The hardcoded debug-only public key (for the ‘all all … all’ seed at m/0h) is replaced with the corresponding nist256p1 public key. The verification logic and message hashing remain otherwise unchanged. No changelog entry is recorded.
Changed components
core/src/apps/common/payment_request.pyPaymentRequestVerifier.verify()PaymentRequestVerifier debug public keyInspect captured patch +4 / −4
diff --git a/core/src/apps/common/payment_request.py b/core/src/apps/common/payment_request.py
index 27b2deab..03359f2d 100644
--- a/core/src/apps/common/payment_request.py
+++ b/core/src/apps/common/payment_request.py
@@ -18,8 +18,8 @@ _MEMO_TYPE_TEXT_DETAILS = const(4)
class PaymentRequestVerifier:
if __debug__:
- # secp256k1 public key of m/0h for "all all ... all" seed.
- PUBLIC_KEY = b"\x03\x0f\xdf^(\x9bZ\xefSb\x90\x95:\xe8\x1c\xe6\x0e\x84\x1f\xf9V\xf3f\xac\x12?\xa6\x9d\xb3\xc7\x9f!\xb0"
+ # nist256p1 public key of m/0h for "all all ... all" seed.
+ PUBLIC_KEY = b"\x03\xd9\xd9\x3f\x89\xc6\x96\x3b\x94\xbb\xd7\xa5\x11\x88\x28\xe4\x4c\x1c\x39\x59\x15\xac\xe8\x48\x88\x71\x7f\x56\x8c\xb0\x19\x74\xc3"
else:
PUBLIC_KEY = b""
@@ -85,7 +85,7 @@ class PaymentRequestVerifier:
writers.write_uint32_le(self.h_pr, slip44_id)
def verify(self) -> None:
- from trezor.crypto.curve import secp256k1
+ from trezor.crypto.curve import nist256p1
if self.expected_amount is not None and self.amount != self.expected_amount:
raise DataError("Invalid amount in payment request.")
@@ -93,7 +93,7 @@ class PaymentRequestVerifier:
hash_outputs = self.h_outputs.get_digest()
writers.write_bytes_fixed(self.h_pr, hash_outputs, 32)
- if not secp256k1.verify(
+ if not nist256p1.verify(
self.PUBLIC_KEY, self.signature, self.h_pr.get_digest()
):
raise DataError("Invalid signature in payment request.")
Why this scored 18/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.