Skip to content

feat(hive): SLIP-0048 + HiveGetPublicKeys + AccountCreate + AccountUpdate#246

Merged
BitHighlander merged 15 commits into
alphafrom
feature/hive
May 24, 2026
Merged

feat(hive): SLIP-0048 + HiveGetPublicKeys + AccountCreate + AccountUpdate#246
BitHighlander merged 15 commits into
alphafrom
feature/hive

Conversation

@BitHighlander

Copy link
Copy Markdown
Owner

Summary

  • Fixes Hive key derivation from BIP-44 → SLIP-0048 (m/48'/13'/role'/account'/0')
  • Adds HiveGetPublicKeys: derive all 4 role keys (owner/active/memo/posting) in one interaction
  • Adds HiveSignAccountCreate: sign Graphene account_create op — device is sole root of trust from genesis
  • Adds HiveSignAccountUpdate: sign account_update op — replace existing account authorities with device keys
  • Adds parse_stm_pubkey() helper for Graphene authority struct serialization (RIPEMD base58check)
  • Removes incorrect pb_callback_t forbidden check from CMakeLists.txt
  • Proto generation via Docker (kktech/firmware:v15, nanopb 0.3.9.8, protoc 3.5.1)

Wire IDs

Message ID
HiveGetPublicKeys 1604
HivePublicKeys 1605
HiveSignAccountCreate 1606
HiveSignedAccountCreate 1607
HiveSignAccountUpdate 1608
HiveSignedAccountUpdate 1609

Test plan

  • make build-emulator from vault repo — emulator builds clean
  • HiveGetPublicKey returns STM-prefixed key at SLIP-0048 path
  • HiveGetPublicKeys returns all 4 role keys for account 0
  • HiveSignTx signs a transfer and emits valid recoverable secp256k1 signature
  • HiveSignAccountCreate signs account_create, device shows username confirmation
  • HiveSignAccountUpdate signs account_update, device shows warning + new owner key

Fixes lint-format CI gate.
Wire messages-hive.proto through the nanopb build so messages-hive.pb.h
and messages-hive.pb.c are generated at build time. Add field-size
annotations (max_count/max_size/int_size) required by nanopb.
- fsm.h: declare fsm_msgHiveGetPublicKey / fsm_msgHiveSignTx
- interface.h: include messages-hive.pb.h so types are visible
  to all translation units that include fsm.h (draw.c, layout.c, etc.)

Verified: kkemulator_dylib builds clean locally.
Gates test_ethereum_blind_sign_blocked, test_invalid_bip39_word_rejected,
and test_zcash_display_address_wrong_fvk_rejected to requires_firmware
7.15.1+. Our branch targets 7.15.0 so these tests now skip cleanly.
…reate, HiveSignAccountUpdate

- Fix key derivation from BIP-44 to SLIP-0048 (m/48'/13'/role'/account'/0')
- Add HiveGetPublicKeys: derives all 4 role keys in one device interaction
- Add HiveSignAccountCreate: signs Graphene account_create op, device confirms username
- Add HiveSignAccountUpdate: signs Graphene account_update op, replaces all authorities
- Add parse_stm_pubkey() for authority struct serialization (RIPEMD base58check)
- Fix CMakeLists.txt: remove incorrect pb_callback_t check (proto gen uses Docker)
- Use Docker (kktech/firmware:v15) for protoc generation to ensure nanopb 0.3.9.x compat
Security (High): firmware now derives all four role keys (owner/active/posting/memo)
internally from the device root rather than trusting host-supplied STM key strings.
The FSM handler calls hive_deriveRawKey() for each role before fetching the signing
node, then passes raw 33-byte arrays to hive_signAccountCreate/Update. Host-supplied
new_*_key fields are never used for the actual serialized transaction.

Bug (High): invert hdnode_private_ckd return check — the function returns 1 on
success, 0 on failure. All five derivation calls in hive_getPublicKeys/hive_deriveRawKey
previously jumped to fail on success (!=0). Fixed by using !hdnode_private_ckd().

Bug (High): remove spurious 0x00 key-type prefix from append_authority() and
from memo_key serialization in account_create and account_update. Hive's Graphene
wire format encodes public keys as raw 33 bytes with no type byte.

Bug (Medium): add hive_deriveRawKey() helper that centralises SLIP-0048 derivation
with the corrected return-value check; hive_getPublicKeys() now delegates to it,
removing the duplicated (and previously broken) loop.

Bug (Medium): reject memos longer than 440 bytes in hive_signTx() before
serialization to prevent signing a silently-truncated transaction. The constant
is documented relative to tx_buf[512] overhead.

Submodule: bump device-protocol to acc2795 (rebased feature/hive onto remote tip);
SHA is now fetchable from BitHighlander/device-protocol.

API change: hive_signAccountCreate and hive_signAccountUpdate now take four
const uint8_t[33] key parameters; callers derive these from the device root
before the signing node is fetched so the static fsm buffer is not clobbered.
@BitHighlander

Copy link
Copy Markdown
Owner Author

All 6 review findings addressed in commit 3f36827.

High — Security: host-supplied keys never used for signing
fsm_msgHiveSignAccountCreate and fsm_msgHiveSignAccountUpdate now call hive_deriveRawKey() (new helper) for each of the four roles before fetching the signing node. The four raw 33-byte keys are passed directly to hive_signAccountCreate/Update. The host-supplied owner_key/new_owner_key etc. fields in the proto are never used in the serialized transaction. The device-derived owner key is displayed on-screen for user verification.

High — hdnode_private_ckd inversion fixed
All derivation calls now use !hdnode_private_ckd(...) (returns 1 on success). The previous != 0 check made hive_getPublicKeys fail on every successful derivation. Fixed in both hive_deriveRawKey() and (by delegation) hive_getPublicKeys().

High — 0x00 key-type prefix removed
append_authority() no longer writes a type byte before the 33 raw key bytes. Memo key serialization in hive_serialize_account_create and hive_serialize_account_update also drops the spurious 0x00. Hive's Graphene wire format has no type prefix.

Medium — parse_stm_pubkey return values (resolved by security fix)
parse_stm_pubkey is no longer called on host-supplied keys; the firmware derives and uses raw bytes directly. Return-value checking is now moot for the signing paths.

Medium — overflow detection
hive_signTx() now rejects memos longer than HIVE_MAX_MEMO_LEN (440 bytes) before serialization, preventing a silently-truncated transaction from being signed. The limit is documented against tx_buf[512] overhead.

Submodule SHA now fetchable
deps/device-protocol rebased onto origin/feature/hive (77e5385) and re-pushed as acc2795, which is publicly accessible on BitHighlander/device-protocol.

deps/device-protocol → 2b25cf7 (BitHighlander/device-protocol master)
  squash merge of feature/hive: all 10 Hive proto message types

deps/python-keepkey → eee4804 (BitHighlander/python-keepkey master)
  squash merge of feature/hive: pb2, mapping, client + hive.py helpers
Three pointer/variable const corrections to satisfy CI static-analysis:
- hive.c: const size_t lens[4]
- fsm_msg_hive.h: const HDNode* root in account_create handler
- fsm_msg_hive.h: const HDNode* root in account_update handler
- Cast account_index to (unsigned int) to suppress -Werror=format on ARM
  (uint32_t is long unsigned int on 32-bit targets; %u expects unsigned int)
- Pin deps/python-keepkey to 04119f3 (old-style pb2 compatible with
  protobuf 3.20.3 CI runtime)
- ripple.c: port XRPL Memos array serialization from alpha (0xF9/0xEA
  encoding for THORChain swap routing memos)
- messages-ripple.options: add RippleSignTx.memo max_size:200 so nanopb
  generates a static buffer instead of a callback (matches alpha)
- Update build-emu pb files with memo field (was missing, generated from
  stale proto without memo)
- Pin deps/python-keepkey to e338df0 (alpha CI test fixes ported)
…hain updates

Merges alpha's Zcash PCZT clear-signing, THORChain deposit improvements, and
EVM updates while preserving all Hive SLIP-0048 messages (HiveGetPublicKey,
HiveGetPublicKeys, HiveSignTx, HiveSignAccountCreate, HiveSignAccountUpdate
and their response types).

Conflict resolutions:
- deps/device-protocol: merge commit combining Hive 10-message set + Zcash/THORChain
- deps/python-keepkey: e338df0 (Hive pb2 + test fixes on master)
- include/keepkey/firmware/fsm.h: kept all 5 Hive forward decls
- include/keepkey/firmware/hive.h: kept full Hive header with constants
- include/keepkey/transport/messages-hive.options: kept full Hive options
- include/keepkey/transport/messages-ripple.options: added memo max_size:200
- lib/firmware/fsm_msg_hive.h: kept our Hive FSM handlers
- lib/firmware/hive.c: kept our Hive crypto impl with const fixes
- lib/transport/CMakeLists.txt: used alpha's nanopb invocation style
@BitHighlander BitHighlander merged commit 6994348 into alpha May 24, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant