What changed, and why it matters
This is a small code cleanup in the COLDCARD firmware that switches BIP-322 message hashing from a software double-SHA256 to a hardware-accelerated tagged-SHA256 function. The change removes a TODO comment and uses a dedicated function (ngu.hash.sha256t) that the hardware can speed up. There is no direct evidence in the commit of a security vulnerability being fixed; it appears to be a performance and maintainability improvement.
No immediate action required. Treat as routine optimization/cleanup. If reviewing for security, verify that ngu.hash.sha256t produces byte-identical output to the previous sha256s(tag+tag+msg) construction and that the hardware accelerator does not introduce side-channel or fault-injection risks compared to the software implementation.
Security signals we found
Use of hardware-accelerated cryptographic primitive (tagged_sha256)
Removal of TODO indicating previous implementation was pending hardware/library support
Hash output still verified against expected value, reducing risk of behavioral change
No bounds checks, input validation, or memory safety changes visible
Evidence from the diff
In shared/auth.py, the BIP-322 message hash computation is changed from ngu.hash.sha256s(bip322_tag_hash+bip322_tag_hash+msg) to ngu.hash.sha256t(bip322_tag_hash, msg, True). This uses a hardware-accelerated tagged SHA256 implementation instead of concatenating the tag twice and doing a plain double SHA256 in software. The precomputed tag hash remains the same, and the resulting digest is asserted against self.psbt.por322_msg_hash, preserving correctness. The commit removes two TODO comments related to moving the code and needing newer libngu support.
Changed components
shared/auth.pyBIP-322 message signing/verification flowngu.hash module (tagged SHA256 implementation)Inspect captured patch +2 / −3
diff --git a/shared/auth.py b/shared/auth.py
index 2d6991b..2ce92fe 100644
--- a/shared/auth.py
+++ b/shared/auth.py
@@ -296,7 +296,7 @@ class ApproveTransaction(UserAuthorizedAction):
key0="to input message manually", title="BIP-322 MSG",
no_qr=not version.has_qwerty)
- # TODO move elswhere
+ # single sha256 of b'BIP0322-signed-message'
bip322_tag_hash = b'te\x84\xa1\x87/\xa1\x00AUN\xff\xa08\xd6\x12IB\xddy\xb4\xe5\x8aL\xda\x18N\x13\xdb\xe6,I'
if ch == KEY_CANCEL:
@@ -325,9 +325,8 @@ class ApproveTransaction(UserAuthorizedAction):
with open(fn, 'rt') as fd:
msg = fd.read()
- # TODO needs newer libngu with sha256t
assert msg, "need msg"
- msg_hash = ngu.hash.sha256s(bip322_tag_hash+bip322_tag_hash+msg)
+ msg_hash = ngu.hash.sha256t(bip322_tag_hash, msg, True)
assert msg_hash == self.psbt.por322_msg_hash, "hash verification failed"
ch = await ux_show_story(
msg+"\n\nPress %s to approve message, otherwise %s to exit." % (OK, X),
Why this scored 22/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.