feat(hive): HiveSignMessage — Keychain signBuffer, unblocks dApp login#306
Closed
BitHighlander wants to merge 4 commits into
Closed
feat(hive): HiveSignMessage — Keychain signBuffer, unblocks dApp login#306BitHighlander wants to merge 4 commits into
BitHighlander wants to merge 4 commits into
Conversation
…ks dApp login Digest is SHA256(raw message bytes) ONLY — no chain_id prepend, no message prefix (the hive-js Signature.signBuffer contract every Hive dApp verifies against). Output: 65-byte compact recoverable sig (27+recid+4) + the 33-byte compressed pubkey so the host can build Keychain's publicKey response field without a second round-trip. - Full SLIP-48 path shape enforced like the tx handlers; any of the four roles may sign (dApp login uses posting') - Messages beginning with the mainnet chain id are refused: such a buffer would hash to a broadcastable TRANSACTION digest (tx digest = SHA256(chain_id || tx)) - 1024-byte cap in proto AND handler (memo-length lesson) - Printable text shown as-is, other payloads as a hex preview - hive_sign_raw_digest factored out of hive_sign_digest (shared header/recid logic, no duplication) - IDs 1610-1613 skipped: NEAR holds them on device-protocol master - pyk: sign_message + 7 signBuffer tests (recovery, roles, boundary, oversize, path fence, chain-id collision)
…ffer Finding 1: printable text over 128 bytes now routes through the hex preview + byte count instead of confirm()'s silently-truncating body buffer (BODY_CHAR_MAX) — a long message could otherwise show a benign prefix while the device signs hidden trailing content. Same budget as SolanaSignMessage. Finding 2: owner' removed from the accepted signBuffer roles. Keychain's requestSignBuffer surface is Posting | Active | Memo only; no consumer offers owner', and the cold owner key must not be normalized into dApp flows. Also: comment now says printable ASCII (0x20-0x7e), not UTF-8. Pins: device-protocol a793934 (role doc), python-keepkey ed8cbdf (19/19 on emulator incl. new >128B printable boundary + owner' reject).
Owner
Author
|
Both findings addressed in ddade55:
Re-verified on a rebuilt UDP emulator: 19/19 hive tests. Testnet chain-id fence left out per the review's no-change-required note — mainnet is the broadcastable-funds case. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements P3 from the Hive full-support audit: the dApp login primitive. SkateHive and every Aioha/Keychain-SDK dApp authenticates via
requestSignBuffer— a message signature with the posting key that the dApp verifies by pubkey recovery against the account's on-chain authority. It cannot be shimmed host-side. Notably: Hive Keychain itself throwssign_buffer_ledger_errorfor Ledger accounts, so no hardware wallet can do Hive dApp login today.Stacked on #305 (
fix/hive-sign-hardening) — uses its SLIP-48 enforcement conventions; GitHub will retarget this todevelopwhen #305 merges.Contract (verified against Keychain source, hive-js
Signature.signBuffer)sig[0] = 27 + recid + 4, then r‖s; low-S via the existinghive_is_canoniccallback.publicKeyfield without a second device round-trip.Message IDs: 1614/1615 (not 1610/1611)
The sign-message handoff proposed 1610/1611, but NEAR holds 1610-1613 on device-protocol master (PR #32, merged). Registry note added in
messages.proto. Follow-on Hive primitives (P4HiveSignOperations, P5 memo crypto) must start at 1616.Security fences
m/48'/13'/role'/account'/0', 5 hardened components) exactly like the tx handlers; any of the four roles may sign (login uses posting').SHA256(chain_id || tx), so a crafted "message" beginning with the mainnet chain-id bytes would hash to a broadcastable transaction's digest. No legitimate challenge starts with those 32 bytes; the handler rejects them. (Keychain itself does not guard this.)Pins
deps/device-protocol→9e46aeb(feat/hive-sign-messageoff the current pin33521a8, only the two new messages — no unrelated proto drift)deps/python-keepkey→591dba8(feat/hive-sign-messageoff fix(hive): enforce SLIP-48 path in SignTx + specific memo-length error #305's pin35555d7):hive.sign_message(), wire-id mapping, pb2 regen with the pinned protoc 3.5.1 (docker v8)Verification
SHA256(message), assert ∈ {responsepublic_key, independently-derivedHiveGetPublicKey}), all-four-roles distinctness, non-printable buffer, 1024 boundary, 1025 reject, path fence (BIP-44 / 3054' / unassigned role / short path), chain-id-prefix reject.Storage.StorageRoundTrip, the documented macOS-ARM64 golden-vector platform artifact (Linux CI is the source of truth for it).make kkfirmwareclean; generated nanopb has zeropb_callback_t(options caps complete).Release scope
7.15.0 is still untagged; the handoff recommends shipping this in the 7.15.0 rc train so Hive launches dApp-login-capable instead of transfer-only. Version gates in the pyk tests are set to 7.15.0 accordingly — flip to 7.15.1 if the decision goes the other way.