Skip to content

Commit 0b451e9

Browse files
author
Jamie C. Driver
committed
wallet: move function to deduce ga service path to wallet.c
Logic that pertains to wallet operations, including logic specific to Green multisig, should be contained in wallet.c rather than keychain.c
1 parent 1b08fd9 commit 0b451e9

File tree

3 files changed

+36
-30
lines changed

3 files changed

+36
-30
lines changed

main/keychain.c

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "storage.h"
99
#include "utils/malloc_ext.h"
1010
#include "utils/network.h"
11+
#include "wallet.h"
1112

1213
#include <sodium/crypto_verify_32.h>
1314
#include <string.h>
@@ -20,10 +21,6 @@
2021
// Encrypted length plus hmac (input length given)
2122
#define ENCRYPTED_DATA_LEN(len) (AES_ENCRYPTED_LEN(len) + HMAC_SHA256_LEN)
2223

23-
// GA derived key index, and fixed GA key message
24-
static const uint32_t GA_PATH_ROOT = BIP32_INITIAL_HARDENED_CHILD + 0x4741;
25-
static const uint8_t GA_KEY_MSG[] = "GreenAddress.it HD wallet path";
26-
2724
// Internal variables - the single/global keychain data
2825
static keychain_t* keychain_data = NULL;
2926
static network_type_t network_type_restriction = NETWORK_TYPE_NONE;
@@ -245,31 +242,6 @@ bool keychain_is_network_type_consistent(const char* network)
245242
return network_type_restriction == NETWORK_TYPE_NONE || network_type == network_type_restriction;
246243
}
247244

248-
// Helper to create the service/gait path.
249-
// (The below is correct for newly created wallets, verified in regtest).
250-
static void populate_service_path(keychain_t* keydata)
251-
{
252-
JADE_ASSERT(keydata);
253-
254-
// 1. Derive a child of our private key using the fixed GA index
255-
struct ext_key derived;
256-
SENSITIVE_PUSH(&derived, sizeof(derived));
257-
JADE_WALLY_VERIFY(bip32_key_from_parent_path(
258-
&keydata->xpriv, &GA_PATH_ROOT, 1, BIP32_FLAG_KEY_PRIVATE | BIP32_FLAG_SKIP_HASH, &derived));
259-
260-
// 2. Get it as an 'extended public key' byte-array
261-
uint8_t extkeydata[sizeof(derived.chain_code) + sizeof(derived.pub_key)];
262-
SENSITIVE_PUSH(extkeydata, sizeof(extkeydata));
263-
memcpy(extkeydata, derived.chain_code, sizeof(derived.chain_code));
264-
memcpy(extkeydata + sizeof(derived.chain_code), derived.pub_key, sizeof(derived.pub_key));
265-
266-
// 3. HMAC the fixed GA key message with 2. to yield the 512-bit 'service path' for this mnemonic/private key
267-
JADE_WALLY_VERIFY(wally_hmac_sha512(GA_KEY_MSG, sizeof(GA_KEY_MSG), extkeydata, sizeof(extkeydata),
268-
keydata->service_path, sizeof(keydata->service_path)));
269-
SENSITIVE_POP(extkeydata);
270-
SENSITIVE_POP(&derived);
271-
}
272-
273245
void keychain_get_new_mnemonic(char** mnemonic, const size_t nwords)
274246
{
275247
JADE_INIT_OUT_PPTR(mnemonic);
@@ -311,7 +283,7 @@ void keychain_derive_from_seed(const uint8_t* seed, const size_t seed_len, keych
311283
wally_asset_blinding_key_from_seed(seed, seed_len, keydata->master_unblinding_key, HMAC_SHA512_LEN));
312284

313285
// Compute and cache the path the GA server will use to sign
314-
populate_service_path(keydata);
286+
wallet_calculate_gaservice_path(&keydata->xpriv, keydata->service_path, sizeof(keydata->service_path));
315287
}
316288

317289
// Derive master key from mnemonic if passed a valid mnemonic

main/wallet.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
#include <mbedtls/base64.h>
2828
#include <sodium/utils.h>
2929

30+
// GA derived key index, and fixed GA key message
31+
static const uint32_t GA_PATH_ROOT = BIP32_INITIAL_HARDENED_CHILD + 0x4741;
32+
static const uint8_t GA_KEY_MSG[] = "GreenAddress.it HD wallet path";
33+
3034
// Restrictions on GA BIP32 path elements
3135
static const uint32_t SUBACT_ROOT = BIP32_INITIAL_HARDENED_CHILD + 3;
3236
static const uint32_t SUBACT_FLOOR = BIP32_INITIAL_HARDENED_CHILD;
@@ -496,6 +500,35 @@ void wallet_build_receive_path(const uint32_t subaccount, const uint32_t branch,
496500
}
497501
}
498502

503+
// Helper to create the service/gait path.
504+
// (The below is correct for newly created wallets, verified in regtest).
505+
bool wallet_calculate_gaservice_path(struct ext_key* root_key, uint8_t* service_path, const size_t service_path_len)
506+
{
507+
if (!root_key || !service_path || service_path_len != HMAC_SHA512_LEN) {
508+
return false;
509+
}
510+
511+
// 1. Derive a child of the private key using the fixed GA index
512+
struct ext_key derived;
513+
SENSITIVE_PUSH(&derived, sizeof(derived));
514+
JADE_WALLY_VERIFY(bip32_key_from_parent_path(
515+
root_key, &GA_PATH_ROOT, 1, BIP32_FLAG_KEY_PRIVATE | BIP32_FLAG_SKIP_HASH, &derived));
516+
517+
// 2. Get it as an 'extended public key' byte-array
518+
uint8_t extkeydata[sizeof(derived.chain_code) + sizeof(derived.pub_key)];
519+
SENSITIVE_PUSH(extkeydata, sizeof(extkeydata));
520+
memcpy(extkeydata, derived.chain_code, sizeof(derived.chain_code));
521+
memcpy(extkeydata + sizeof(derived.chain_code), derived.pub_key, sizeof(derived.pub_key));
522+
523+
// 3. HMAC the fixed GA key message with 2. to yield the 512-bit 'service path' for this mnemonic/private key
524+
JADE_WALLY_VERIFY(wally_hmac_sha512(
525+
GA_KEY_MSG, sizeof(GA_KEY_MSG), extkeydata, sizeof(extkeydata), service_path, service_path_len));
526+
SENSITIVE_POP(extkeydata);
527+
SENSITIVE_POP(&derived);
528+
529+
return true;
530+
}
531+
499532
bool wallet_get_gaservice_fingerprint(const char* network, uint8_t* output, size_t output_len)
500533
{
501534
JADE_ASSERT(network);

main/wallet.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ void wallet_get_fingerprint(uint8_t* output, size_t output_len);
8989
bool wallet_get_hdkey(const uint32_t* path, size_t path_len, uint32_t flags, struct ext_key* output);
9090
bool wallet_get_xpub(const char* network, const uint32_t* path, size_t path_len, char** output);
9191

92+
bool wallet_calculate_gaservice_path(struct ext_key* root_key, uint8_t* service_path, size_t service_path_len);
9293
bool wallet_get_gaservice_fingerprint(const char* network, uint8_t* output, size_t output_len);
9394
bool wallet_get_gaservice_path(
9495
const uint32_t* path, size_t path_len, uint32_t* ga_path, size_t ga_path_len, size_t* written);

0 commit comments

Comments
 (0)