1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-22 14:28:07 +00:00

nem: refactor serialization code

This commit is contained in:
Saleem Rashid 2019-02-16 15:00:56 +01:00 committed by Pavol Rusnak
parent e3caf14c43
commit 2ac59892b7
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
2 changed files with 98 additions and 169 deletions

244
nem.c
View File

@ -30,6 +30,16 @@
#include "sha3.h" #include "sha3.h"
#include "memzero.h" #include "memzero.h"
#define CAN_WRITE(NEEDED) ((ctx->offset + (NEEDED)) <= ctx->size)
#define SERIALIZE_U32(DATA) \
do { if (!nem_write_u32(ctx, (DATA))) return false; } while (0)
#define SERIALIZE_U64(DATA) \
do { if (!nem_write_u64(ctx, (DATA))) return false; } while (0)
#define SERIALIZE_TAGGED(DATA, LENGTH) \
do { if (!nem_write_tagged(ctx, (DATA), (LENGTH))) return false; } while (0)
const char *nem_network_name(uint8_t network) { const char *nem_network_name(uint8_t network) {
switch (network) { switch (network) {
case NEM_NETWORK_MAINNET: case NEM_NETWORK_MAINNET:
@ -43,39 +53,49 @@ const char *nem_network_name(uint8_t network) {
} }
} }
static inline void nem_write_u32(nem_transaction_ctx *ctx, uint32_t data) { static inline bool nem_write_checked(nem_transaction_ctx *ctx, const uint8_t *data, uint32_t length) {
if (!CAN_WRITE(length)) {
return false;
}
memcpy(&ctx->buffer[ctx->offset], data, length);
ctx->offset += length;
return true;
}
static inline bool nem_write_u32(nem_transaction_ctx *ctx, uint32_t data) {
if (!CAN_WRITE(4)) {
return false;
}
ctx->buffer[ctx->offset++] = (data >> 0) & 0xff; ctx->buffer[ctx->offset++] = (data >> 0) & 0xff;
ctx->buffer[ctx->offset++] = (data >> 8) & 0xff; ctx->buffer[ctx->offset++] = (data >> 8) & 0xff;
ctx->buffer[ctx->offset++] = (data >> 16) & 0xff; ctx->buffer[ctx->offset++] = (data >> 16) & 0xff;
ctx->buffer[ctx->offset++] = (data >> 24) & 0xff; ctx->buffer[ctx->offset++] = (data >> 24) & 0xff;
return true;
} }
static inline void nem_write_u64(nem_transaction_ctx *ctx, uint64_t data) { static inline bool nem_write_u64(nem_transaction_ctx *ctx, uint64_t data) {
nem_write_u32(ctx, (data >> 0) & 0xffffffff); SERIALIZE_U32((data >> 0) & 0xffffffff);
nem_write_u32(ctx, (data >> 32) & 0xffffffff); SERIALIZE_U32((data >> 32) & 0xffffffff);
return true;
} }
static inline void nem_write(nem_transaction_ctx *ctx, const uint8_t *data, uint32_t length) { static inline bool nem_write_tagged(nem_transaction_ctx *ctx, const uint8_t *data, uint32_t length) {
nem_write_u32(ctx, length); SERIALIZE_U32(length);
memcpy(&ctx->buffer[ctx->offset], data, length); return nem_write_checked(ctx, data, length);
ctx->offset += length;
}
static inline bool nem_can_write(nem_transaction_ctx *ctx, size_t needed) {
return (ctx->offset + needed) <= ctx->size;
} }
static inline bool nem_write_mosaic_str(nem_transaction_ctx *ctx, const char *name, const char *value) { static inline bool nem_write_mosaic_str(nem_transaction_ctx *ctx, const char *name, const char *value) {
uint32_t name_length = strlen(name); uint32_t name_length = strlen(name);
uint32_t value_length = strlen(value); uint32_t value_length = strlen(value);
#define NEM_SERIALIZE \ SERIALIZE_U32(sizeof(uint32_t) + name_length + sizeof(uint32_t) + value_length);
serialize_u32(sizeof(uint32_t) + name_length + sizeof(uint32_t) + value_length) \ SERIALIZE_TAGGED((const uint8_t *) name, name_length);
serialize_write((uint8_t *) name, name_length) \ SERIALIZE_TAGGED((const uint8_t *) value, value_length);
serialize_write((uint8_t *) value, value_length)
#include "nem_serialize.h"
return true; return true;
} }
@ -178,15 +198,12 @@ bool nem_transaction_write_common(nem_transaction_ctx *ctx,
uint64_t fee, uint64_t fee,
uint32_t deadline) { uint32_t deadline) {
#define NEM_SERIALIZE \ SERIALIZE_U32(type);
serialize_u32(type) \ SERIALIZE_U32(version);
serialize_u32(version) \ SERIALIZE_U32(timestamp);
serialize_u32(timestamp) \ SERIALIZE_TAGGED(signer, sizeof(ed25519_public_key));
serialize_write(signer, sizeof(ed25519_public_key)) \ SERIALIZE_U64(fee);
serialize_u64(fee) \ SERIALIZE_U32(deadline);
serialize_u32(deadline)
#include "nem_serialize.h"
return true; return true;
} }
@ -221,36 +238,20 @@ bool nem_transaction_create_transfer(nem_transaction_ctx *ctx,
deadline); deadline);
if (!ret) return false; if (!ret) return false;
#define NEM_SERIALIZE \ SERIALIZE_TAGGED((const uint8_t *) recipient, NEM_ADDRESS_SIZE);
serialize_write((uint8_t *) recipient, NEM_ADDRESS_SIZE) \ SERIALIZE_U64(amount);
serialize_u64(amount)
#include "nem_serialize.h"
if (length) { if (length) {
SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint32_t) + length);
#define NEM_SERIALIZE \ SERIALIZE_U32(encrypted ? 0x02 : 0x01);
serialize_u32(sizeof(uint32_t) + sizeof(uint32_t) + length) \ SERIALIZE_TAGGED(payload, length);
serialize_u32(encrypted ? 0x02 : 0x01) \
serialize_write(payload, length)
#include "nem_serialize.h"
} else { } else {
SERIALIZE_U32(0);
#define NEM_SERIALIZE \
serialize_u32(0)
#include "nem_serialize.h"
} }
if (mosaics) { if (mosaics) {
#define NEM_SERIALIZE \ SERIALIZE_U32(mosaics);
serialize_u32(mosaics)
#include "nem_serialize.h"
} }
@ -266,14 +267,11 @@ bool nem_transaction_write_mosaic(nem_transaction_ctx *ctx,
size_t mosaic_length = strlen(mosaic); size_t mosaic_length = strlen(mosaic);
size_t identifier_length = sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length; size_t identifier_length = sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length;
#define NEM_SERIALIZE \ SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint64_t) + identifier_length);
serialize_u32(sizeof(uint32_t) + sizeof(uint64_t) + identifier_length) \ SERIALIZE_U32(identifier_length);
serialize_u32(identifier_length) \ SERIALIZE_TAGGED((const uint8_t *) namespace, namespace_length);
serialize_write((uint8_t *) namespace, namespace_length) \ SERIALIZE_TAGGED((const uint8_t *) mosaic, mosaic_length);
serialize_write((uint8_t *) mosaic, mosaic_length) \ SERIALIZE_U64(quantity);
serialize_u64(quantity)
#include "nem_serialize.h"
return true; return true;
} }
@ -299,10 +297,7 @@ bool nem_transaction_create_multisig(nem_transaction_ctx *ctx,
deadline); deadline);
if (!ret) return false; if (!ret) return false;
#define NEM_SERIALIZE \ SERIALIZE_TAGGED(inner->buffer, inner->offset);
serialize_write(inner->buffer, inner->offset)
#include "nem_serialize.h"
return true; return true;
} }
@ -334,12 +329,9 @@ bool nem_transaction_create_multisig_signature(nem_transaction_ctx *ctx,
uint8_t hash[SHA3_256_DIGEST_LENGTH]; uint8_t hash[SHA3_256_DIGEST_LENGTH];
keccak_256(inner->buffer, inner->offset, hash); keccak_256(inner->buffer, inner->offset, hash);
#define NEM_SERIALIZE \ SERIALIZE_U32(sizeof(uint32_t) + SHA3_256_DIGEST_LENGTH);
serialize_u32(sizeof(uint32_t) + SHA3_256_DIGEST_LENGTH) \ SERIALIZE_TAGGED(hash, SHA3_256_DIGEST_LENGTH);
serialize_write(hash, SHA3_256_DIGEST_LENGTH) \ SERIALIZE_TAGGED((const uint8_t *) address, NEM_ADDRESS_SIZE);
serialize_write((uint8_t *) address, NEM_ADDRESS_SIZE)
#include "nem_serialize.h"
return true; return true;
} }
@ -369,25 +361,15 @@ bool nem_transaction_create_provision_namespace(nem_transaction_ctx *ctx,
if (!ret) return false; if (!ret) return false;
if (parent) { if (parent) {
SERIALIZE_TAGGED((const uint8_t *) rental_sink, NEM_ADDRESS_SIZE);
#define NEM_SERIALIZE \ SERIALIZE_U64(rental_fee);
serialize_write((uint8_t *) rental_sink, NEM_ADDRESS_SIZE) \ SERIALIZE_TAGGED((const uint8_t *) namespace, strlen(namespace));
serialize_u64(rental_fee) \ SERIALIZE_TAGGED((const uint8_t *) parent, strlen(parent));
serialize_write((uint8_t *) namespace, strlen(namespace)) \
serialize_write((uint8_t *) parent, strlen(parent))
#include "nem_serialize.h"
} else { } else {
SERIALIZE_TAGGED((const uint8_t *) rental_sink, NEM_ADDRESS_SIZE);
#define NEM_SERIALIZE \ SERIALIZE_U64(rental_fee);
serialize_write((uint8_t *) rental_sink, NEM_ADDRESS_SIZE) \ SERIALIZE_TAGGED((const uint8_t *) namespace, strlen(namespace));
serialize_u64(rental_fee) \ SERIALIZE_U32(0xffffffff);
serialize_write((uint8_t *) namespace, strlen(namespace)) \
serialize_u32(0xffffffff)
#include "nem_serialize.h"
} }
return true; return true;
@ -435,16 +417,13 @@ bool nem_transaction_create_mosaic_creation(nem_transaction_ctx *ctx,
nem_transaction_ctx state; nem_transaction_ctx state;
memcpy(&state, ctx, sizeof(state)); memcpy(&state, ctx, sizeof(state));
#define NEM_SERIALIZE \ SERIALIZE_U32(0);
serialize_u32(0) \ SERIALIZE_TAGGED(signer, sizeof(ed25519_public_key));
serialize_write(signer, sizeof(ed25519_public_key)) \ SERIALIZE_U32(identifier_length);
serialize_u32(identifier_length) \ SERIALIZE_TAGGED((const uint8_t *) namespace, namespace_length);
serialize_write((uint8_t *) namespace, namespace_length) \ SERIALIZE_TAGGED((const uint8_t *) mosaic, mosaic_length);
serialize_write((uint8_t *) mosaic, mosaic_length) \ SERIALIZE_TAGGED((const uint8_t *) description, strlen(description));
serialize_write((uint8_t *) description, strlen(description)) \ SERIALIZE_U32(4); // Number of properties
serialize_u32(4) // Number of properties
#include "nem_serialize.h"
if (!nem_write_mosaic_u64(ctx, "divisibility", divisibility)) return false; if (!nem_write_mosaic_u64(ctx, "divisibility", divisibility)) return false;
if (!nem_write_mosaic_u64(ctx, "initialSupply", supply)) return false; if (!nem_write_mosaic_u64(ctx, "initialSupply", supply)) return false;
@ -456,34 +435,22 @@ bool nem_transaction_create_mosaic_creation(nem_transaction_ctx *ctx,
size_t levy_mosaic_length = strlen(levy_mosaic); size_t levy_mosaic_length = strlen(levy_mosaic);
size_t levy_identifier_length = sizeof(uint32_t) + levy_namespace_length + sizeof(uint32_t) + levy_mosaic_length; size_t levy_identifier_length = sizeof(uint32_t) + levy_namespace_length + sizeof(uint32_t) + levy_mosaic_length;
#define NEM_SERIALIZE \ SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint32_t) + NEM_ADDRESS_SIZE + sizeof(uint32_t) + levy_identifier_length + sizeof(uint64_t));
serialize_u32(sizeof(uint32_t) + sizeof(uint32_t) + NEM_ADDRESS_SIZE + sizeof(uint32_t) + levy_identifier_length + sizeof(uint64_t)) \ SERIALIZE_U32(levy_type);
serialize_u32(levy_type) \ SERIALIZE_TAGGED((const uint8_t *) levy_address, NEM_ADDRESS_SIZE);
serialize_write((uint8_t *) levy_address, NEM_ADDRESS_SIZE) \ SERIALIZE_U32(levy_identifier_length);
serialize_u32(levy_identifier_length) \ SERIALIZE_TAGGED((const uint8_t *) levy_namespace, levy_namespace_length);
serialize_write((uint8_t *) levy_namespace, levy_namespace_length) \ SERIALIZE_TAGGED((const uint8_t *) levy_mosaic, levy_mosaic_length);
serialize_write((uint8_t *) levy_mosaic, levy_mosaic_length) \ SERIALIZE_U64(levy_fee);
serialize_u64(levy_fee)
#include "nem_serialize.h"
} else { } else {
SERIALIZE_U32(0);
#define NEM_SERIALIZE \
serialize_u32(0)
#include "nem_serialize.h"
} }
// Rewrite length // Rewrite length
nem_write_u32(&state, ctx->offset - state.offset - sizeof(uint32_t)); nem_write_u32(&state, ctx->offset - state.offset - sizeof(uint32_t));
#define NEM_SERIALIZE \ SERIALIZE_TAGGED((const uint8_t *) creation_sink, NEM_ADDRESS_SIZE);
serialize_write((uint8_t *) creation_sink, NEM_ADDRESS_SIZE) \ SERIALIZE_U64(creation_fee);
serialize_u64(creation_fee)
#include "nem_serialize.h"
return true; return true;
@ -517,14 +484,11 @@ bool nem_transaction_create_mosaic_supply_change(nem_transaction_ctx *ctx,
size_t mosaic_length = strlen(mosaic); size_t mosaic_length = strlen(mosaic);
size_t identifier_length = sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length; size_t identifier_length = sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length;
#define NEM_SERIALIZE \ SERIALIZE_U32(identifier_length);
serialize_u32(identifier_length) \ SERIALIZE_TAGGED((const uint8_t *) namespace, namespace_length);
serialize_write((uint8_t *) namespace, namespace_length) \ SERIALIZE_TAGGED((const uint8_t *) mosaic, mosaic_length);
serialize_write((uint8_t *) mosaic, mosaic_length) \ SERIALIZE_U32(type);
serialize_u32(type) \ SERIALIZE_U64(delta);
serialize_u64(delta)
#include "nem_serialize.h"
return true; return true;
} }
@ -551,10 +515,7 @@ bool nem_transaction_create_aggregate_modification(nem_transaction_ctx *ctx,
deadline); deadline);
if (!ret) return false; if (!ret) return false;
#define NEM_SERIALIZE \ SERIALIZE_U32(modifications);
serialize_u32(modifications)
#include "nem_serialize.h"
return true; return true;
} }
@ -563,12 +524,9 @@ bool nem_transaction_write_cosignatory_modification(nem_transaction_ctx *ctx,
uint32_t type, uint32_t type,
const ed25519_public_key cosignatory) { const ed25519_public_key cosignatory) {
#define NEM_SERIALIZE \ SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(ed25519_public_key));
serialize_u32(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(ed25519_public_key)) \ SERIALIZE_U32(type);
serialize_u32(type) \ SERIALIZE_TAGGED(cosignatory, sizeof(ed25519_public_key));
serialize_write(cosignatory, sizeof(ed25519_public_key))
#include "nem_serialize.h"
return true; return true;
} }
@ -576,11 +534,8 @@ bool nem_transaction_write_cosignatory_modification(nem_transaction_ctx *ctx,
bool nem_transaction_write_minimum_cosignatories(nem_transaction_ctx *ctx, bool nem_transaction_write_minimum_cosignatories(nem_transaction_ctx *ctx,
int32_t relative_change) { int32_t relative_change) {
#define NEM_SERIALIZE \ SERIALIZE_U32(sizeof(uint32_t));
serialize_u32(sizeof(uint32_t)) \ SERIALIZE_U32((uint32_t) relative_change);
serialize_u32((uint32_t) relative_change)
#include "nem_serialize.h"
return true; return true;
} }
@ -607,11 +562,8 @@ bool nem_transaction_create_importance_transfer(nem_transaction_ctx *ctx,
deadline); deadline);
if (!ret) return false; if (!ret) return false;
#define NEM_SERIALIZE \ SERIALIZE_U32(mode);
serialize_u32(mode) \ SERIALIZE_TAGGED(remote, sizeof(ed25519_public_key));
serialize_write(remote, sizeof(ed25519_public_key))
#include "nem_serialize.h"
return true; return true;
} }

View File

@ -1,23 +0,0 @@
#define serialize_u32(data) + sizeof(uint32_t)
#define serialize_u64(data) + sizeof(uint64_t)
#define serialize_write(data, length) + (length)
if (!nem_can_write(ctx, NEM_SERIALIZE)) {
return false;
}
#undef serialize_u32
#undef serialize_u64
#undef serialize_write
#define serialize_u32(data) nem_write_u32(ctx, (data));
#define serialize_u64(data) nem_write_u64(ctx, (data));
#define serialize_write(data, length) nem_write(ctx, (data), (length));
NEM_SERIALIZE
#undef serialize_u32
#undef serialize_u64
#undef serialize_write
#undef NEM_SERIALIZE