Skip to content

Commit 601c6ff

Browse files
committed
feat(core): misc features add
1. expand the batch public key export interface to include BIP32 node info 2. add support for getting the Kaspa address the same as official ones 3. adjust the default auto shut-down time to 5 minutes
1 parent 3f602a8 commit 601c6ff

File tree

12 files changed

+98
-30
lines changed

12 files changed

+98
-30
lines changed

common/protob/messages-crypto.proto

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ option java_outer_classname = "TrezorMessageCrypto";
88
option (include_in_bitcoin_only) = true;
99

1010
import "messages.proto";
11-
11+
import "messages-common.proto";
1212
/**
1313
* Request: Ask device to encrypt or decrypt value of given key
1414
* @start
@@ -143,6 +143,7 @@ message BatchGetPublickeys {
143143
}
144144
optional string ecdsa_curve_name = 1 [default="ed25519"];
145145
repeated Path paths = 2;
146+
optional bool include_node = 3 [default=false];
146147
}
147148

148149
/**
@@ -151,4 +152,6 @@ message BatchGetPublickeys {
151152
*/
152153
message EcdsaPublicKeys {
153154
repeated bytes public_keys = 1;
155+
repeated common.HDNodeType hd_nodes = 2;
156+
optional uint32 root_fingerprint = 3;
154157
}

common/protob/messages-kaspa.proto

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ message KaspaGetAddress {
1515
repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
1616
optional bool show_display = 2; // optionally show on display before sending the result
1717
optional string prefix = 3 [default="kaspa"]; // prefix for address
18-
optional string scheme = 4 [default="schnorr"]; // address scheme
18+
optional string scheme = 4 [default="schnorr"]; // address scheme
19+
optional bool use_tweak = 5 [default=true]; // use bip340 tweak
1920
}
2021

2122
/**
@@ -38,7 +39,8 @@ message KaspaSignTx {
3839
required bytes raw_message = 2; // the bip143-like pre-hashed message to be signed
3940
optional string scheme = 3 [default="schnorr"]; // signature scheme
4041
optional string prefix = 4 [default="kaspa"]; // prefix for address
41-
optional uint32 input_count = 5 [default=1]; // number of inputs in the transaction
42+
optional uint32 input_count = 5 [default=1]; // number of inputs in the transaction
43+
optional bool use_tweak = 6 [default=true]; // use bip340 tweak
4244
}
4345

4446
/**

core/embed/firmware/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ int main(void) {
199199
mp_stack_set_limit((char *)&_estack - (char *)&_sstack - 1024);
200200

201201
#if MICROPY_ENABLE_PYSTACK
202-
static mp_obj_t pystack[1024];
202+
static mp_obj_t pystack[2048];
203203
mp_pystack_init(pystack, &pystack[MP_ARRAY_SIZE(pystack)]);
204204
#endif
205205

core/src/all_modules.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,8 @@
773773
import apps.solana.spl.memo.memo_program
774774
apps.solana.spl.spl_token_program
775775
import apps.solana.spl.spl_token_program
776+
apps.solana.spl.spl_tokens
777+
import apps.solana.spl.spl_tokens
776778
apps.solana.stake.program
777779
import apps.solana.stake.program
778780
apps.solana.system._layouts

core/src/apps/kaspa/addresses.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,20 @@ def is_valid(cls, prefix: str) -> bool:
3939

4040
def encode_address(
4141
node: bip32.HDNode,
42-
schema: str,
42+
scheme: str,
4343
prefix: str = Prefix.Mainnet,
44+
use_tweak: bool = True,
4445
) -> str:
45-
if schema == "schnorr":
46-
pubkey = bip340.tweak_public_key(node.public_key()[1:])
46+
raw_pubkey = node.public_key()
47+
if scheme == "schnorr":
48+
pubkey = (
49+
bip340.tweak_public_key(raw_pubkey[1:]) if use_tweak else raw_pubkey[1:]
50+
)
4751
assert len(pubkey) == Version.public_key_len(Version.PubKey)
4852
version = Version.PubKey
4953
else:
50-
pubkey = node.public_key()
54+
pubkey = raw_pubkey
5155
assert len(pubkey) == Version.public_key_len(Version.PubKeyECDSA)
5256
version = Version.PubKeyECDSA
5357

54-
address = cashaddr.encode(prefix, version, pubkey)
55-
return address
58+
return cashaddr.encode(prefix, version, pubkey)

core/src/apps/kaspa/get_address.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,12 @@ async def get_address(
3030
if msg.scheme not in ALLOWED_SCHEMES:
3131
raise wire.DataError("Invalid address scheme provided.")
3232
node = keychain.derive(msg.address_n)
33-
address = encode_address(node, prefix=msg.prefix, schema=msg.scheme)
33+
address = encode_address(
34+
node,
35+
prefix=msg.prefix,
36+
scheme=msg.scheme,
37+
use_tweak=getattr(msg, "use_tweak", True),
38+
)
3439

3540
if msg.show_display:
3641
path = paths.address_n_to_str(msg.address_n)

core/src/apps/kaspa/sign_tx.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from trezor.messages import KaspaSignedTx, KaspaTxInputAck, KaspaTxInputRequest
66
from trezor.ui.layouts import confirm_blind_sign_common, confirm_final
77

8-
from apps.bitcoin.common import bip340_sign, ecdsa_sign
8+
from apps.bitcoin.common import bip340_sign, bip340_sign_internal, ecdsa_sign
99
from apps.common import paths
1010
from apps.common.keychain import auto_keychain
1111

@@ -37,15 +37,16 @@ async def sign_tx(
3737
raise wire.DataError("Invalid prefix provided.")
3838

3939
ctx.primary_color, ctx.icon_path = lv.color_hex(PRIMARY_COLOR), ICON
40-
global address_prefix, schema, addresses, request_index, input_count
40+
global address_prefix, scheme, addresses, request_index, input_count
4141
address_prefix = msg.prefix
42-
schema = msg.scheme
42+
scheme = msg.scheme
4343
input_count = msg.input_count
4444
request_index = 0
4545
addresses = []
4646
signature = b""
47+
use_tweak = getattr(msg, "use_tweak", True)
4748
while input_count > 0:
48-
signature = await sign_input(ctx, msg, keychain)
49+
signature = await sign_input(ctx, msg, keychain, use_tweak=use_tweak)
4950
input_count -= 1
5051
request_index += 1
5152
if input_count > 0:
@@ -62,25 +63,31 @@ async def sign_tx(
6263
return KaspaSignedTx(signature=signature)
6364

6465

65-
async def sign_input(ctx, msg: Signable, keychain) -> bytes:
66+
async def sign_input(ctx, msg: Signable, keychain, use_tweak: bool = True) -> bytes:
6667
await paths.validate_path(ctx, keychain, msg.address_n)
6768
node = keychain.derive(msg.address_n)
6869
hasher = hashwriter()
6970
hasher.write(msg.raw_message)
7071
sig_hash = hasher.get_digest()
7172

72-
if schema == "ecdsa":
73+
if scheme == "ecdsa":
7374
hasher_ecdsa = hashwriter_ecdsa()
7475
hasher_ecdsa.write(sig_hash)
7576
sig_hash = hasher_ecdsa.get_digest()
7677

77-
address = encode_address(node, prefix=address_prefix, schema=schema)
78+
address = encode_address(
79+
node, prefix=address_prefix, scheme=scheme, use_tweak=use_tweak
80+
)
7881
if msg.address_n not in addresses:
7982
addresses.append(msg.address_n)
8083
await confirm_blind_sign_common(ctx, address, msg.raw_message)
8184

82-
if schema == "schnorr":
83-
signature = bip340_sign(node, sig_hash)
85+
if scheme == "schnorr":
86+
signature = (
87+
bip340_sign(node, sig_hash)
88+
if use_tweak
89+
else bip340_sign_internal(node, sig_hash)
90+
)
8491
else:
8592
signature = ecdsa_sign(node, sig_hash)
8693
return signature

core/src/apps/misc/batch_get_pubkeys.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import TYPE_CHECKING
22

33
from trezor import wire
4-
from trezor.messages import EcdsaPublicKeys
4+
from trezor.messages import EcdsaPublicKeys, HDNodeType
55

66
from apps.common import paths
77
from apps.common.keychain import get_keychain
@@ -21,16 +21,37 @@ async def batch_get_pubkeys(
2121
validate(msg)
2222
keychain = await get_keychain(ctx, msg.ecdsa_curve_name, [AlwaysMatchingSchema])
2323
pubkeys = []
24-
24+
nodes = []
2525
translator = (
2626
(lambda pubkey: pubkey)
2727
if "secp256k1" == msg.ecdsa_curve_name
2828
else (lambda pubkey: pubkey[1:])
2929
)
30+
include_node = False
31+
root_fingerprint = None
32+
if "ed25519" not in msg.ecdsa_curve_name and msg.include_node:
33+
include_node = True
34+
root_fingerprint = keychain.root_fingerprint()
3035
for path in msg.paths:
3136
node = keychain.derive(path.address_n)
32-
pubkeys.append(translator(node.public_key()))
33-
return EcdsaPublicKeys(public_keys=pubkeys)
37+
pubkey = translator(node.public_key())
38+
if include_node:
39+
nodes.append(
40+
HDNodeType(
41+
depth=node.depth(),
42+
child_num=node.child_num(),
43+
fingerprint=node.fingerprint(),
44+
chain_code=node.chain_code(),
45+
public_key=pubkey,
46+
)
47+
)
48+
else:
49+
pubkeys.append(pubkey)
50+
return EcdsaPublicKeys(
51+
public_keys=pubkeys or None,
52+
hd_nodes=nodes or None,
53+
root_fingerprint=root_fingerprint,
54+
)
3455

3556

3657
def validate(msg: BatchGetPublickeys):

core/src/storage/device.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@
7474
AUTOSHUTDOWN_DELAY_MINIMUM = 60 * 1000 # 1 minute
7575
AUTOLOCK_DELAY_MINIMUM = 30 * 1000 # 30 seconds
7676

77-
AUTOSHUTDOWN_DELAY_DEFAULT = 10 * 60 * 1000 # 10 minutes
77+
AUTOSHUTDOWN_DELAY_DEFAULT = 5 * 60 * 1000 # 5 minutes
7878
AUTOLOCK_DELAY_DEFAULT = 60 * 1000 # 1 minute
7979
# autolock intervals larger than AUTOLOCK_DELAY_MAXIMUM cause issues in the scheduler
80-
if __debug__:
81-
AUTOSHUTDOWN_DELAY_MAXIMUM = AUTOLOCK_DELAY_MAXIMUM = const(0x2000_0000) # ~6 days
82-
else:
83-
AUTOSHUTDOWN_DELAY_MAXIMUM = AUTOLOCK_DELAY_MAXIMUM = 0x1000_0000 # ~3 days
80+
# if __debug__:
81+
# AUTOSHUTDOWN_DELAY_MAXIMUM = AUTOLOCK_DELAY_MAXIMUM = const(0x2000_0000) # ~6 days
82+
# else:
83+
AUTOSHUTDOWN_DELAY_MAXIMUM = AUTOLOCK_DELAY_MAXIMUM = 0x1000_0000 # ~3 days
8484

8585
# Length of SD salt auth tag.
8686
# Other SD-salt-related constants are in sd_salt.py

core/src/trezor/messages.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2546,12 +2546,14 @@ def is_type_of(cls, msg: Any) -> TypeGuard["CosiSignature"]:
25462546
class BatchGetPublickeys(protobuf.MessageType):
25472547
ecdsa_curve_name: "str"
25482548
paths: "list[Path]"
2549+
include_node: "bool"
25492550

25502551
def __init__(
25512552
self,
25522553
*,
25532554
paths: "list[Path] | None" = None,
25542555
ecdsa_curve_name: "str | None" = None,
2556+
include_node: "bool | None" = None,
25552557
) -> None:
25562558
pass
25572559

@@ -2561,11 +2563,15 @@ def is_type_of(cls, msg: Any) -> TypeGuard["BatchGetPublickeys"]:
25612563

25622564
class EcdsaPublicKeys(protobuf.MessageType):
25632565
public_keys: "list[bytes]"
2566+
hd_nodes: "list[HDNodeType]"
2567+
root_fingerprint: "int | None"
25642568

25652569
def __init__(
25662570
self,
25672571
*,
25682572
public_keys: "list[bytes] | None" = None,
2573+
hd_nodes: "list[HDNodeType] | None" = None,
2574+
root_fingerprint: "int | None" = None,
25692575
) -> None:
25702576
pass
25712577

@@ -5414,6 +5420,7 @@ class KaspaGetAddress(protobuf.MessageType):
54145420
show_display: "bool | None"
54155421
prefix: "str"
54165422
scheme: "str"
5423+
use_tweak: "bool"
54175424

54185425
def __init__(
54195426
self,
@@ -5422,6 +5429,7 @@ def __init__(
54225429
show_display: "bool | None" = None,
54235430
prefix: "str | None" = None,
54245431
scheme: "str | None" = None,
5432+
use_tweak: "bool | None" = None,
54255433
) -> None:
54265434
pass
54275435

@@ -5449,6 +5457,7 @@ class KaspaSignTx(protobuf.MessageType):
54495457
scheme: "str"
54505458
prefix: "str"
54515459
input_count: "int"
5460+
use_tweak: "bool"
54525461

54535462
def __init__(
54545463
self,
@@ -5458,6 +5467,7 @@ def __init__(
54585467
scheme: "str | None" = None,
54595468
prefix: "str | None" = None,
54605469
input_count: "int | None" = None,
5470+
use_tweak: "bool | None" = None,
54615471
) -> None:
54625472
pass
54635473

0 commit comments

Comments
 (0)