mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 15:38:11 +00:00
update protobuf, disable SimpleSignTx
This commit is contained in:
parent
80ab3b40b4
commit
7cba60895d
131
firmware/fsm.c
131
firmware/fsm.c
@ -343,131 +343,6 @@ void fsm_msgSignTx(SignTx *msg)
|
||||
signing_init(msg->inputs_count, msg->outputs_count, coin, node);
|
||||
}
|
||||
|
||||
void fsm_msgSimpleSignTx(SimpleSignTx *msg)
|
||||
{
|
||||
RESP_INIT(TxRequest);
|
||||
|
||||
if (msg->inputs_count < 1) {
|
||||
fsm_sendFailure(FailureType_Failure_Other, "Transaction must have at least one input");
|
||||
layoutHome();
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg->outputs_count < 1) {
|
||||
fsm_sendFailure(FailureType_Failure_Other, "Transaction must have at least one output");
|
||||
layoutHome();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!protectPin(true)) {
|
||||
layoutHome();
|
||||
return;
|
||||
}
|
||||
|
||||
HDNode *node = fsm_getRootNode();
|
||||
if (!node) return;
|
||||
const CoinType *coin = coinByName(msg->coin_name);
|
||||
if (!coin) {
|
||||
fsm_sendFailure(FailureType_Failure_Other, "Invalid coin name");
|
||||
layoutHome();
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t version = 1;
|
||||
uint32_t lock_time = 0;
|
||||
int tx_size = transactionSimpleSign(coin, node, msg->inputs, msg->inputs_count, msg->outputs, msg->outputs_count, version, lock_time, resp->serialized.serialized_tx.bytes);
|
||||
if (tx_size < 0) {
|
||||
fsm_sendFailure(FailureType_Failure_Other, "Signing cancelled by user");
|
||||
layoutHome();
|
||||
return;
|
||||
}
|
||||
if (tx_size == 0) {
|
||||
fsm_sendFailure(FailureType_Failure_Other, "Error signing transaction");
|
||||
layoutHome();
|
||||
return;
|
||||
}
|
||||
|
||||
size_t i, j;
|
||||
|
||||
// determine change address
|
||||
uint64_t change_spend = 0;
|
||||
for (i = 0; i < msg->outputs_count; i++) {
|
||||
if (msg->outputs[i].address_n_count > 0) { // address_n set -> change address
|
||||
if (change_spend == 0) { // not set
|
||||
change_spend = msg->outputs[i].amount;
|
||||
} else {
|
||||
fsm_sendFailure(FailureType_Failure_Other, "Only one change output allowed");
|
||||
layoutHome();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check origin transactions
|
||||
uint8_t prev_hashes[ pb_arraysize(SimpleSignTx, transactions) ][32];
|
||||
for (i = 0; i < msg->transactions_count; i++) {
|
||||
if (!transactionHash(&(msg->transactions[i]), prev_hashes[i])) {
|
||||
memset(prev_hashes[i], 0, 32);
|
||||
}
|
||||
}
|
||||
|
||||
// calculate spendings
|
||||
uint64_t to_spend = 0;
|
||||
bool found;
|
||||
for (i = 0; i < msg->inputs_count; i++) {
|
||||
found = false;
|
||||
for (j = 0; j < msg->transactions_count; j++) {
|
||||
if (memcmp(msg->inputs[i].prev_hash.bytes, prev_hashes[j], 32) == 0) { // found prev TX
|
||||
if (msg->inputs[i].prev_index < msg->transactions[j].bin_outputs_count) {
|
||||
to_spend += msg->transactions[j].bin_outputs[msg->inputs[i].prev_index].amount;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
fsm_sendFailure(FailureType_Failure_Other, "Invalid prevhash");
|
||||
layoutHome();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t spending = 0;
|
||||
for (i = 0; i < msg->outputs_count; i++) {
|
||||
spending += msg->outputs[i].amount;
|
||||
}
|
||||
if (spending > to_spend) {
|
||||
fsm_sendFailure(FailureType_Failure_NotEnoughFunds, "Not enough funds");
|
||||
layoutHome();
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t fee = to_spend - spending;
|
||||
if (fee > (((uint64_t)tx_size + 999) / 1000) * coin->maxfee_kb) {
|
||||
layoutFeeOverThreshold(coin, fee, ((uint64_t)tx_size + 999) / 1000);
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_FeeOverThreshold, false)) {
|
||||
fsm_sendFailure(FailureType_Failure_ActionCancelled, "Fee over threshold. Signing cancelled.");
|
||||
layoutHome();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// last confirmation
|
||||
layoutConfirmTx(coin, to_spend - change_spend - fee, fee);
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) {
|
||||
fsm_sendFailure(FailureType_Failure_ActionCancelled, "Signing cancelled by user");
|
||||
} else {
|
||||
resp->has_request_type = true;
|
||||
resp->request_type = RequestType_TXFINISHED;
|
||||
resp->has_serialized = true;
|
||||
resp->serialized.has_serialized_tx = true;
|
||||
resp->serialized.serialized_tx.size = (uint32_t)tx_size;
|
||||
msg_write(MessageType_MessageType_TxRequest, resp);
|
||||
}
|
||||
|
||||
layoutHome();
|
||||
}
|
||||
|
||||
void fsm_msgCancel(Cancel *msg)
|
||||
{
|
||||
(void)msg;
|
||||
@ -636,9 +511,9 @@ void fsm_msgDebugLinkGetState(DebugLinkGetState *msg)
|
||||
(void)msg;
|
||||
RESP_INIT(DebugLinkState);
|
||||
|
||||
// resp->has_layout = true;
|
||||
// resp->layout.size = OLED_BUFSIZE;
|
||||
// memcpy(resp->layout.bytes, oledGetBuffer(), OLED_BUFSIZE);
|
||||
resp->has_layout = true;
|
||||
resp->layout.size = OLED_BUFSIZE;
|
||||
memcpy(resp->layout.bytes, oledGetBuffer(), OLED_BUFSIZE);
|
||||
|
||||
if (storage.has_pin) {
|
||||
resp->has_pin = true;
|
||||
|
@ -38,7 +38,6 @@ void fsm_msgGetPublicKey(GetPublicKey *msg);
|
||||
void fsm_msgLoadDevice(LoadDevice *msg);
|
||||
void fsm_msgResetDevice(ResetDevice *msg);
|
||||
void fsm_msgSignTx(SignTx *msg);
|
||||
void fsm_msgSimpleSignTx(SimpleSignTx *msg);
|
||||
//void fsm_msgPinMatrixAck(PinMatrixAck *msg);
|
||||
void fsm_msgCancel(Cancel *msg);
|
||||
void fsm_msgTxAck(TxAck *msg);
|
||||
|
@ -29,11 +29,6 @@
|
||||
#include "pb_encode.h"
|
||||
#include "messages.pb.h"
|
||||
|
||||
// SimpleSignTx_size is the largest message we operate with
|
||||
#if MSG_IN_SIZE < SimpleSignTx_size
|
||||
#error "MSG_IN_SIZE is too small!"
|
||||
#endif
|
||||
|
||||
struct MessagesMap_t {
|
||||
char type; // n = normal, d = debug
|
||||
char dir; // i = in, o = out
|
||||
@ -55,7 +50,6 @@ static const struct MessagesMap_t MessagesMap[] = {
|
||||
{'n', 'i', MessageType_MessageType_LoadDevice, LoadDevice_fields, (void (*)(void *))fsm_msgLoadDevice},
|
||||
{'n', 'i', MessageType_MessageType_ResetDevice, ResetDevice_fields, (void (*)(void *))fsm_msgResetDevice},
|
||||
{'n', 'i', MessageType_MessageType_SignTx, SignTx_fields, (void (*)(void *))fsm_msgSignTx},
|
||||
{'n', 'i', MessageType_MessageType_SimpleSignTx, SimpleSignTx_fields, (void (*)(void *))fsm_msgSimpleSignTx},
|
||||
// {'n', 'i', MessageType_MessageType_PinMatrixAck, PinMatrixAck_fields, (void (*)(void *))fsm_msgPinMatrixAck},
|
||||
{'n', 'i', MessageType_MessageType_Cancel, Cancel_fields, (void (*)(void *))fsm_msgCancel},
|
||||
{'n', 'i', MessageType_MessageType_TxAck, TxAck_fields, (void (*)(void *))fsm_msgTxAck},
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include <stdbool.h>
|
||||
#include "trezor.h"
|
||||
|
||||
#define MSG_IN_SIZE (24*1024)
|
||||
#define MSG_IN_SIZE (9*1024)
|
||||
|
||||
#define MSG_OUT_SIZE (9*1024)
|
||||
|
||||
@ -34,7 +34,7 @@ uint8_t *msg_out_data(void);
|
||||
|
||||
#if DEBUG_LINK
|
||||
|
||||
#define MSG_DEBUG_OUT_SIZE (2*1024)
|
||||
#define MSG_DEBUG_OUT_SIZE (4*1024)
|
||||
|
||||
#define msg_debug_read(buf, len) msg_read_common('d', (buf), (len))
|
||||
#define msg_debug_write(id, ptr) msg_write_common('d', (id), (ptr))
|
||||
|
@ -9,9 +9,10 @@ Features.bootloader_hash max_size:32
|
||||
ApplySettings.language max_size:17
|
||||
ApplySettings.label max_size:33
|
||||
|
||||
Ping.message max_size:256
|
||||
Ping.message max_size:256
|
||||
|
||||
Success.message max_size:256
|
||||
Success.message max_size:256
|
||||
Success.payload max_size:1024
|
||||
|
||||
Failure.message max_size:256
|
||||
|
||||
@ -56,16 +57,26 @@ VerifyMessage.message max_size:256
|
||||
MessageSignature.address max_size:35
|
||||
MessageSignature.signature max_size:65
|
||||
|
||||
EncryptKeyValue.address_n max_count:8
|
||||
EncryptKeyValue.key max_size:256
|
||||
EncryptKeyValue.value max_size:1024
|
||||
|
||||
DecryptKeyValue.address_n max_count:8
|
||||
DecryptKeyValue.key max_size:256
|
||||
DecryptKeyValue.value max_size:1024
|
||||
|
||||
EstimateTxSize.coin_name max_size:17
|
||||
|
||||
SignTx.coin_name max_size:17
|
||||
|
||||
SimpleSignTx.inputs max_count:4
|
||||
SimpleSignTx.outputs max_count:4
|
||||
SimpleSignTx.transactions max_count:4
|
||||
# not used in firmware
|
||||
SimpleSignTx.inputs max_count:0
|
||||
SimpleSignTx.outputs max_count:0
|
||||
SimpleSignTx.transactions max_count:0
|
||||
SimpleSignTx.coin_name max_size:17
|
||||
|
||||
FirmwareUpload.payload max_size:0 # not used in firmware
|
||||
# not used in firmware
|
||||
FirmwareUpload.payload max_size:0
|
||||
|
||||
DebugLinkState.layout max_size:1024
|
||||
DebugLinkState.pin max_size:10
|
||||
|
@ -56,8 +56,9 @@ const pb_field_t Ping_fields[5] = {
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
const pb_field_t Success_fields[2] = {
|
||||
const pb_field_t Success_fields[3] = {
|
||||
PB_FIELD2( 1, STRING , OPTIONAL, STATIC , FIRST, Success, message, message, 0),
|
||||
PB_FIELD2( 2, BYTES , OPTIONAL, STATIC , OTHER, Success, payload, message, 0),
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
@ -204,6 +205,20 @@ const pb_field_t MessageSignature_fields[3] = {
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
const pb_field_t EncryptKeyValue_fields[4] = {
|
||||
PB_FIELD2( 1, UINT32 , REPEATED, STATIC , FIRST, EncryptKeyValue, address_n, address_n, 0),
|
||||
PB_FIELD2( 2, STRING , OPTIONAL, STATIC , OTHER, EncryptKeyValue, key, address_n, 0),
|
||||
PB_FIELD2( 3, BYTES , OPTIONAL, STATIC , OTHER, EncryptKeyValue, value, key, 0),
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
const pb_field_t DecryptKeyValue_fields[4] = {
|
||||
PB_FIELD2( 1, UINT32 , REPEATED, STATIC , FIRST, DecryptKeyValue, address_n, address_n, 0),
|
||||
PB_FIELD2( 2, STRING , OPTIONAL, STATIC , OTHER, DecryptKeyValue, key, address_n, 0),
|
||||
PB_FIELD2( 3, BYTES , OPTIONAL, STATIC , OTHER, DecryptKeyValue, value, key, 0),
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
const pb_field_t EstimateTxSize_fields[4] = {
|
||||
PB_FIELD2( 1, UINT32 , REQUIRED, STATIC , FIRST, EstimateTxSize, outputs_count, outputs_count, 0),
|
||||
PB_FIELD2( 2, UINT32 , REQUIRED, STATIC , OTHER, EstimateTxSize, inputs_count, outputs_count, 0),
|
||||
@ -296,11 +311,11 @@ const pb_field_t DebugLinkLog_fields[4] = {
|
||||
* numbers or field sizes that are larger than what can fit in 8 or 16 bit
|
||||
* field descriptors.
|
||||
*/
|
||||
STATIC_ASSERT((pb_membersize(Features, coins[0]) < 65536 && pb_membersize(PublicKey, node) < 65536 && pb_membersize(LoadDevice, node) < 65536 && pb_membersize(SimpleSignTx, inputs[0]) < 65536 && pb_membersize(SimpleSignTx, outputs[0]) < 65536 && pb_membersize(SimpleSignTx, transactions[0]) < 65536 && pb_membersize(TxRequest, details) < 65536 && pb_membersize(TxRequest, serialized) < 65536 && pb_membersize(TxAck, tx) < 65536 && pb_membersize(DebugLinkState, node) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_Initialize_Features_ApplySettings_ChangePin_Ping_Success_Failure_ButtonRequest_ButtonAck_PinMatrixRequest_PinMatrixAck_Cancel_PassphraseRequest_PassphraseAck_GetEntropy_Entropy_GetPublicKey_PublicKey_GetAddress_Address_WipeDevice_LoadDevice_ResetDevice_EntropyRequest_EntropyAck_RecoveryDevice_WordRequest_WordAck_SignMessage_VerifyMessage_MessageSignature_EstimateTxSize_TxSize_SignTx_SimpleSignTx_TxRequest_TxAck_FirmwareErase_FirmwareUpload_DebugLinkDecision_DebugLinkGetState_DebugLinkState_DebugLinkStop_DebugLinkLog)
|
||||
STATIC_ASSERT((pb_membersize(Features, coins[0]) < 65536 && pb_membersize(PublicKey, node) < 65536 && pb_membersize(LoadDevice, node) < 65536 && pb_membersize(SimpleSignTx, inputs[0]) < 65536 && pb_membersize(SimpleSignTx, outputs[0]) < 65536 && pb_membersize(SimpleSignTx, transactions[0]) < 65536 && pb_membersize(TxRequest, details) < 65536 && pb_membersize(TxRequest, serialized) < 65536 && pb_membersize(TxAck, tx) < 65536 && pb_membersize(DebugLinkState, node) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_Initialize_Features_ApplySettings_ChangePin_Ping_Success_Failure_ButtonRequest_ButtonAck_PinMatrixRequest_PinMatrixAck_Cancel_PassphraseRequest_PassphraseAck_GetEntropy_Entropy_GetPublicKey_PublicKey_GetAddress_Address_WipeDevice_LoadDevice_ResetDevice_EntropyRequest_EntropyAck_RecoveryDevice_WordRequest_WordAck_SignMessage_VerifyMessage_MessageSignature_EncryptKeyValue_DecryptKeyValue_EstimateTxSize_TxSize_SignTx_SimpleSignTx_TxRequest_TxAck_FirmwareErase_FirmwareUpload_DebugLinkDecision_DebugLinkGetState_DebugLinkState_DebugLinkStop_DebugLinkLog)
|
||||
#endif
|
||||
|
||||
#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
|
||||
#error Field descriptor for Entropy.entropy is too large. Define PB_FIELD_16BIT to fix this.
|
||||
#error Field descriptor for Success.payload is too large. Define PB_FIELD_16BIT to fix this.
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -34,6 +34,8 @@ typedef enum _MessageType {
|
||||
MessageType_MessageType_Cancel = 20,
|
||||
MessageType_MessageType_TxRequest = 21,
|
||||
MessageType_MessageType_TxAck = 22,
|
||||
MessageType_MessageType_EncryptKeyValue = 23,
|
||||
MessageType_MessageType_DecryptKeyValue = 24,
|
||||
MessageType_MessageType_ApplySettings = 25,
|
||||
MessageType_MessageType_ButtonRequest = 26,
|
||||
MessageType_MessageType_ButtonAck = 27,
|
||||
@ -168,6 +170,34 @@ typedef struct _DebugLinkState {
|
||||
uint32_t recovery_word_pos;
|
||||
} DebugLinkState;
|
||||
|
||||
typedef struct {
|
||||
size_t size;
|
||||
uint8_t bytes[1024];
|
||||
} DecryptKeyValue_value_t;
|
||||
|
||||
typedef struct _DecryptKeyValue {
|
||||
size_t address_n_count;
|
||||
uint32_t address_n[8];
|
||||
bool has_key;
|
||||
char key[256];
|
||||
bool has_value;
|
||||
DecryptKeyValue_value_t value;
|
||||
} DecryptKeyValue;
|
||||
|
||||
typedef struct {
|
||||
size_t size;
|
||||
uint8_t bytes[1024];
|
||||
} EncryptKeyValue_value_t;
|
||||
|
||||
typedef struct _EncryptKeyValue {
|
||||
size_t address_n_count;
|
||||
uint32_t address_n[8];
|
||||
bool has_key;
|
||||
char key[256];
|
||||
bool has_value;
|
||||
EncryptKeyValue_value_t value;
|
||||
} EncryptKeyValue;
|
||||
|
||||
typedef struct {
|
||||
size_t size;
|
||||
uint8_t bytes[1024];
|
||||
@ -378,18 +408,25 @@ typedef struct _SignTx {
|
||||
|
||||
typedef struct _SimpleSignTx {
|
||||
size_t inputs_count;
|
||||
TxInputType inputs[4];
|
||||
TxInputType inputs[0];
|
||||
size_t outputs_count;
|
||||
TxOutputType outputs[4];
|
||||
TxOutputType outputs[0];
|
||||
size_t transactions_count;
|
||||
TransactionType transactions[4];
|
||||
TransactionType transactions[0];
|
||||
bool has_coin_name;
|
||||
char coin_name[17];
|
||||
} SimpleSignTx;
|
||||
|
||||
typedef struct {
|
||||
size_t size;
|
||||
uint8_t bytes[1024];
|
||||
} Success_payload_t;
|
||||
|
||||
typedef struct _Success {
|
||||
bool has_message;
|
||||
char message[256];
|
||||
bool has_payload;
|
||||
Success_payload_t payload;
|
||||
} Success;
|
||||
|
||||
typedef struct _TxAck {
|
||||
@ -466,6 +503,12 @@ extern const char SimpleSignTx_coin_name_default[17];
|
||||
#define DebugLinkState_reset_entropy_tag 8
|
||||
#define DebugLinkState_recovery_fake_word_tag 9
|
||||
#define DebugLinkState_recovery_word_pos_tag 10
|
||||
#define DecryptKeyValue_address_n_tag 1
|
||||
#define DecryptKeyValue_key_tag 2
|
||||
#define DecryptKeyValue_value_tag 3
|
||||
#define EncryptKeyValue_address_n_tag 1
|
||||
#define EncryptKeyValue_key_tag 2
|
||||
#define EncryptKeyValue_value_tag 3
|
||||
#define Entropy_entropy_tag 1
|
||||
#define EntropyAck_entropy_tag 1
|
||||
#define EstimateTxSize_outputs_count_tag 1
|
||||
@ -533,6 +576,7 @@ extern const char SimpleSignTx_coin_name_default[17];
|
||||
#define SimpleSignTx_transactions_tag 3
|
||||
#define SimpleSignTx_coin_name_tag 4
|
||||
#define Success_message_tag 1
|
||||
#define Success_payload_tag 2
|
||||
#define TxAck_tx_tag 1
|
||||
#define TxRequest_request_type_tag 1
|
||||
#define TxRequest_details_tag 2
|
||||
@ -549,7 +593,7 @@ extern const pb_field_t Features_fields[16];
|
||||
extern const pb_field_t ApplySettings_fields[3];
|
||||
extern const pb_field_t ChangePin_fields[2];
|
||||
extern const pb_field_t Ping_fields[5];
|
||||
extern const pb_field_t Success_fields[2];
|
||||
extern const pb_field_t Success_fields[3];
|
||||
extern const pb_field_t Failure_fields[3];
|
||||
extern const pb_field_t ButtonRequest_fields[3];
|
||||
extern const pb_field_t ButtonAck_fields[1];
|
||||
@ -575,6 +619,8 @@ extern const pb_field_t WordAck_fields[2];
|
||||
extern const pb_field_t SignMessage_fields[4];
|
||||
extern const pb_field_t VerifyMessage_fields[4];
|
||||
extern const pb_field_t MessageSignature_fields[3];
|
||||
extern const pb_field_t EncryptKeyValue_fields[4];
|
||||
extern const pb_field_t DecryptKeyValue_fields[4];
|
||||
extern const pb_field_t EstimateTxSize_fields[4];
|
||||
extern const pb_field_t TxSize_fields[2];
|
||||
extern const pb_field_t SignTx_fields[4];
|
||||
@ -595,7 +641,7 @@ extern const pb_field_t DebugLinkLog_fields[4];
|
||||
#define ApplySettings_size 54
|
||||
#define ChangePin_size 2
|
||||
#define Ping_size 265
|
||||
#define Success_size 259
|
||||
#define Success_size 1286
|
||||
#define Failure_size 265
|
||||
#define ButtonRequest_size 265
|
||||
#define ButtonAck_size 0
|
||||
@ -621,10 +667,12 @@ extern const pb_field_t DebugLinkLog_fields[4];
|
||||
#define SignMessage_size 326
|
||||
#define VerifyMessage_size 363
|
||||
#define MessageSignature_size 104
|
||||
#define EncryptKeyValue_size 1334
|
||||
#define DecryptKeyValue_size 1334
|
||||
#define EstimateTxSize_size 31
|
||||
#define TxSize_size 6
|
||||
#define SignTx_size 31
|
||||
#define SimpleSignTx_size (91 + 4*TxInputType_size + 4*TxOutputType_size + 4*TransactionType_size)
|
||||
#define SimpleSignTx_size (19 + 0*TxInputType_size + 0*TxOutputType_size + 0*TransactionType_size)
|
||||
#define TxRequest_size (18 + TxRequestDetailsType_size + TxRequestSerializedType_size)
|
||||
#define TxAck_size (6 + TransactionType_size)
|
||||
#define FirmwareErase_size 0
|
||||
|
@ -1,26 +1,29 @@
|
||||
HDNodeType.chain_code max_size:32
|
||||
HDNodeType.private_key max_size:32
|
||||
HDNodeType.public_key max_size:33
|
||||
HDNodeType.chain_code max_size:32
|
||||
HDNodeType.private_key max_size:32
|
||||
HDNodeType.public_key max_size:33
|
||||
|
||||
CoinType.coin_name max_size:17
|
||||
CoinType.coin_shortcut max_size:9
|
||||
CoinType.coin_name max_size:17
|
||||
CoinType.coin_shortcut max_size:9
|
||||
|
||||
TxInputType.address_n max_count:8
|
||||
TxInputType.prev_hash max_size:32
|
||||
TxInputType.script_sig max_size:520
|
||||
TxInputType.address_n max_count:8
|
||||
TxInputType.prev_hash max_size:32
|
||||
TxInputType.script_sig max_size:520
|
||||
|
||||
TxOutputType.address max_size:35
|
||||
TxOutputType.address_n max_count:8
|
||||
TxOutputType.script_args max_count:3
|
||||
TxOutputType.script_args max_size:16
|
||||
TxOutputType.address max_size:35
|
||||
TxOutputType.address_n max_count:8
|
||||
|
||||
TxOutputBinType.script_pubkey max_size:256
|
||||
TxOutputBinType.script_pubkey max_size:256
|
||||
|
||||
TransactionType.inputs max_count:8
|
||||
TransactionType.bin_outputs max_count:4
|
||||
TransactionType.outputs max_count:4
|
||||
TransactionType.inputs max_count:1
|
||||
TransactionType.bin_outputs max_count:1
|
||||
TransactionType.outputs max_count:1
|
||||
|
||||
TxRequestDetailsType.tx_hash max_size:32
|
||||
TxRequestDetailsType.tx_hash max_size:32
|
||||
|
||||
TxRequestSerializedType.signature max_size:80
|
||||
TxRequestSerializedType.serialized_tx max_size:1024
|
||||
|
||||
MultisigRedeemScriptType.pubkeys max_count:5
|
||||
MultisigRedeemScriptType.pubkeys max_size:33
|
||||
MultisigRedeemScriptType.signatures max_count:4
|
||||
MultisigRedeemScriptType.signatures max_size:80
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "types.pb.h"
|
||||
|
||||
const uint32_t TxInputType_sequence_default = 4294967295u;
|
||||
const InputScriptType TxInputType_script_type_default = InputScriptType_SPENDADDRESS;
|
||||
|
||||
|
||||
const pb_field_t HDNodeType_fields[7] = {
|
||||
@ -24,21 +25,28 @@ const pb_field_t CoinType_fields[5] = {
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
const pb_field_t TxInputType_fields[6] = {
|
||||
const pb_field_t MultisigRedeemScriptType_fields[3] = {
|
||||
PB_FIELD2( 1, BYTES , REPEATED, STATIC , FIRST, MultisigRedeemScriptType, pubkeys, pubkeys, 0),
|
||||
PB_FIELD2( 2, BYTES , REPEATED, STATIC , OTHER, MultisigRedeemScriptType, signatures, pubkeys, 0),
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
const pb_field_t TxInputType_fields[8] = {
|
||||
PB_FIELD2( 1, UINT32 , REPEATED, STATIC , FIRST, TxInputType, address_n, address_n, 0),
|
||||
PB_FIELD2( 2, BYTES , REQUIRED, STATIC , OTHER, TxInputType, prev_hash, address_n, 0),
|
||||
PB_FIELD2( 3, UINT32 , REQUIRED, STATIC , OTHER, TxInputType, prev_index, prev_hash, 0),
|
||||
PB_FIELD2( 4, BYTES , OPTIONAL, STATIC , OTHER, TxInputType, script_sig, prev_index, 0),
|
||||
PB_FIELD2( 5, UINT32 , OPTIONAL, STATIC , OTHER, TxInputType, sequence, script_sig, &TxInputType_sequence_default),
|
||||
PB_FIELD2( 6, ENUM , OPTIONAL, STATIC , OTHER, TxInputType, script_type, sequence, &TxInputType_script_type_default),
|
||||
PB_FIELD2( 7, MESSAGE , OPTIONAL, STATIC , OTHER, TxInputType, multisig, script_type, &MultisigRedeemScriptType_fields),
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
const pb_field_t TxOutputType_fields[6] = {
|
||||
const pb_field_t TxOutputType_fields[5] = {
|
||||
PB_FIELD2( 1, STRING , OPTIONAL, STATIC , FIRST, TxOutputType, address, address, 0),
|
||||
PB_FIELD2( 2, UINT32 , REPEATED, STATIC , OTHER, TxOutputType, address_n, address, 0),
|
||||
PB_FIELD2( 3, UINT64 , REQUIRED, STATIC , OTHER, TxOutputType, amount, address_n, 0),
|
||||
PB_FIELD2( 4, ENUM , REQUIRED, STATIC , OTHER, TxOutputType, script_type, amount, 0),
|
||||
PB_FIELD2( 5, BYTES , REPEATED, STATIC , OTHER, TxOutputType, script_args, script_type, 0),
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
@ -134,7 +142,7 @@ const pb_extension_type_t wire_debug_out = {
|
||||
* numbers or field sizes that are larger than what can fit in 8 or 16 bit
|
||||
* field descriptors.
|
||||
*/
|
||||
STATIC_ASSERT((pb_membersize(TransactionType, inputs[0]) < 65536 && pb_membersize(TransactionType, bin_outputs[0]) < 65536 && pb_membersize(TransactionType, outputs[0]) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_HDNodeType_CoinType_TxInputType_TxOutputType_TxOutputBinType_TransactionType_TxRequestDetailsType_TxRequestSerializedType)
|
||||
STATIC_ASSERT((pb_membersize(TxInputType, multisig) < 65536 && pb_membersize(TransactionType, inputs[0]) < 65536 && pb_membersize(TransactionType, bin_outputs[0]) < 65536 && pb_membersize(TransactionType, outputs[0]) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_HDNodeType_CoinType_MultisigRedeemScriptType_TxInputType_TxOutputType_TxOutputBinType_TransactionType_TxRequestDetailsType_TxRequestSerializedType)
|
||||
#endif
|
||||
|
||||
#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
|
||||
|
@ -24,10 +24,15 @@ typedef enum _FailureType {
|
||||
FailureType_Failure_FirmwareError = 99
|
||||
} FailureType;
|
||||
|
||||
typedef enum _ScriptType {
|
||||
ScriptType_PAYTOADDRESS = 0,
|
||||
ScriptType_PAYTOSCRIPTHASH = 1
|
||||
} ScriptType;
|
||||
typedef enum _OutputScriptType {
|
||||
OutputScriptType_PAYTOADDRESS = 0,
|
||||
OutputScriptType_PAYTOSCRIPTHASH = 1
|
||||
} OutputScriptType;
|
||||
|
||||
typedef enum _InputScriptType {
|
||||
InputScriptType_SPENDADDRESS = 0,
|
||||
InputScriptType_SPENDMULTISIG = 1
|
||||
} InputScriptType;
|
||||
|
||||
typedef enum _RequestType {
|
||||
RequestType_TXINPUT = 0,
|
||||
@ -93,24 +98,20 @@ typedef struct _HDNodeType {
|
||||
|
||||
typedef struct {
|
||||
size_t size;
|
||||
uint8_t bytes[32];
|
||||
} TxInputType_prev_hash_t;
|
||||
uint8_t bytes[33];
|
||||
} MultisigRedeemScriptType_pubkeys_t;
|
||||
|
||||
typedef struct {
|
||||
size_t size;
|
||||
uint8_t bytes[256];
|
||||
} TxInputType_script_sig_t;
|
||||
uint8_t bytes[80];
|
||||
} MultisigRedeemScriptType_signatures_t;
|
||||
|
||||
typedef struct _TxInputType {
|
||||
size_t address_n_count;
|
||||
uint32_t address_n[8];
|
||||
TxInputType_prev_hash_t prev_hash;
|
||||
uint32_t prev_index;
|
||||
bool has_script_sig;
|
||||
TxInputType_script_sig_t script_sig;
|
||||
bool has_sequence;
|
||||
uint32_t sequence;
|
||||
} TxInputType;
|
||||
typedef struct _MultisigRedeemScriptType {
|
||||
size_t pubkeys_count;
|
||||
MultisigRedeemScriptType_pubkeys_t pubkeys[5];
|
||||
size_t signatures_count;
|
||||
MultisigRedeemScriptType_signatures_t signatures[4];
|
||||
} MultisigRedeemScriptType;
|
||||
|
||||
typedef struct {
|
||||
size_t size;
|
||||
@ -122,20 +123,13 @@ typedef struct _TxOutputBinType {
|
||||
TxOutputBinType_script_pubkey_t script_pubkey;
|
||||
} TxOutputBinType;
|
||||
|
||||
typedef struct {
|
||||
size_t size;
|
||||
uint8_t bytes[16];
|
||||
} TxOutputType_script_args_t;
|
||||
|
||||
typedef struct _TxOutputType {
|
||||
bool has_address;
|
||||
char address[35];
|
||||
size_t address_n_count;
|
||||
uint32_t address_n[8];
|
||||
uint64_t amount;
|
||||
ScriptType script_type;
|
||||
size_t script_args_count;
|
||||
TxOutputType_script_args_t script_args[3];
|
||||
OutputScriptType script_type;
|
||||
} TxOutputType;
|
||||
|
||||
typedef struct {
|
||||
@ -169,17 +163,42 @@ typedef struct _TxRequestSerializedType {
|
||||
TxRequestSerializedType_serialized_tx_t serialized_tx;
|
||||
} TxRequestSerializedType;
|
||||
|
||||
typedef struct {
|
||||
size_t size;
|
||||
uint8_t bytes[32];
|
||||
} TxInputType_prev_hash_t;
|
||||
|
||||
typedef struct {
|
||||
size_t size;
|
||||
uint8_t bytes[520];
|
||||
} TxInputType_script_sig_t;
|
||||
|
||||
typedef struct _TxInputType {
|
||||
size_t address_n_count;
|
||||
uint32_t address_n[8];
|
||||
TxInputType_prev_hash_t prev_hash;
|
||||
uint32_t prev_index;
|
||||
bool has_script_sig;
|
||||
TxInputType_script_sig_t script_sig;
|
||||
bool has_sequence;
|
||||
uint32_t sequence;
|
||||
bool has_script_type;
|
||||
InputScriptType script_type;
|
||||
bool has_multisig;
|
||||
MultisigRedeemScriptType multisig;
|
||||
} TxInputType;
|
||||
|
||||
typedef struct _TransactionType {
|
||||
bool has_version;
|
||||
uint32_t version;
|
||||
size_t inputs_count;
|
||||
TxInputType inputs[8];
|
||||
TxInputType inputs[1];
|
||||
size_t bin_outputs_count;
|
||||
TxOutputBinType bin_outputs[4];
|
||||
TxOutputBinType bin_outputs[1];
|
||||
bool has_lock_time;
|
||||
uint32_t lock_time;
|
||||
size_t outputs_count;
|
||||
TxOutputType outputs[4];
|
||||
TxOutputType outputs[1];
|
||||
bool has_inputs_cnt;
|
||||
uint32_t inputs_cnt;
|
||||
bool has_outputs_cnt;
|
||||
@ -194,6 +213,7 @@ extern const pb_extension_type_t wire_debug_out;
|
||||
|
||||
/* Default values for struct fields */
|
||||
extern const uint32_t TxInputType_sequence_default;
|
||||
extern const InputScriptType TxInputType_script_type_default;
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define CoinType_coin_name_tag 1
|
||||
@ -206,23 +226,26 @@ extern const uint32_t TxInputType_sequence_default;
|
||||
#define HDNodeType_chain_code_tag 4
|
||||
#define HDNodeType_private_key_tag 5
|
||||
#define HDNodeType_public_key_tag 6
|
||||
#define TxInputType_address_n_tag 1
|
||||
#define TxInputType_prev_hash_tag 2
|
||||
#define TxInputType_prev_index_tag 3
|
||||
#define TxInputType_script_sig_tag 4
|
||||
#define TxInputType_sequence_tag 5
|
||||
#define MultisigRedeemScriptType_pubkeys_tag 1
|
||||
#define MultisigRedeemScriptType_signatures_tag 2
|
||||
#define TxOutputBinType_amount_tag 1
|
||||
#define TxOutputBinType_script_pubkey_tag 2
|
||||
#define TxOutputType_address_tag 1
|
||||
#define TxOutputType_address_n_tag 2
|
||||
#define TxOutputType_amount_tag 3
|
||||
#define TxOutputType_script_type_tag 4
|
||||
#define TxOutputType_script_args_tag 5
|
||||
#define TxRequestDetailsType_request_index_tag 1
|
||||
#define TxRequestDetailsType_tx_hash_tag 2
|
||||
#define TxRequestSerializedType_signature_index_tag 1
|
||||
#define TxRequestSerializedType_signature_tag 2
|
||||
#define TxRequestSerializedType_serialized_tx_tag 3
|
||||
#define TxInputType_address_n_tag 1
|
||||
#define TxInputType_prev_hash_tag 2
|
||||
#define TxInputType_prev_index_tag 3
|
||||
#define TxInputType_script_sig_tag 4
|
||||
#define TxInputType_sequence_tag 5
|
||||
#define TxInputType_script_type_tag 6
|
||||
#define TxInputType_multisig_tag 7
|
||||
#define TransactionType_version_tag 1
|
||||
#define TransactionType_inputs_tag 2
|
||||
#define TransactionType_bin_outputs_tag 3
|
||||
@ -238,8 +261,9 @@ extern const uint32_t TxInputType_sequence_default;
|
||||
/* Struct field encoding specification for nanopb */
|
||||
extern const pb_field_t HDNodeType_fields[7];
|
||||
extern const pb_field_t CoinType_fields[5];
|
||||
extern const pb_field_t TxInputType_fields[6];
|
||||
extern const pb_field_t TxOutputType_fields[6];
|
||||
extern const pb_field_t MultisigRedeemScriptType_fields[3];
|
||||
extern const pb_field_t TxInputType_fields[8];
|
||||
extern const pb_field_t TxOutputType_fields[5];
|
||||
extern const pb_field_t TxOutputBinType_fields[3];
|
||||
extern const pb_field_t TransactionType_fields[8];
|
||||
extern const pb_field_t TxRequestDetailsType_fields[3];
|
||||
@ -248,10 +272,11 @@ extern const pb_field_t TxRequestSerializedType_fields[4];
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define HDNodeType_size 121
|
||||
#define CoinType_size 47
|
||||
#define TxInputType_size 353
|
||||
#define TxOutputType_size 156
|
||||
#define MultisigRedeemScriptType_size 503
|
||||
#define TxInputType_size 1129
|
||||
#define TxOutputType_size 102
|
||||
#define TxOutputBinType_size 270
|
||||
#define TransactionType_size 4600
|
||||
#define TransactionType_size 1533
|
||||
#define TxRequestDetailsType_size 40
|
||||
#define TxRequestSerializedType_size 1115
|
||||
|
||||
|
@ -98,7 +98,7 @@ int compile_output(const CoinType *coin, const HDNode *root, TxOutputType *in, T
|
||||
memset(out, 0, sizeof(TxOutputBinType));
|
||||
out->amount = in->amount;
|
||||
|
||||
if (in->script_type == ScriptType_PAYTOADDRESS) {
|
||||
if (in->script_type == OutputScriptType_PAYTOADDRESS) {
|
||||
out->script_pubkey.bytes[0] = 0x76; // OP_DUP
|
||||
out->script_pubkey.bytes[1] = 0xA9; // OP_HASH_160
|
||||
out->script_pubkey.bytes[2] = 0x14; // pushing 20 bytes
|
||||
@ -113,7 +113,7 @@ int compile_output(const CoinType *coin, const HDNode *root, TxOutputType *in, T
|
||||
return 25;
|
||||
}
|
||||
|
||||
if (in->script_type == ScriptType_PAYTOSCRIPTHASH) {
|
||||
if (in->script_type == OutputScriptType_PAYTOSCRIPTHASH) {
|
||||
out->script_pubkey.bytes[0] = 0xA9; // OP_HASH_160
|
||||
out->script_pubkey.bytes[1] = 0x14; // pushing 20 bytes
|
||||
uint8_t decoded[21];
|
||||
@ -275,80 +275,6 @@ void tx_hash_final(TxStruct *t, uint8_t *hash, bool reverse)
|
||||
}
|
||||
}
|
||||
|
||||
bool transactionHash(TransactionType *tx, uint8_t *hash)
|
||||
{
|
||||
TxStruct t;
|
||||
uint32_t i;
|
||||
tx_init(&t, tx->inputs_count, tx->bin_outputs_count, tx->version, tx->lock_time, false);
|
||||
for (i = 0; i < tx->inputs_count; i++) {
|
||||
if (!tx_hash_input(&t, &(tx->inputs[i]))) return false;
|
||||
}
|
||||
for (i = 0; i < tx->bin_outputs_count; i++) {
|
||||
if (!tx_hash_output(&t, &(tx->bin_outputs[i]))) return false;
|
||||
}
|
||||
tx_hash_final(&t, hash, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
int transactionSimpleSign(const CoinType *coin, HDNode *root, TxInputType *inputs, uint32_t inputs_count, TxOutputType *outputs, uint32_t outputs_count, uint32_t version, uint32_t lock_time, uint8_t *out)
|
||||
{
|
||||
uint32_t idx, i, k, r = 0;
|
||||
TxStruct ti, to;
|
||||
uint8_t buf[512];
|
||||
TxInputType input;
|
||||
TxOutputBinType output;
|
||||
HDNode node;
|
||||
uint8_t privkey[32], pubkey[33], hash[32], sig[64];
|
||||
|
||||
layoutProgressSwipe("Signing", 0, 0);
|
||||
tx_init(&to, inputs_count, outputs_count, version, lock_time, false);
|
||||
for (idx = 0; idx < inputs_count; idx++) {
|
||||
// compute inner transaction
|
||||
memcpy(&input, &(inputs[idx]), sizeof(TxInputType));
|
||||
tx_init(&ti, inputs_count, outputs_count, version, lock_time, true);
|
||||
memset(privkey, 0, 32);
|
||||
memset(pubkey, 0, 33);
|
||||
for (i = 0; i < inputs_count; i++) {
|
||||
if (i == idx) {
|
||||
memcpy(&node, root, sizeof(HDNode));
|
||||
for (k = 0; k < inputs[i].address_n_count; k++) {
|
||||
hdnode_private_ckd(&node, inputs[i].address_n[k]);
|
||||
}
|
||||
ecdsa_get_pubkeyhash(node.public_key, hash);
|
||||
inputs[i].script_sig.size = compile_script_sig(coin->address_type, hash, inputs[i].script_sig.bytes);
|
||||
if (inputs[i].script_sig.size == 0) {
|
||||
return 0;
|
||||
}
|
||||
memcpy(privkey, node.private_key, 32);
|
||||
memcpy(pubkey, node.public_key, 33);
|
||||
} else {
|
||||
inputs[i].script_sig.size = 0;
|
||||
}
|
||||
if (!tx_hash_input(&ti, &(inputs[i]))) return 0;
|
||||
}
|
||||
for (i = 0; i < outputs_count; i++) {
|
||||
int co = compile_output(coin, root, &(outputs[i]), &output, idx == 0);
|
||||
if (co <= 0) {
|
||||
return co;
|
||||
}
|
||||
if (!tx_hash_output(&ti, &output)) return 0;
|
||||
}
|
||||
tx_hash_final(&ti, hash, false);
|
||||
ecdsa_sign_digest(privkey, hash, sig);
|
||||
int der_len = ecdsa_sig_to_der(sig, buf);
|
||||
input.script_sig.size = serialize_script_sig(buf, der_len, pubkey, 33, input.script_sig.bytes);
|
||||
r += tx_serialize_input(&to, input.prev_hash.bytes, input.prev_index, input.script_sig.bytes, input.script_sig.size, input.sequence, out + r);
|
||||
layoutProgress("Signing", 1000 * idx / inputs_count, idx);
|
||||
}
|
||||
for (i = 0; i < outputs_count; i++) {
|
||||
if (compile_output(coin, root, &(outputs[i]), &output, false) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
r += tx_serialize_output(&to, output.amount, output.script_pubkey.bytes, output.script_pubkey.size, out + r);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32_t transactionEstimateSize(uint32_t inputs, uint32_t outputs)
|
||||
{
|
||||
return 10 + inputs * 149 + outputs * 35;
|
||||
|
@ -52,10 +52,6 @@ bool tx_hash_input(TxStruct *t, TxInputType *input);
|
||||
bool tx_hash_output(TxStruct *t, TxOutputBinType *output);
|
||||
void tx_hash_final(TxStruct *t, uint8_t *hash, bool reverse);
|
||||
|
||||
bool transactionHash(TransactionType *tx, uint8_t *hash);
|
||||
|
||||
int transactionSimpleSign(const CoinType *coin, HDNode *root, TxInputType *inputs, uint32_t inputs_count, TxOutputType *outputs, uint32_t outputs_count, uint32_t version, uint32_t lock_time, uint8_t *out);
|
||||
|
||||
uint32_t transactionEstimateSize(uint32_t inputs, uint32_t outputs);
|
||||
|
||||
uint32_t transactionEstimateSizeKb(uint32_t inputs, uint32_t outputs);
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 1865a0428d1803416174f31a1d6b53b6632384a9
|
||||
Subproject commit 06f4aee3fd45ec533e7e0e5a2ac06c98ae9975d6
|
Loading…
Reference in New Issue
Block a user