Only compute pubkey on demand.

Changed all hdnode callers to call hdnode_fill_public_key if
they need the public key.
pull/25/head
Jochen Hoenicke 8 years ago
parent c6309ff93c
commit ae4dff6e5f

@ -85,13 +85,13 @@ uint32_t deser_length(const uint8_t *in, uint32_t *out)
return 1 + 8;
}
int sshMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature)
int sshMessageSign(HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature)
{
signature[0] = 0; // prefix: pad with zero, so all signatures are 65 bytes
return hdnode_sign(node, message, message_len, signature + 1, NULL);
}
int gpgMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature)
int gpgMessageSign(HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature)
{
// GPG should sign a SHA256 digest of the original message.
if (message_len != 32) {
@ -120,7 +120,7 @@ int cryptoGetECDHSessionKey(const HDNode *node, const uint8_t *peer_public_key,
return 0;
}
int cryptoMessageSign(const CoinType *coin, const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature)
int cryptoMessageSign(const CoinType *coin, HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature)
{
SHA256_CTX ctx;
sha256_Init(&ctx);
@ -294,7 +294,7 @@ uint8_t *cryptoHDNodePathToPubkey(const HDNodePathType *hdnodepath)
{
if (!hdnodepath->node.has_public_key || hdnodepath->node.public_key.size != 33) return 0;
static HDNode node;
if (hdnode_from_xpub(hdnodepath->node.depth, hdnodepath->node.fingerprint, hdnodepath->node.child_num, hdnodepath->node.chain_code.bytes, hdnodepath->node.public_key.bytes, SECP256K1_NAME, &node) == 0) {
if (hdnode_from_xpub(hdnodepath->node.depth, hdnodepath->node.child_num, hdnodepath->node.chain_code.bytes, hdnodepath->node.public_key.bytes, SECP256K1_NAME, &node) == 0) {
return 0;
}
layoutProgressUpdate(true);

@ -33,14 +33,14 @@ uint32_t ser_length(uint32_t len, uint8_t *out);
uint32_t ser_length_hash(SHA256_CTX *ctx, uint32_t len);
int sshMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature);
int sshMessageSign(HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature);
int gpgMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature);
int gpgMessageSign(HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature);
int cryptoGetECDHSessionKey(const HDNode *node, const uint8_t *peer_public_key, uint8_t *session_key);
int cryptoMessageSign(const CoinType *coin, const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature);
int cryptoMessageSign(const CoinType *coin, HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature);
int cryptoMessageVerify(const CoinType *coin, const uint8_t *message, size_t message_len, const uint8_t *address_raw, const uint8_t *signature);

@ -94,7 +94,7 @@ const CoinType *fsm_getCoin(const char *name)
return coin;
}
const HDNode *fsm_getDerivedNode(const char *curve, uint32_t *address_n, size_t address_n_count)
HDNode *fsm_getDerivedNode(const char *curve, uint32_t *address_n, size_t address_n_count)
{
static HDNode node;
if (!storage_getRootNode(&node, curve, true)) {
@ -298,8 +298,21 @@ void fsm_msgGetPublicKey(GetPublicKey *msg)
if (msg->has_ecdsa_curve_name) {
curve = msg->ecdsa_curve_name;
}
const HDNode *node = fsm_getDerivedNode(curve, msg->address_n, msg->address_n_count);
if (!node) return;
uint32_t fpr;
HDNode *node;
if (msg->address_n_count == 0) {
/* get master node */
fpr = 0;
node = fsm_getDerivedNode(curve, msg->address_n, 0);
} else {
/* get parent node */
node = fsm_getDerivedNode(curve, msg->address_n, msg->address_n_count - 1);
if (!node) return;
fpr = hdnode_fingerprint(node);
/* get child */
hdnode_private_ckd(node, msg->address_n[msg->address_n_count - 1]);
}
hdnode_fill_public_key(node);
if (msg->has_show_display && msg->show_display) {
layoutPublicKey(node->public_key);
@ -311,7 +324,7 @@ void fsm_msgGetPublicKey(GetPublicKey *msg)
}
resp->node.depth = node->depth;
resp->node.fingerprint = node->fingerprint;
resp->node.fingerprint = fpr;
resp->node.child_num = node->child_num;
resp->node.chain_code.size = 32;
memcpy(resp->node.chain_code.bytes, node->chain_code, 32);
@ -319,8 +332,12 @@ void fsm_msgGetPublicKey(GetPublicKey *msg)
resp->node.has_public_key = true;
resp->node.public_key.size = 33;
memcpy(resp->node.public_key.bytes, node->public_key, 33);
if (node->public_key[0] == 1) {
/* ed25519 public key */
resp->node.public_key.bytes[0] = 0;
}
resp->has_xpub = true;
hdnode_serialize_public(node, resp->xpub, sizeof(resp->xpub));
hdnode_serialize_public(node, fpr, resp->xpub, sizeof(resp->xpub));
msg_write(MessageType_MessageType_PublicKey, resp);
layoutHome();
}
@ -561,8 +578,9 @@ void fsm_msgGetAddress(GetAddress *msg)
const CoinType *coin = fsm_getCoin(msg->coin_name);
if (!coin) return;
const HDNode *node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n, msg->address_n_count);
HDNode *node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n, msg->address_n_count);
if (!node) return;
hdnode_fill_public_key(node);
if (msg->has_multisig) {
layoutProgressSwipe("Preparing", 0);
@ -641,14 +659,14 @@ void fsm_msgSignMessage(SignMessage *msg)
const CoinType *coin = fsm_getCoin(msg->coin_name);
if (!coin) return;
const HDNode *node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n, msg->address_n_count);
HDNode *node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n, msg->address_n_count);
if (!node) return;
layoutProgressSwipe("Signing", 0);
if (cryptoMessageSign(coin, node, msg->message.bytes, msg->message.size, resp->signature.bytes) == 0) {
resp->has_address = true;
uint8_t addr_raw[21];
ecdsa_get_address_raw(node->public_key, coin->address_type, addr_raw);
hdnode_get_address_raw(node, coin->address_type, addr_raw);
base58_encode_check(addr_raw, 21, resp->address, sizeof(resp->address));
resp->has_signature = true;
resp->signature.size = 65;
@ -735,7 +753,7 @@ void fsm_msgSignIdentity(SignIdentity *msg)
if (msg->has_ecdsa_curve_name) {
curve = msg->ecdsa_curve_name;
}
const HDNode *node = fsm_getDerivedNode(curve, address_n, 5);
HDNode *node = fsm_getDerivedNode(curve, address_n, 5);
if (!node) return;
bool sign_ssh = msg->identity.has_proto && (strcmp(msg->identity.proto, "ssh") == 0);
@ -755,17 +773,22 @@ void fsm_msgSignIdentity(SignIdentity *msg)
}
if (result == 0) {
hdnode_fill_public_key(node);
if (strcmp(curve, SECP256K1_NAME) != 0) {
resp->has_address = false;
} else {
resp->has_address = true;
uint8_t addr_raw[21];
ecdsa_get_address_raw(node->public_key, 0x00, addr_raw); // hardcoded Bitcoin address type
hdnode_get_address_raw(node, 0x00, addr_raw); // hardcoded Bitcoin address type
base58_encode_check(addr_raw, 21, resp->address, sizeof(resp->address));
}
resp->has_public_key = true;
resp->public_key.size = 33;
memcpy(resp->public_key.bytes, node->public_key, 33);
if (node->public_key[0] == 1) {
/* ed25519 public key */
resp->public_key.bytes[0] = 0;
}
resp->has_signature = true;
resp->signature.size = 65;
msg_write(MessageType_MessageType_SignedIdentity, resp);
@ -859,9 +882,7 @@ void fsm_msgEncryptMessage(EncryptMessage *msg)
}
node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n, msg->address_n_count);
if (!node) return;
uint8_t public_key[33];
ecdsa_get_public_key33(&secp256k1, node->private_key, public_key);
ecdsa_get_address_raw(public_key, coin->address_type, address_raw);
hdnode_get_address_raw(node, coin->address_type, address_raw);
}
layoutEncryptMessage(msg->message.bytes, msg->message.size, signing);
if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) {

@ -471,6 +471,7 @@ void signing_txack(TransactionType *tx)
signing_abort();
return;
}
hdnode_fill_public_key(&node);
if (tx->inputs[0].script_type == InputScriptType_SPENDMULTISIG) {
if (!tx->inputs[0].has_multisig) {
fsm_sendFailure(FailureType_Failure_Other, "Multisig info not provided");

@ -361,7 +361,7 @@ bool storage_getRootNode(HDNode *node, const char *curve, bool usePassphrase)
if (!protectPassphrase()) {
return false;
}
if (hdnode_from_xprv(storage.node.depth, storage.node.fingerprint, storage.node.child_num, storage.node.chain_code.bytes, storage.node.private_key.bytes, curve, node) == 0) {
if (hdnode_from_xprv(storage.node.depth, storage.node.child_num, storage.node.chain_code.bytes, storage.node.private_key.bytes, curve, node) == 0) {
return false;
}
if (storage.has_passphrase_protection && storage.passphrase_protection && sessionPassphraseCached && strlen(sessionPassphrase) > 0) {

@ -71,7 +71,7 @@ int compile_output(const CoinType *coin, const HDNode *root, TxOutputType *in, T
return 0;
}
layoutProgressUpdate(true);
ecdsa_get_address_raw(node.public_key, coin->address_type, addr_raw);
hdnode_get_address_raw(&node, coin->address_type, addr_raw);
} else
if (in->has_address) { // address provided -> regular output
if (needs_confirm) {

@ -1 +1 @@
Subproject commit 16f477787d7e59a37e0f05807182cef8aeb1e2d5
Subproject commit 3390fcf89e5502d6087a8b0d182fc9db05bbd759
Loading…
Cancel
Save