Skip to content

Commit 13caab9

Browse files
committed
MASP Transactions must accompany MASP Transfers. MASP Builders must accompany MASP Transactions. Only sign displayed sections. Support signing non-MASP IBC Transfers.
1 parent ef0450c commit 13caab9

File tree

6 files changed

+42
-29
lines changed

6 files changed

+42
-29
lines changed

app/src/crypto.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ zxerr_t crypto_sign(const parser_tx_t *txObj, uint8_t *output, uint16_t outputLe
411411
signature_section.hashes.hashesLen += 2;
412412

413413
// Include Masp hash in the signature if it's there
414-
if (txObj->transaction.isMasp) {
414+
if ((txObj->typeTx == Transfer && txObj->transfer.has_shielded_hash) || (txObj->typeTx == IBC && txObj->ibc.transfer.has_shielded_hash)) {
415415
#if !defined(APP_TESTING)
416416
if (get_state() != STATE_EXTRACT_SPENDS) {
417417
return zxerr_unknown;

app/src/parser_impl.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ parser_error_t _read(parser_context_t *ctx, parser_tx_t *v) {
2727

2828
CHECK_ERROR(validateTransactionParams(v))
2929

30-
if(ctx->tx_obj->transaction.isMasp || ctx->tx_obj->ibc.is_ibc) {
31-
CHECK_ERROR(verifyShieldedHash(ctx))
32-
}
30+
CHECK_ERROR(verifyShieldedHash(ctx))
3331

3432
if (ctx->offset != ctx->bufferLen) {
3533
return parser_unexpected_unparsed_bytes;
@@ -51,7 +49,7 @@ parser_error_t getNumItems(const parser_context_t *ctx, uint8_t *numItems) {
5149
break;
5250

5351
case Transfer:
54-
if(ctx->tx_obj->transaction.isMasp) {
52+
if(ctx->tx_obj->transfer.has_shielded_hash) {
5553
uint8_t items = 1;
5654
items += 3 * ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.n_outputs; // print from outputs
5755
items += 3 * ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.n_spends; // print from spends
@@ -130,7 +128,7 @@ parser_error_t getNumItems(const parser_context_t *ctx, uint8_t *numItems) {
130128

131129
case IBC:
132130
*numItems = (app_mode_expert() ? IBC_EXPERT_PARAMS : IBC_NORMAL_PARAMS);
133-
if(ctx->tx_obj->transaction.isMasp) {
131+
if(ctx->tx_obj->ibc.transfer.has_shielded_hash) {
134132
*numItems += 3 * ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.n_outputs; // print from outputs
135133
*numItems += 3 * ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.n_spends; // print from spends
136134
}

app/src/parser_impl_txn.c

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,8 @@ parser_error_t readSections(parser_context_t *ctx, parser_tx_t *v) {
12551255
if (v->transaction.sections.sectionLen > 7) {
12561256
return parser_invalid_output_buffer;
12571257
}
1258-
v->transaction.isMasp = false;
1258+
v->transaction.hasMaspTx = false;
1259+
v->transaction.hasMaspBuilder = false;
12591260
v->transaction.sections.extraDataLen = 0;
12601261
v->transaction.sections.signaturesLen = 0;
12611262

@@ -1296,11 +1297,12 @@ parser_error_t readSections(parser_context_t *ctx, parser_tx_t *v) {
12961297
#if defined(COMPILE_MASP)
12971298
case DISCRIMINANT_MASP_TX:
12981299
// Identify tx has masp tx
1299-
v->transaction.isMasp = true;
1300+
v->transaction.hasMaspTx = true;
13001301
CHECK_ERROR(readMaspTx(ctx, &v->transaction.sections.maspTx))
13011302
v->transaction.maspTx_idx = i+1;
13021303
break;
13031304
case DISCRIMINANT_MASP_BUILDER:
1305+
v->transaction.hasMaspBuilder = true;
13041306
CHECK_ERROR(readMaspBuilder(ctx, &v->transaction.sections.maspBuilder))
13051307
break;
13061308
#endif
@@ -1421,24 +1423,36 @@ parser_error_t verifyShieldedHash(parser_context_t *ctx) {
14211423
}
14221424

14231425
#if defined(LEDGER_SPECIFIC)
1424-
// compute tx_id hash
14251426
uint8_t tx_id_hash[HASH_LEN] = {0};
1426-
if (tx_hash_txId(ctx->tx_obj, tx_id_hash) != zxerr_ok) {
1427-
return parser_unexpected_error;
1428-
}
1429-
1430-
if (ctx->tx_obj->transaction.sections.maspBuilder.target_hash.len == HASH_LEN) {
1431-
if (memcmp(tx_id_hash, ctx->tx_obj->transaction.sections.maspBuilder.target_hash.ptr, HASH_LEN) != 0) {
1427+
if (ctx->tx_obj->transaction.hasMaspTx) {
1428+
if (!ctx->tx_obj->transaction.hasMaspBuilder) {
1429+
// MASP Trabsactions must be accompanied by MASP Builders
1430+
return parser_unexpected_error;
1431+
} else if (tx_hash_txId(ctx->tx_obj, tx_id_hash) != zxerr_ok) {
1432+
// compute tx_id hash
1433+
return parser_unexpected_error;
1434+
} else if (memcmp(tx_id_hash, ctx->tx_obj->transaction.sections.maspBuilder.target_hash.ptr, HASH_LEN) != 0) {
1435+
// MASP Builder must have the correct TxId
14321436
return parser_invalid_target_hash;
14331437
}
14341438
}
14351439

1436-
if (ctx->tx_obj->transfer.has_shielded_hash && memcmp(ctx->tx_obj->transfer.shielded_hash.ptr, tx_id_hash, HASH_LEN) != 0) {
1437-
return parser_invalid_target_hash;
1438-
}
1439-
1440-
if(ctx->tx_obj->ibc.transfer.has_shielded_hash && memcmp(ctx->tx_obj->ibc.transfer.shielded_hash.ptr, tx_id_hash, HASH_LEN) != 0) {
1441-
return parser_invalid_target_hash;
1440+
if (ctx->tx_obj->typeTx == Transfer && ctx->tx_obj->transfer.has_shielded_hash) {
1441+
if (!ctx->tx_obj->transaction.hasMaspTx) {
1442+
// MASP transfers must be accompanied by MASP Transactions
1443+
return parser_unexpected_error;
1444+
} else if (memcmp(ctx->tx_obj->transfer.shielded_hash.ptr, tx_id_hash, HASH_LEN) != 0) {
1445+
// MASP Transactions must have the correct TxId
1446+
return parser_invalid_target_hash;
1447+
}
1448+
} else if (ctx->tx_obj->typeTx == IBC && ctx->tx_obj->ibc.transfer.has_shielded_hash) {
1449+
if (!ctx->tx_obj->transaction.hasMaspTx) {
1450+
// IBC MASP transfers must be accompanied by MASP Transactions
1451+
return parser_unexpected_error;
1452+
} else if (memcmp(ctx->tx_obj->ibc.transfer.shielded_hash.ptr, tx_id_hash, HASH_LEN) != 0) {
1453+
// MASP Transactions must have the correct TxId
1454+
return parser_invalid_target_hash;
1455+
}
14421456
}
14431457
#endif
14441458

app/src/parser_print_txn.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,8 @@ static parser_error_t printTransferTxn( const parser_context_t *ctx,
174174
// Get pointer to the outputs
175175
bytes_t out = ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.outputs;
176176
// Compute number of spends/outs in the builder tx , and number of itemns to be printer for each
177-
uint32_t n_spends = ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.n_spends * (uint32_t) ctx->tx_obj->transaction.isMasp;
178-
uint32_t n_outs = ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.n_outputs * (uint32_t) ctx->tx_obj->transaction.isMasp;
177+
uint32_t n_spends = ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.n_spends * (uint32_t) ctx->tx_obj->transfer.has_shielded_hash;
178+
uint32_t n_outs = ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.n_outputs * (uint32_t) ctx->tx_obj->transfer.has_shielded_hash;
179179
uint16_t spend_index = 0;
180180
uint16_t out_index = 0;
181181

@@ -1132,8 +1132,8 @@ static parser_error_t printIBCTxn( const parser_context_t *ctx,
11321132
// Get pointer to the outputs
11331133
bytes_t out = ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.outputs;
11341134
// Compute number of spends/outs in the builder tx , and number of itemns to be printer for each
1135-
uint32_t n_spends = ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.n_spends * (uint32_t) ctx->tx_obj->transaction.isMasp;
1136-
uint32_t n_outs = ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.n_outputs * (uint32_t) ctx->tx_obj->transaction.isMasp;
1135+
uint32_t n_spends = ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.n_spends * (uint32_t) ctx->tx_obj->ibc.transfer.has_shielded_hash;
1136+
uint32_t n_outs = ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.n_outputs * (uint32_t) ctx->tx_obj->ibc.transfer.has_shielded_hash;
11371137
uint16_t spend_index = 0;
11381138
uint16_t out_index = 0;
11391139

@@ -1445,8 +1445,8 @@ static parser_error_t printNFTIBCTxn( const parser_context_t *ctx,
14451445
// Get pointer to the outputs
14461446
bytes_t out = ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.outputs;
14471447
// Compute number of spends/outs in the builder tx , and number of itemns to be printer for each
1448-
uint32_t n_spends = ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.n_spends * (uint32_t) ctx->tx_obj->transaction.isMasp;
1449-
uint32_t n_outs = ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.n_outputs * (uint32_t) ctx->tx_obj->transaction.isMasp;
1448+
uint32_t n_spends = ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.n_spends * (uint32_t) ctx->tx_obj->ibc.transfer.has_shielded_hash;
1449+
uint32_t n_outs = ctx->tx_obj->transaction.sections.maspBuilder.builder.sapling_builder.n_outputs * (uint32_t) ctx->tx_obj->ibc.transfer.has_shielded_hash;
14501450
uint16_t spend_index = 0;
14511451
uint16_t out_index = 0;
14521452

app/src/parser_txdef.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,8 @@ typedef struct {
280280
header_t header;
281281
sections_t sections;
282282
uint8_t maspTx_idx;
283-
bool isMasp;
283+
bool hasMaspTx;
284+
bool hasMaspBuilder;
284285
} transaction_t;
285286

286287

tests/testvectors.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50947,4 +50947,4 @@
5094750947
],
5094850948
"valid": true
5094950949
}
50950-
]
50950+
]

0 commit comments

Comments
 (0)