Skip to content

Commit 98176a0

Browse files
author
Jamie C. Driver
committed
wallet: refactor calculating ga cosigner service bip32 path
Populate the root part of the path (dependent on the wallet root key) separately from deducing the path tail (dependent on user path).
1 parent 52912af commit 98176a0

File tree

2 files changed

+62
-33
lines changed

2 files changed

+62
-33
lines changed

main/wallet.c

Lines changed: 59 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -579,50 +579,77 @@ bool wallet_get_gaservice_fingerprint(const char* network, uint8_t* output, size
579579
return true;
580580
}
581581

582-
// Fetch the wallet's relevant gait service path based on the user signer's path
583-
bool wallet_get_gaservice_path(
584-
const uint32_t* path, const size_t path_len, uint32_t* ga_path, const size_t ga_path_len, size_t* written)
582+
static void wallet_get_gaservice_path_root(const bool subaccount_root, uint32_t* ga_path, const size_t ga_path_len)
585583
{
586-
if (!path || path_len == 0 || !ga_path || ga_path_len != MAX_GASERVICE_PATH_LEN || !written) {
587-
return false;
588-
}
584+
JADE_ASSERT(ga_path);
585+
JADE_ASSERT(ga_path_len == GASERVICE_ROOT_PATH_LEN);
589586

590587
const keychain_t* const keychain = keychain_get();
591588
JADE_ASSERT(keychain);
592589

593-
// We only support the following cases
594-
if (path_len == 2) {
595-
// 1. 1/ptr
596-
if (path[0] != PATH_BRANCH || path[1] >= MAX_PATH_PTR) {
597-
return false;
598-
}
590+
// The first element is 3 for subaccount paths, or 1 otherwise
591+
ga_path[0] = subaccount_root ? 3 : 1;
599592

600-
// gapath: 1/<ga service path (32)>/ptr
601-
ga_path[0] = path[0];
602-
// skip 1-32
603-
ga_path[33] = path[1];
604-
*written = 34;
593+
// GA service path goes in elements 1 - 32 incl.
594+
JADE_STATIC_ASSERT(sizeof(keychain->gaservice_path) == (ga_path_len - 1) * sizeof(ga_path[0]));
595+
memcpy(&ga_path[1], keychain->gaservice_path, sizeof(keychain->gaservice_path));
596+
}
597+
598+
static bool wallet_get_gaservice_path_tail(const uint32_t* path, const size_t path_len, uint32_t* ga_path,
599+
const size_t ga_path_len, size_t* written, bool* is_subaccount_path)
600+
{
601+
JADE_ASSERT(path);
602+
JADE_ASSERT(path_len);
603+
JADE_ASSERT(ga_path);
604+
JADE_ASSERT(ga_path_len >= MAX_GASERVICE_PATH_TAIL_LEN);
605+
JADE_ASSERT(written);
606+
JADE_ASSERT(is_subaccount_path);
607+
608+
// We only support the following cases - populate the path tail
609+
if (path_len == 2 && path[0] == PATH_BRANCH && path[1] < MAX_PATH_PTR) {
610+
// 1. 1/ptr
611+
// service path tail: ptr
612+
ga_path[0] = path[1];
613+
*written = 1;
614+
*is_subaccount_path = false;
615+
return true;
616+
}
605617

606-
} else if (path_len == 4) {
618+
if (path_len == 4 && path[0] == SUBACT_ROOT && path[1] > SUBACT_FLOOR && path[1] < SUBACT_CEILING
619+
&& path[2] == PATH_BRANCH && path[3] < MAX_PATH_PTR) {
607620
// 2. 3'/subact'/1/ptr
608-
if (path[0] != SUBACT_ROOT || path[1] <= SUBACT_FLOOR || path[1] >= SUBACT_CEILING || path[2] != PATH_BRANCH
609-
|| path[3] >= MAX_PATH_PTR) {
610-
return false;
611-
}
621+
// service path tail: subact/ptr
622+
ga_path[0] = unharden(path[1]);
623+
ga_path[1] = path[3];
624+
*written = 2;
625+
*is_subaccount_path = true;
626+
return true;
627+
}
612628

613-
// gapath: 3/<ga service path (32)>/subact/ptr
614-
ga_path[0] = unharden(path[0]);
615-
// skip 1-32
616-
ga_path[33] = unharden(path[1]);
617-
ga_path[34] = path[3];
618-
*written = 35;
619-
} else {
629+
// Path pattern not recognised
630+
return false;
631+
}
632+
633+
// Fetch the wallet's relevant gait service path based on the user signer's path
634+
bool wallet_get_gaservice_path(
635+
const uint32_t* path, const size_t path_len, uint32_t* ga_path, const size_t ga_path_len, size_t* written)
636+
{
637+
if (!path || path_len == 0 || !ga_path || ga_path_len != MAX_GASERVICE_PATH_LEN || !written) {
620638
return false;
621639
}
622640

623-
// GA service path goes in elements 1 - 32 incl.
624-
JADE_STATIC_ASSERT(sizeof(keychain->gaservice_path) == (ga_path_len - 1) * sizeof(ga_path[0]));
625-
memcpy(&ga_path[1], keychain->gaservice_path, sizeof(keychain->gaservice_path));
641+
// Populate the path tail based on the user path
642+
size_t tail_len = 0;
643+
bool is_subaccount_path = false;
644+
if (!wallet_get_gaservice_path_tail(path, path_len, &ga_path[GASERVICE_ROOT_PATH_LEN],
645+
ga_path_len - GASERVICE_ROOT_PATH_LEN, &tail_len, &is_subaccount_path)) {
646+
// Path pattern not recognised
647+
return false;
648+
}
649+
650+
// Populate GA service path root
651+
wallet_get_gaservice_path_root(is_subaccount_path, ga_path, GASERVICE_ROOT_PATH_LEN);
652+
*written = GASERVICE_ROOT_PATH_LEN + tail_len;
626653

627654
return true;
628655
}

main/wallet.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ typedef struct {
2323
} signing_data_t;
2424

2525
#define MAX_VARIANT_LEN 24
26-
#define MAX_GASERVICE_PATH_LEN 35
26+
#define GASERVICE_ROOT_PATH_LEN (1 + 32)
27+
#define MAX_GASERVICE_PATH_TAIL_LEN (1 + 1)
28+
#define MAX_GASERVICE_PATH_LEN (GASERVICE_ROOT_PATH_LEN + MAX_GASERVICE_PATH_TAIL_LEN)
2729

2830
// 'm' + ( ('/' + <10 digit number>[+ ']) * n) + '\0'
2931
#define MAX_PATH_STR_LEN(max_path_elems) (1 + ((1 + 10 + 1) * max_path_elems) + 1)

0 commit comments

Comments
 (0)