Skip to content

Commit d5e105a

Browse files
authored
feat(legacy): add support for aptos message sign (#219)
1 parent 38be335 commit d5e105a

File tree

13 files changed

+288
-1
lines changed

13 files changed

+288
-1
lines changed

common/protob/messages-aptos.proto

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,30 @@ message AptosSignedTx {
4141
required bytes public_key = 1; // public key for the private key used to sign tx
4242
required bytes signature = 2; // the signature of the raw transaction
4343
}
44+
45+
/**
46+
* Request: ask device to sign Aptos message
47+
* @start
48+
* @next AptosMessageSignature
49+
*/
50+
message AptosSignMessage {
51+
repeated uint32 address_n = 1;
52+
required AptosMessagePayload payload = 2;
53+
54+
message AptosMessagePayload {
55+
optional string address = 2;
56+
optional string chain_id = 3;
57+
optional string application = 4;
58+
required string nonce = 5;
59+
required string message = 6;
60+
}
61+
}
62+
63+
/**
64+
* Response: signature for message
65+
* @end
66+
**/
67+
message AptosMessageSignature {
68+
required bytes signature = 1;
69+
required string address = 2;
70+
}

common/protob/messages.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,8 @@ enum MessageType {
367367
MessageType_AptosAddress = 10601 [(wire_out) = true];
368368
MessageType_AptosSignTx = 10602 [(wire_in) = true];
369369
MessageType_AptosSignedTx = 10603 [(wire_out) = true];
370+
MessageType_AptosSignMessage = 10604 [(wire_in) = true];
371+
MessageType_AptosMessageSignature = 10605 [(wire_out) = true];
370372

371373
// WebAuthn
372374
MessageType_WebAuthnListResidentCredentials = 800 [(wire_in) = true];

core/src/trezor/enums/MessageType.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,8 @@
240240
AptosAddress = 10601
241241
AptosSignTx = 10602
242242
AptosSignedTx = 10603
243+
AptosSignMessage = 10604
244+
AptosMessageSignature = 10605
243245
WebAuthnListResidentCredentials = 800
244246
WebAuthnCredentials = 801
245247
WebAuthnAddResidentCredential = 802

core/src/trezor/enums/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ class MessageType(IntEnum):
245245
AptosAddress = 10601
246246
AptosSignTx = 10602
247247
AptosSignedTx = 10603
248+
AptosSignMessage = 10604
249+
AptosMessageSignature = 10605
248250
WebAuthnListResidentCredentials = 800
249251
WebAuthnCredentials = 801
250252
WebAuthnAddResidentCredential = 802

core/src/trezor/messages.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6254,6 +6254,60 @@ def __init__(
62546254
def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["AptosSignedTx"]:
62556255
return isinstance(msg, cls)
62566256

6257+
class AptosSignMessage(protobuf.MessageType):
6258+
address_n: "list[int]"
6259+
payload: "AptosMessagePayload"
6260+
6261+
def __init__(
6262+
self,
6263+
*,
6264+
payload: "AptosMessagePayload",
6265+
address_n: "list[int] | None" = None,
6266+
) -> None:
6267+
pass
6268+
6269+
@classmethod
6270+
def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["AptosSignMessage"]:
6271+
return isinstance(msg, cls)
6272+
6273+
class AptosMessageSignature(protobuf.MessageType):
6274+
signature: "bytes"
6275+
address: "str"
6276+
6277+
def __init__(
6278+
self,
6279+
*,
6280+
signature: "bytes",
6281+
address: "str",
6282+
) -> None:
6283+
pass
6284+
6285+
@classmethod
6286+
def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["AptosMessageSignature"]:
6287+
return isinstance(msg, cls)
6288+
6289+
class AptosMessagePayload(protobuf.MessageType):
6290+
address: "str | None"
6291+
chain_id: "str | None"
6292+
application: "str | None"
6293+
nonce: "str"
6294+
message: "str"
6295+
6296+
def __init__(
6297+
self,
6298+
*,
6299+
nonce: "str",
6300+
message: "str",
6301+
address: "str | None" = None,
6302+
chain_id: "str | None" = None,
6303+
application: "str | None" = None,
6304+
) -> None:
6305+
pass
6306+
6307+
@classmethod
6308+
def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["AptosMessagePayload"]:
6309+
return isinstance(msg, cls)
6310+
62576311
class NearGetAddress(protobuf.MessageType):
62586312
address_n: "list[int]"
62596313
show_display: "bool | None"

legacy/firmware/aptos.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ static const uint8_t APTOS_RAW_TX_PREFIX[32] = {
1515
54, 67, 169, 188, 111, 102, 147, 189, 220, 26, 159,
1616
236, 158, 103, 74, 70, 30, 170, 0, 177, 147};
1717

18+
static const char *MESSAGE_PREFIX = "APTOS\n";
19+
1820
void aptos_get_address_from_public_key(const uint8_t *public_key,
1921
char *address) {
2022
uint8_t buf[SIZE_PUBKEY] = {0};
@@ -52,3 +54,56 @@ void aptos_sign_tx(const AptosSignTx *msg, const HDNode *node,
5254
resp->public_key.size = 32;
5355
msg_write(MessageType_MessageType_AptosSignedTx, resp);
5456
}
57+
58+
void aptos_sign_message(const AptosSignMessage *msg, const HDNode *node,
59+
AptosMessageSignature *resp) {
60+
AptosMessagePayload payload = msg->payload;
61+
char full_message[sizeof(AptosMessagePayload) + 58] = {0};
62+
63+
strcat(full_message, MESSAGE_PREFIX);
64+
if (payload.has_address) {
65+
char *address = payload.address;
66+
strcat(full_message, "address: ");
67+
strcat(full_message, address);
68+
strcat(full_message, "\n");
69+
}
70+
if (payload.has_application) {
71+
char *application = payload.application;
72+
strcat(full_message, "application: ");
73+
strcat(full_message, application);
74+
strcat(full_message, "\n");
75+
}
76+
if (payload.has_chain_id) {
77+
char *chain_id = payload.chain_id;
78+
strcat(full_message, "chainId: ");
79+
strcat(full_message, chain_id);
80+
strcat(full_message, "\n");
81+
}
82+
char *message = payload.message;
83+
strcat(full_message, "message: ");
84+
strcat(full_message, message);
85+
strcat(full_message, "\n");
86+
char *nonce = payload.nonce;
87+
strcat(full_message, "nonce: ");
88+
strcat(full_message, nonce);
89+
90+
aptos_get_address_from_public_key(node->public_key + 1, resp->address);
91+
// display here
92+
layoutVerifyAddress(NULL, resp->address);
93+
if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) {
94+
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
95+
layoutHome();
96+
return;
97+
}
98+
if (!fsm_layoutSignMessage((const uint8_t *)full_message,
99+
strlen(full_message))) {
100+
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
101+
layoutHome();
102+
return;
103+
}
104+
ed25519_sign((const uint8_t *)full_message, strlen(full_message),
105+
node->private_key, node->public_key + 1, resp->signature.bytes);
106+
107+
resp->signature.size = 64;
108+
msg_write(MessageType_MessageType_AptosMessageSignature, resp);
109+
}

legacy/firmware/aptos.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,6 @@ void aptos_get_address_from_public_key(const uint8_t *public_key,
3232
char *address);
3333
void aptos_sign_tx(const AptosSignTx *msg, const HDNode *node,
3434
AptosSignedTx *resp);
35+
void aptos_sign_message(const AptosSignMessage *msg, const HDNode *node,
36+
AptosMessageSignature *resp);
3537
#endif // __APTOS_H__

legacy/firmware/fsm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ void fsm_msgTronSignTx(TronSignTx *msg);
176176
// aptos
177177
void fsm_msgAptosGetAddress(const AptosGetAddress *msg);
178178
void fsm_msgAptosSignTx(const AptosSignTx *msg);
179+
void fsm_msgAptosSignMessage(const AptosSignMessage *msg);
179180

180181
// near
181182
void fsm_msgNearGetAddress(NearGetAddress *msg);

legacy/firmware/fsm_msg_aptos.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,20 @@ void fsm_msgAptosSignTx(const AptosSignTx *msg) {
6262

6363
layoutHome();
6464
}
65+
66+
void fsm_msgAptosSignMessage(const AptosSignMessage *msg) {
67+
CHECK_INITIALIZED
68+
69+
CHECK_PIN
70+
RESP_INIT(AptosMessageSignature)
71+
72+
HDNode *node = fsm_getDerivedNode(ED25519_NAME, msg->address_n,
73+
msg->address_n_count, NULL);
74+
if (!node) return;
75+
76+
hdnode_fill_public_key(node);
77+
78+
aptos_sign_message(msg, node, resp);
79+
80+
layoutHome();
81+
}

legacy/firmware/protob/messages-aptos.options

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,13 @@ AptosSignTx.raw_tx max_size:1024
66

77
AptosSignedTx.public_key max_size:32
88
AptosSignedTx.signature max_size:64
9+
10+
AptosSignMessage.address_n max_count:8
11+
AptosMessagePayload.address max_size:67
12+
AptosMessagePayload.chain_id max_size: 8
13+
AptosMessagePayload.application max_size:128
14+
AptosMessagePayload.nonce max_size:64
15+
AptosMessagePayload.message max_size:1024
16+
17+
AptosMessageSignature.signature max_size:64
18+
AptosMessageSignature.address max_size:67

0 commit comments

Comments
 (0)