diff --git a/messages-solana.options b/messages-solana.options index 411233ab..ee812da1 100644 --- a/messages-solana.options +++ b/messages-solana.options @@ -13,3 +13,8 @@ SolanaSignMessage.coin_name max_size:21 SolanaSignMessage.message max_size:1024 SolanaMessageSignature.public_key max_size:32 SolanaMessageSignature.signature max_size:64 +SolanaSignOffchainMessage.address_n max_count:8 +SolanaSignOffchainMessage.coin_name max_size:21 +SolanaSignOffchainMessage.message max_size:1212 +SolanaOffchainMessageSignature.public_key max_size:32 +SolanaOffchainMessageSignature.signature max_size:64 diff --git a/messages-solana.proto b/messages-solana.proto index e0c341e7..f0ca4484 100644 --- a/messages-solana.proto +++ b/messages-solana.proto @@ -79,3 +79,40 @@ message SolanaMessageSignature { optional bytes public_key = 1; // 32-byte Ed25519 public key optional bytes signature = 2; // 64-byte Ed25519 signature } + +/** + * Request: Ask device to sign a Solana off-chain message with domain separation + * + * Per the Solana off-chain message spec, the device signs over the envelope: + * "\xff" || "solana offchain" || || + * || || + * + * The "\xff" lead byte is invalid as a Solana transaction prefix, providing + * domain separation that plain SolanaSignMessage lacks. Firmware constructs + * the envelope from the components below; host supplies version/format/message. + * + * Format values: + * 0 = Restricted ASCII (printable, max 1212 bytes) — renderable on display + * 1 = UTF-8 (max 1212 bytes) — renderable, may need policy gate + * 2 = UTF-8 (max 65515 bytes) — Ledger-only mode, blind-sign + * + * @next SolanaOffchainMessageSignature + * @next Failure + */ +message SolanaSignOffchainMessage { + repeated uint32 address_n = 1; // BIP-32/BIP-44 path to signing key + optional string coin_name = 2 [default = "Solana"]; + optional uint32 version = 3 [default = 0]; // Off-chain message spec version (0 = current) + optional uint32 message_format = 4; // 0=ASCII, 1=UTF8 limited, 2=UTF8 extended + optional bytes message = 5; // Raw message payload (firmware wraps with envelope) + optional bool show_display = 6; // Show message on device display +} + +/** + * Response: Ed25519 signature over the off-chain message envelope + * @prev SolanaSignOffchainMessage + */ +message SolanaOffchainMessageSignature { + optional bytes public_key = 1; // 32-byte Ed25519 public key + optional bytes signature = 2; // 64-byte Ed25519 signature over the envelope +} diff --git a/messages-ton.options b/messages-ton.options index 3b046331..91bf283e 100644 --- a/messages-ton.options +++ b/messages-ton.options @@ -8,3 +8,8 @@ TonSignTx.memo max_size:121 TonAddress.address max_size:50 TonAddress.raw_address max_size:70 TonSignedTx.signature max_size:64 +TonSignMessage.address_n max_count:8 +TonSignMessage.coin_name max_size:21 +TonSignMessage.message max_size:1024 +TonMessageSignature.public_key max_size:32 +TonMessageSignature.signature max_size:64 diff --git a/messages-ton.proto b/messages-ton.proto index 6813fbd4..09e44eba 100644 --- a/messages-ton.proto +++ b/messages-ton.proto @@ -70,3 +70,31 @@ message TonSignTx { message TonSignedTx { optional bytes signature = 1; // Ed25519 signature (64 bytes) } + +////////////////////////////////////// +// TON: Message signing // +////////////////////////////////////// + +/** + * Request: Ask device to sign an arbitrary message with Ed25519 + * Note: lacks domain separation by default. Firmware policy may gate + * this behind AdvancedMode (matching the SolanaSignMessage pattern) + * until a TON Connect-style envelope (ton_proof) is implemented. + * @next TonMessageSignature + * @next Failure + */ +message TonSignMessage { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional string coin_name = 2 [default='Ton']; + optional bytes message = 3; // Message bytes to sign + optional bool show_display = 4; // Show message on device display +} + +/** + * Response: Ed25519 signature and public key for the signed message + * @prev TonSignMessage + */ +message TonMessageSignature { + optional bytes public_key = 1; // 32-byte Ed25519 public key + optional bytes signature = 2; // 64-byte Ed25519 signature +} diff --git a/messages-tron.options b/messages-tron.options index c6437134..1e2ca71a 100644 --- a/messages-tron.options +++ b/messages-tron.options @@ -14,3 +14,17 @@ TronTriggerSmartContract.contract_address max_size:35 TronTriggerSmartContract.data max_size:512 TronSignTx.data max_size:256 TronSignedTx.serialized_tx max_size:1024 +TronSignMessage.address_n max_count:8 +TronSignMessage.coin_name max_size:21 +TronSignMessage.message max_size:1024 +TronMessageSignature.address max_size:35 +TronMessageSignature.signature max_size:65 +TronVerifyMessage.address max_size:35 +TronVerifyMessage.signature max_size:65 +TronVerifyMessage.message max_size:1024 +TronSignTypedHash.address_n max_count:8 +TronSignTypedHash.coin_name max_size:21 +TronSignTypedHash.domain_separator_hash max_size:32 +TronSignTypedHash.message_hash max_size:32 +TronTypedDataSignature.address max_size:35 +TronTypedDataSignature.signature max_size:65 diff --git a/messages-tron.proto b/messages-tron.proto index cb566450..f091c785 100644 --- a/messages-tron.proto +++ b/messages-tron.proto @@ -81,3 +81,68 @@ message TronSignedTx { optional bytes signature = 1; // ECDSA signature (65 bytes: r + s + recovery_id) optional bytes serialized_tx = 2; // Reconstructed raw_data bytes (for host verification) } + +////////////////////////////////////// +// TRON: Message signing (TIP-191) // +////////////////////////////////////// + +/** + * Request: Ask device to sign a message using TIP-191 personal_sign + * Hash: keccak256("\x19TRON Signed Message:\n" + len(message) + message) + * @next TronMessageSignature + * @next Failure + */ +message TronSignMessage { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional string coin_name = 2 [default='Tron']; + optional bytes message = 3; // Message bytes to sign + optional bool show_display = 4; // Show message on device display +} + +/** + * Response: Signed message + * @prev TronSignMessage + */ +message TronMessageSignature { + optional string address = 1; // Base58Check TRON address that signed + optional bytes signature = 2; // 65-byte signature (r + s + v) +} + +/** + * Request: Ask device to verify a TIP-191 message signature + * @next Success + * @next Failure + */ +message TronVerifyMessage { + optional string address = 1; // Base58Check TRON address claimed to have signed + optional bytes signature = 2; // 65-byte signature to verify + optional bytes message = 3; // Message that was signed +} + +////////////////////////////////////// +// TRON: Typed data signing (TIP-712)// +////////////////////////////////////// + +/** + * Request: Ask device to sign hash of typed data (TIP-712 hash mode) + * Domain separation: keccak256("\x19\x01" + domain_separator_hash + message_hash) + * Host pre-computes the EIP-712-style domainSeparator and message hashes. + * @start + * @next TronTypedDataSignature + * @next Failure + */ +message TronSignTypedHash { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional string coin_name = 2 [default='Tron']; + required bytes domain_separator_hash = 3; // 32-byte domainSeparator hash + optional bytes message_hash = 4; // 32-byte message hash (empty if domain-only) +} + +/** + * Response: Signed typed data + * @prev TronSignTypedHash + */ +message TronTypedDataSignature { + required string address = 1; // Base58Check TRON address that signed + required bytes signature = 2; // 65-byte signature (r + s + v) +} diff --git a/messages.proto b/messages.proto index e9f37e02..ca35898c 100644 --- a/messages.proto +++ b/messages.proto @@ -140,6 +140,8 @@ enum MessageType { MessageType_SolanaSignedTx = 753 [ (wire_out) = true ]; MessageType_SolanaSignMessage = 754 [ (wire_in) = true ]; MessageType_SolanaMessageSignature = 755 [ (wire_out) = true ]; + MessageType_SolanaSignOffchainMessage = 756 [ (wire_in) = true ]; + MessageType_SolanaOffchainMessageSignature = 757 [ (wire_out) = true ]; // Binance MessageType_BinanceGetAddress = 800 [ (wire_in) = true ]; @@ -224,12 +226,19 @@ enum MessageType { MessageType_TronAddress = 1401 [ (wire_out) = true ]; MessageType_TronSignTx = 1402 [ (wire_in) = true ]; MessageType_TronSignedTx = 1403 [ (wire_out) = true ]; + MessageType_TronSignMessage = 1404 [ (wire_in) = true ]; + MessageType_TronMessageSignature = 1405 [ (wire_out) = true ]; + MessageType_TronVerifyMessage = 1406 [ (wire_in) = true ]; + MessageType_TronSignTypedHash = 1407 [ (wire_in) = true ]; + MessageType_TronTypedDataSignature = 1408 [ (wire_out) = true ]; // TON MessageType_TonGetAddress = 1500 [ (wire_in) = true ]; MessageType_TonAddress = 1501 [ (wire_out) = true ]; MessageType_TonSignTx = 1502 [ (wire_in) = true ]; MessageType_TonSignedTx = 1503 [ (wire_out) = true ]; + MessageType_TonSignMessage = 1504 [ (wire_in) = true ]; + MessageType_TonMessageSignature = 1505 [ (wire_out) = true ]; } //////////////////// diff --git a/package-lock.json b/package-lock.json index a709fae2..462ec2a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keepkey/device-protocol", - "version": "7.2.4", + "version": "7.14.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index e004b2d8..51f6d535 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@keepkey/device-protocol", - "version": "7.13.4", + "version": "7.14.1", "publishConfig": { "access": "public" },