Skip to content

release/7.15.0: Zcash Orchard, message-signing (TRON/TON/Solana), XRP memo#106

Open
BitHighlander wants to merge 17 commits into
keepkey:masterfrom
BitHighlander:master
Open

release/7.15.0: Zcash Orchard, message-signing (TRON/TON/Solana), XRP memo#106
BitHighlander wants to merge 17 commits into
keepkey:masterfrom
BitHighlander:master

Conversation

@BitHighlander
Copy link
Copy Markdown
Collaborator

Summary

This PR brings the BitHighlander fork master into keepkey/device-protocol master, covering the full 7.15.0 protocol surface.

New protocol messages / fields

Zcash Orchard

  • ZcashSignTx + Orchard shielded transaction protocol
  • ZcashDisplayAddress (IDs 1308/1309) — display and verify Orchard addresses
  • seed_fingerprint field added to FVK / address / sign message bindings

Message-signing parity (Finding coverage)

  • TronSignMessage (TIP-191), TronVerifyMessage, TronSignTypedHash (TIP-712)
  • TonSignMessage — Ed25519 message-signing primitive
  • SolanaSignOffchainMessage — domain-separated envelope (1212 byte limit, format 0)

XRP / THORChain

  • Optional memo field (field 7) on RippleSignTx — required for THORChain swap routing

THORChain

  • Optional denom field on ThorchainMsgSend — any-denom validation

Bug fixes

  • fix/zcash-seed-fingerprint-formula-doc — corrected formula in proto comments

Commits

16 commits ahead of keepkey/master. All additive (optional proto fields, new message IDs). No existing field numbers changed — fully backward compatible.

Test plan

  • Verify proto field numbers don't collide with any keepkey/master additions
  • Confirm firmware CI passes on the firmware branches that reference these protos
  • Spot-check RippleSignTx field 7 optional — old firmware ignores unknown fields gracefully

BitHighlander and others added 17 commits March 23, 2026 15:26
- PCZT streaming protocol: ZcashSignPCZT, ZcashPCZTAction, ZcashPCZTActionAck
- Orchard FVK: ZcashGetOrchardFVK, ZcashOrchardFVK
- Transparent shielding: ZcashTransparentInput, ZcashTransparentSig
- Wire IDs 1300-1307
- nanopb options for all fields

Multi-phase protocol: session init → action streaming → transparent signing.
Supports on-device Orchard digest verification via sub-digest fields.
New messages for displaying a Zcash unified address on the device screen
with FVK verification. The host provides the UA string and FVK components;
the device independently derives FVK from seed and verifies the match
before displaying the address with a QR code.

- ZcashDisplayAddress (wire_in 1308): address + ak/nk/rivk for verification
- ZcashAddress (wire_out 1309): confirmed address after user approval
- nanopb options: address max_size:128, key fields max_size:32
feat(zcash): add ZcashDisplayAddress protocol (IDs 1308/1309)
The device only verifies the Orchard FVK — it cannot verify
transparent or Sapling receivers that may also be bundled in
a Unified Address. Updated proto comments to explicitly state
the guarantee: "This UA contains an Orchard receiver from this
account" rather than implying full address ownership.

Also clarified that account or address_n is required (no silent
fallback to account 0).
docs(zcash): clarify ZcashDisplayAddress verification scope
…TIP-712)

Adds proto definitions for TRON message-signing parity:
- TronSignMessage / TronMessageSignature (1404/1405) — TIP-191 personal_sign
- TronVerifyMessage (1406) — host-asserted signature verification
- TronSignTypedHash / TronTypedDataSignature (1407/1408) — TIP-712 hash mode

Mirrors the Ethereum personal_sign + EIP-712 hash-mode shape. Firmware
implementation will reuse the secp256k1 + keccak256 primitives already
present for Ethereum, swapping the message prefix to '\x19TRON Signed Message:\n'
for TIP-191 and using '\x19\x01' for TIP-712.

Reserves IDs 1404-1408 contiguous to existing TRON range (1400-1403).
Adds TonSignMessage / TonMessageSignature (1504/1505) — basic Ed25519
arbitrary-bytes signing, mirroring SolanaSignMessage's shape.

This primitive lacks domain separation by design (raw Ed25519 over message
bytes). Firmware should gate it behind the AdvancedMode policy — same
fence used for SolanaSignMessage in fsm_msg_solana.h — until a TON
Connect ton_proof envelope is added as a separate proto.

Reserves IDs 1504-1505 contiguous to existing TON range (1500-1503).
Adds SolanaSignOffchainMessage / SolanaOffchainMessageSignature (756/757)
implementing the Solana off-chain message spec:

  '\xff' || 'solana offchain' || version || format || length || message

The '\xff' lead byte is invalid as a Solana transaction prefix, providing
the domain separation that plain SolanaSignMessage (754/755) lacks. With
this primitive, firmware can drop the AdvancedMode policy gate currently
required for SolanaSignMessage (fsm_msg_solana.h:461-472) for ASCII/UTF8
off-chain messages, since the envelope makes transaction-shaped attacks
impossible.

message_format values per spec:
  0 = Restricted ASCII (max 1212 bytes) — display-renderable
  1 = UTF-8 limited (max 1212 bytes) — display-renderable with care
  2 = UTF-8 extended (max 65515) — blind-sign only

Reserves IDs 756-757 contiguous to existing Solana range (750-755).
Bumped message max_size to 1212 to match the spec ceiling for formats 0/1.
…sages

ZIP-32 §6.1 seed fingerprint:

  SeedFingerprint := BLAKE2b-256("Zcash_HD_Seed_FP", seed)

A 32-byte stable identity of the device's seed. Adds optional bytes
seed_fingerprint fields across the existing zcash messages so hosts
and devices can bind FVKs, addresses, and signing sessions to a
specific seed identity.

Four new fields, all optional, fully backward compatible:

  ZcashOrchardFVK.seed_fingerprint              (4)
    Returned alongside (ak, nk, rivk). Lets a host pin an FVK to
    this device's seed.

  ZcashAddress.seed_fingerprint                 (2)
    Returned alongside the confirmed UA after on-device verification.
    Lets a host record "this address is on this device's seed."

  ZcashSignPCZT.expected_seed_fingerprint       (31)
    Sent by host. If present, device checks against its own
    fingerprint and rejects with Failure on mismatch before signing.
    Mirrors Keystone3's PCZT zip32_derivation seed_fingerprint check
    at the session level (one tx = one seed, no per-action duplication
    needed for our flow).

  ZcashDisplayAddress.expected_seed_fingerprint (7)
    Sent by host. Same rejection semantics as above before displaying.

Matching nanopb max_size:32 entries added to messages-zcash.options.

No existing fields modified. Devices and hosts that don't populate
the new fields continue to work unchanged.
feat(zcash): add seed_fingerprint binding to FVK / address / sign messages
Brings in upstream's 7.14.0 release + features/7.15 commits:
  d0b8d80 feat: 7.14.0 protocol — BIP-85, EVM metadata, Solana, TRON, TON, Zcash
  18bb4a7 Merge pull request keepkey#100 from keepkey/release/7.14.0
  bbcfcb0 feat: add ZcashDisplayAddress protocol messages (IDs 1308-1309)
  bf8646b Merge pull request keepkey#101 from keepkey/features/7.15

Note: ZcashDisplayAddress was developed in parallel on both sides.
Conflict resolution prefers upstream's version (max_size:256 for the
unified-address fields, more correct than fork's :128 since UAs can be
long when shielded receivers are present).

# Conflicts:
#	messages-zcash.options
#	messages-zcash.proto
#	messages.proto
#	package.json
Brings in TRON/TON/Solana message-signing proto definitions:
  0e3dc97 feat(tron): TIP-191 SignMessage, VerifyMessage, TIP-712 SignTypedHash
  20e646a feat(ton): Ed25519 SignMessage primitive
  c0ef415 feat(solana): SignOffchainMessage with domain-separated envelope

After this merge, fork master is the single source of truth that
firmware branches pin to during fork-only testing. A clean upstream
PR can be assembled later by cherry-picking these 3 commits onto a
fresh branch off keepkey/master.
Field comments documented the formula as

  BLAKE2b-256("Zcash_HD_Seed_FP", seed)

but ZIP-32 §6.1 (and the actual conforming implementations in the
upstream zip32 Rust crate, keystone3-firmware, and our own firmware)
prepend a 1-byte length:

  BLAKE2b-256("Zcash_HD_Seed_FP", I2LEBSP_8(len(seed)) || seed)

A host implementer following the proto comments would compute the
wrong fingerprint and have the device reject every signing/display
request with "seed fingerprint mismatch."

Comment-only change. No wire-format impact.
…formula-doc

fix(zcash): correct seed_fingerprint formula in proto comments
Add optional string memo field (field 7) to RippleSignTx protobuf message.
This enables THORChain swap routing memos and other arbitrary memo data
to be included in XRP transactions signed by the device.
feat(ripple): add memo field to RippleSignTx for 7.14.2
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