Skip to content

Commit 677e961

Browse files
authored
Merge pull request #608 from Cypherock/chore/remove-obsolete-bitcoin-input-parser
Remove old bitcoin input parser
2 parents ad4717b + 3251bb2 commit 677e961

File tree

5 files changed

+0
-650
lines changed

5 files changed

+0
-650
lines changed

apps/btc_family/btc_txn.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -447,9 +447,6 @@ static bool fetch_valid_input(btc_query_t *query) {
447447
// verify transaction details and discard the raw-transaction (prev_txn)
448448
const btc_prev_txn_chunk_t *prev_txn = &(query->sign_txn.prev_txn_chunk);
449449

450-
btc_verify_input_t verify_input_data;
451-
memzero(&(verify_input_data), sizeof(btc_verify_input_t));
452-
453450
// req prev txn chunk from host
454451
if (!btc_get_query(query, BTC_QUERY_SIGN_TXN_TAG) ||
455452
!check_which_request(query, BTC_SIGN_TXN_REQUEST_PREV_TXN_CHUNK_TAG)) {

apps/btc_family/btc_txn_helpers.c

Lines changed: 0 additions & 268 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@
6565
#include <stdio.h>
6666

6767
#include "bignum.h"
68-
#include "btc_helpers.h"
6968
#include "btc_script.h"
7069
#include "utils.h"
7170

@@ -328,277 +327,10 @@ STATIC bool calculate_p2wpkh_digest(const btc_txn_context_t *context,
328327
return true;
329328
}
330329

331-
static void update_hash(btc_verify_input_t *verify_input_data,
332-
const uint8_t *raw_txn_chunk,
333-
int chunk_index,
334-
int32_t offset) {
335-
hash_case update = DEFAULT;
336-
337-
if (0 == chunk_index) {
338-
update = FIRST_CHUNK_HASH;
339-
}
340-
switch (update) {
341-
case FIRST_CHUNK_HASH: {
342-
if (verify_input_data->is_segwit) {
343-
sha256_Update(&(verify_input_data->sha_256_ctx), raw_txn_chunk, 4);
344-
// skip marker and flag
345-
sha256_Update(
346-
&(verify_input_data->sha_256_ctx), raw_txn_chunk + 6, offset - 6);
347-
} else {
348-
sha256_Update(&(verify_input_data->sha_256_ctx), raw_txn_chunk, offset);
349-
}
350-
return;
351-
break;
352-
}
353-
354-
default: {
355-
sha256_Update(&(verify_input_data->sha_256_ctx), raw_txn_chunk, offset);
356-
break;
357-
}
358-
}
359-
}
360-
361-
static void update_locktime(btc_verify_input_t *verify_input_data,
362-
const uint8_t *raw_txn_chunk,
363-
int chunk_index) {
364-
if (verify_input_data->is_locktime_split) {
365-
// last second chunk
366-
if (chunk_index + 2 == verify_input_data->chunk_total) {
367-
memcpy(
368-
verify_input_data->locktime,
369-
raw_txn_chunk + (CHUNK_SIZE - 4 - verify_input_data->size_last_chunk),
370-
4 - verify_input_data->size_last_chunk);
371-
return;
372-
} else if (chunk_index + 1 == verify_input_data->chunk_total) {
373-
memcpy(
374-
verify_input_data->locktime + 4 - verify_input_data->size_last_chunk,
375-
raw_txn_chunk,
376-
verify_input_data->size_last_chunk);
377-
verify_input_data->has_locktime = true;
378-
return;
379-
} else {
380-
// wait for subsequent chunks
381-
return;
382-
}
383-
} else if (chunk_index + 1 == verify_input_data->chunk_total) {
384-
memcpy(verify_input_data->locktime,
385-
raw_txn_chunk + verify_input_data->size_last_chunk - 4,
386-
4);
387-
verify_input_data->has_locktime = true;
388-
} else {
389-
// wait for subsequent chunks
390-
return;
391-
}
392-
}
393-
394-
// TODO: Add chunking condition for varint decode
395-
// refer: https://app.clickup.com/t/9002019994/PRF-7288
396-
static int64_t varint_decode(const uint8_t *raw_txn_chunk, int32_t *offset) {
397-
uint8_t first_byte = raw_txn_chunk[*offset];
398-
if (first_byte < 0xFD) {
399-
return first_byte;
400-
} else {
401-
// TODO: var-int varies between 1-9 bytes
402-
// current implementation supports decoding
403-
// upto 3 bytes only
404-
uint8_t result[2];
405-
memcpy(result, raw_txn_chunk + *offset + 1, 2);
406-
*offset += 2;
407-
return U16_READ_LE_ARRAY(result);
408-
}
409-
}
410330
/*****************************************************************************
411331
* GLOBAL FUNCTIONS
412332
*****************************************************************************/
413333

414-
int btc_verify_input(const uint8_t *raw_txn_chunk,
415-
const uint32_t chunk_index,
416-
btc_verify_input_t *verify_input_data,
417-
const btc_sign_txn_input_t *input) {
418-
if (NULL == input || NULL == raw_txn_chunk ||
419-
0 == verify_input_data->chunk_total) {
420-
return -1;
421-
}
422-
423-
int32_t offset = 0;
424-
if (chunk_index == 0) {
425-
// ignore network version (4-bytes), skip marker & flag (in segwit)
426-
offset += (raw_txn_chunk[4] == 0 ? 6 : 4);
427-
if (6 == offset) {
428-
verify_input_data->is_segwit = true;
429-
}
430-
431-
// TODO: Improve varint decode.
432-
// size of variable containing script size and ip-count/op-count
433-
// varies (1-9 Bytes) depending on its value.
434-
// refer:
435-
// https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer
436-
verify_input_data->count =
437-
raw_txn_chunk[offset++]; ///< store the number of inputs in the
438-
///< raw_txn
439-
440-
verify_input_data->parsetype = INPUT;
441-
sha256_Init(&(verify_input_data->sha_256_ctx));
442-
} else {
443-
offset += verify_input_data->prev_offset;
444-
}
445-
switch (verify_input_data->parsetype) {
446-
case INPUT: {
447-
while (verify_input_data->input_index < (verify_input_data->count) &&
448-
INPUT == verify_input_data->parsetype) {
449-
input_case ip_case = verify_input_data->input_parse;
450-
switch (ip_case) {
451-
case PREVIOUS_TX_HASH_PLUS_OP_INDEX_CASE: {
452-
if (offset + 36 >= CHUNK_SIZE) {
453-
verify_input_data->prev_offset = (offset + 36) - CHUNK_SIZE;
454-
update_hash(
455-
verify_input_data, raw_txn_chunk, chunk_index, CHUNK_SIZE);
456-
verify_input_data->input_parse = SCRIPT_LENGTH_CASE;
457-
return 4;
458-
} else {
459-
offset += 36;
460-
}
461-
}
462-
463-
case SCRIPT_LENGTH_CASE: {
464-
int64_t script_length = varint_decode(raw_txn_chunk, &offset);
465-
if (offset + script_length + 1 + 4 >= CHUNK_SIZE) {
466-
verify_input_data->prev_offset =
467-
(offset + script_length + 1 + 4) - CHUNK_SIZE;
468-
update_hash(
469-
verify_input_data, raw_txn_chunk, chunk_index, CHUNK_SIZE);
470-
verify_input_data->input_parse =
471-
PREVIOUS_TX_HASH_PLUS_OP_INDEX_CASE;
472-
verify_input_data->input_index++;
473-
return 4;
474-
} else {
475-
offset += (script_length + 1 + 4);
476-
}
477-
break;
478-
}
479-
480-
default:
481-
break;
482-
}
483-
verify_input_data->input_parse = PREVIOUS_TX_HASH_PLUS_OP_INDEX_CASE;
484-
verify_input_data->input_index++;
485-
}
486-
verify_input_data->parsetype = OP_COUNT;
487-
}
488-
489-
case OP_COUNT: {
490-
if (offset + 1 >= CHUNK_SIZE) {
491-
// reset prev offset
492-
verify_input_data->prev_offset =
493-
offset - CHUNK_SIZE; ///< Did not add +1 as returning back to
494-
///< this stage to read op count
495-
update_hash(verify_input_data, raw_txn_chunk, chunk_index, CHUNK_SIZE);
496-
return 4;
497-
} else {
498-
verify_input_data->count = raw_txn_chunk[offset++];
499-
}
500-
verify_input_data->parsetype = OUTPUT;
501-
verify_input_data->output_parse = VALUE_CASE;
502-
}
503-
504-
case OUTPUT: {
505-
while (verify_input_data->output_index < verify_input_data->count) {
506-
output_case op_case = verify_input_data->output_parse;
507-
switch (op_case) {
508-
case VALUE_CASE: {
509-
if (verify_input_data->output_index == input->prev_output_index) {
510-
if (offset + 8 >= CHUNK_SIZE) {
511-
verify_input_data->prev_offset = (offset + 8) - CHUNK_SIZE;
512-
memcpy(verify_input_data->value,
513-
raw_txn_chunk + offset,
514-
CHUNK_SIZE - offset);
515-
update_hash(
516-
verify_input_data, raw_txn_chunk, chunk_index, CHUNK_SIZE);
517-
verify_input_data->output_parse = VALUE_SPLIT_CASE;
518-
verify_input_data->is_split = 1;
519-
return 4;
520-
} else {
521-
memcpy(verify_input_data->value, raw_txn_chunk + offset, 8);
522-
}
523-
}
524-
if (offset + 8 >= CHUNK_SIZE) {
525-
verify_input_data->prev_offset = (offset + 8) - CHUNK_SIZE;
526-
update_hash(
527-
verify_input_data, raw_txn_chunk, chunk_index, CHUNK_SIZE);
528-
verify_input_data->output_parse = SCRIPT_PUBKEY_CASE;
529-
return 4;
530-
} else {
531-
offset += 8;
532-
}
533-
}
534-
535-
case VALUE_SPLIT_CASE: {
536-
if (verify_input_data->is_split) {
537-
memcpy(verify_input_data->value + (8 - offset),
538-
raw_txn_chunk,
539-
offset);
540-
verify_input_data->output_parse = SCRIPT_PUBKEY_CASE;
541-
verify_input_data->is_split = 0;
542-
}
543-
}
544-
545-
case SCRIPT_PUBKEY_CASE: {
546-
if (offset + raw_txn_chunk[offset] + 1 >= CHUNK_SIZE) {
547-
verify_input_data->prev_offset =
548-
(offset + raw_txn_chunk[offset] + 1) - CHUNK_SIZE;
549-
update_hash(
550-
verify_input_data, raw_txn_chunk, chunk_index, CHUNK_SIZE);
551-
verify_input_data->output_parse = VALUE_CASE;
552-
verify_input_data->output_index++;
553-
return 4;
554-
} else {
555-
offset += (raw_txn_chunk[offset] + 1);
556-
}
557-
break;
558-
}
559-
default:
560-
break;
561-
}
562-
verify_input_data->output_parse = VALUE_CASE;
563-
verify_input_data->output_index++;
564-
}
565-
566-
verify_input_data->parsetype = LOCK_TIME;
567-
update_hash(verify_input_data, raw_txn_chunk, chunk_index, offset);
568-
}
569-
570-
case LOCK_TIME: {
571-
update_locktime(verify_input_data, raw_txn_chunk, chunk_index);
572-
if (false == verify_input_data->has_locktime) {
573-
return 4;
574-
}
575-
sha256_Update(
576-
&(verify_input_data->sha_256_ctx), verify_input_data->locktime, 4);
577-
}
578-
default:
579-
break;
580-
}
581-
582-
verify_input_data->parsetype = END;
583-
584-
// Finalize hashing
585-
uint8_t hash[SHA256_DIGEST_LENGTH] = {0};
586-
sha256_Final(&(verify_input_data->sha_256_ctx), hash);
587-
588-
if (U64_READ_LE_ARRAY(verify_input_data->value) == 0) {
589-
return 1;
590-
}
591-
sha256_Raw(hash, sizeof(hash), hash);
592-
// verify input txn hash
593-
if (memcmp(hash, input->prev_txn_hash, sizeof(input->prev_txn_hash)) != 0) {
594-
return 2;
595-
}
596-
if (U64_READ_LE_ARRAY(verify_input_data->value) != input->value) {
597-
return 3;
598-
}
599-
return 0;
600-
}
601-
602334
uint64_t get_transaction_fee_threshold(const btc_txn_context_t *txn_ctx) {
603335
return (g_btc_app->max_fee / 1000) * (get_transaction_weight(txn_ctx) / 4);
604336
}

apps/btc_family/btc_txn_helpers.h

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@
1313
* INCLUDES
1414
*****************************************************************************/
1515

16-
#include "btc/sign_txn.pb.h"
1716
#include "btc_priv.h"
18-
#include "sha2.h"
1917

2018
/*****************************************************************************
2119
* MACROS AND DEFINES
@@ -26,39 +24,6 @@
2624
/*****************************************************************************
2725
* TYPEDEFS
2826
*****************************************************************************/
29-
typedef enum parse_type { INPUT, OP_COUNT, OUTPUT, LOCK_TIME, END } parse_type;
30-
31-
typedef enum input_case {
32-
PREVIOUS_TX_HASH_PLUS_OP_INDEX_CASE,
33-
SCRIPT_LENGTH_CASE,
34-
SEQ_CASE
35-
} input_case;
36-
37-
typedef enum output_case {
38-
VALUE_CASE,
39-
VALUE_SPLIT_CASE,
40-
SCRIPT_PUBKEY_CASE
41-
} output_case;
42-
43-
typedef enum hash_case { FIRST_CHUNK_HASH, DEFAULT } hash_case;
44-
typedef struct btc_verify_input {
45-
int32_t chunk_total;
46-
int32_t count; // count of ip/op
47-
int32_t prev_offset; // offset to remember from prev chunk
48-
int32_t input_index;
49-
int32_t output_index;
50-
SHA256_CTX sha_256_ctx;
51-
parse_type parsetype;
52-
input_case input_parse;
53-
output_case output_parse;
54-
bool is_segwit;
55-
bool is_split;
56-
bool has_locktime;
57-
bool is_locktime_split;
58-
int32_t size_last_chunk;
59-
uint8_t value[8];
60-
uint8_t locktime[4];
61-
} btc_verify_input_t;
6227

6328
/*****************************************************************************
6429
* EXPORTED VARIABLES
@@ -68,34 +33,6 @@ typedef struct btc_verify_input {
6833
* GLOBAL FUNCTION PROTOTYPES
6934
*****************************************************************************/
7035

71-
/**
72-
* @brief Verifies the provided input with its related raw transaction byte
73-
* @details The function verifies if the input details match with the details in
74-
* the raw transaction. This is done by checking the output value against the
75-
* specified output index in the raw transaction and then finally matching the
76-
* specified hash with the calculated hash from the raw transactions bytes.
77-
* To remove size limitations, the function requests the prev_txn from host
78-
* in chunks of size CHUNK_SIZE.
79-
*
80-
* @param [in] raw_txn_chunk current chunk of transaction.
81-
* @param [in] chunk_index index of current chunk.
82-
* @param [in] verify_input_data struct to hold data and flags required by
83-
* parser.
84-
* @param [in] input Immutable reference to the btc_txn_input_t.
85-
*
86-
* @return int Result of verification, 0 if verified otherwise error status.
87-
* @retval 0 Input verified successfully.
88-
* @retval -1 If function parameters are invalid
89-
* @retval 1 If specified output index (input->prev_output_index) is not present
90-
* @retval 2 If there is a hash (input->prev_txn_hash) mismatch
91-
* @retval 3 If there is a value (input->value) mismatch
92-
* @retval 4 If in processing state, not all chunks parsed
93-
*/
94-
int btc_verify_input(const uint8_t *raw_txn_chunk,
95-
const uint32_t chunk_index,
96-
btc_verify_input_t *verify_input_data,
97-
const btc_sign_txn_input_t *input);
98-
9936
/**
10037
* @brief Calculates an estimated upper cap on the transaction fee.
10138
* @details The function calculates the fee according to the assumed upper cap

0 commit comments

Comments
 (0)