WIP field hashing support
This commit is contained in:
@@ -3,34 +3,140 @@
|
||||
#include "field_hash.h"
|
||||
#include "encode_field.h"
|
||||
#include "path.h"
|
||||
#include "mem.h"
|
||||
#include "eip712.h"
|
||||
#include "shared_context.h"
|
||||
|
||||
const uint8_t *field_hash(const void *const structs_array,
|
||||
const uint8_t *const data,
|
||||
const uint8_t data_length)
|
||||
static s_field_hashing *fh = NULL;
|
||||
|
||||
static bool field_hash_init(void)
|
||||
{
|
||||
if (fh == NULL)
|
||||
{
|
||||
if ((fh = mem_alloc(sizeof(*fh))) == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
fh->state = FHS_IDLE;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint8_t *field_hash(const uint8_t *data,
|
||||
uint8_t data_length,
|
||||
bool partial)
|
||||
{
|
||||
const void *field_ptr;
|
||||
const char *type;
|
||||
uint8_t typelen;
|
||||
const char *key;
|
||||
uint8_t keylen;
|
||||
const void *field;
|
||||
e_type field_type;
|
||||
uint8_t *hash_ptr = NULL;
|
||||
|
||||
(void)structs_array;
|
||||
(void)data;
|
||||
(void)data_length;
|
||||
// get field by path
|
||||
//encode_integer(data, data_length);
|
||||
field = path_get_field();
|
||||
if (field != NULL)
|
||||
if ((fh == NULL) && (field_hash_init() == false))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
// get field by path
|
||||
if ((field_ptr = path_get_field()) == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
field_type = struct_field_type(field_ptr);
|
||||
if (fh->state == FHS_IDLE) // first packet for this frame
|
||||
{
|
||||
fh->remaining_size = (data[0] << 8) | data[1]; // network byte order
|
||||
data += sizeof(uint16_t);
|
||||
data_length -= sizeof(uint16_t);
|
||||
fh->state = FHS_WAITING_FOR_MORE;
|
||||
cx_keccak_init((cx_hash_t*)&global_sha3, 256); // init hash
|
||||
}
|
||||
fh->remaining_size -= data_length;
|
||||
// if a dynamic type -> continue progressive hash
|
||||
if (IS_DYN(field_type))
|
||||
{
|
||||
cx_hash((cx_hash_t*)&global_sha3,
|
||||
0,
|
||||
data,
|
||||
data_length,
|
||||
NULL,
|
||||
0);
|
||||
}
|
||||
if (fh->remaining_size == 0)
|
||||
{
|
||||
if (partial) // only makes sense if marked as complete
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
printf("==> ");
|
||||
type = get_struct_field_typename(field, &typelen);
|
||||
type = get_struct_field_typename(field_ptr, &typelen);
|
||||
fwrite(type, sizeof(char), typelen, stdout);
|
||||
printf(" ");
|
||||
key = get_struct_field_keyname(field, &keylen);
|
||||
key = get_struct_field_keyname(field_ptr, &keylen);
|
||||
fwrite(key, sizeof(char), keylen, stdout);
|
||||
printf("\n");
|
||||
|
||||
uint8_t *value = NULL;
|
||||
|
||||
if (!IS_DYN(field_type))
|
||||
{
|
||||
switch (field_type)
|
||||
{
|
||||
case TYPE_SOL_INT:
|
||||
case TYPE_SOL_UINT:
|
||||
case TYPE_SOL_BYTES_FIX:
|
||||
value = encode_integer(data, data_length);
|
||||
break;
|
||||
case TYPE_SOL_ADDRESS:
|
||||
value = encode_address(data, data_length);
|
||||
break;
|
||||
case TYPE_SOL_BOOL:
|
||||
value = encode_boolean((bool*)data, data_length);
|
||||
break;
|
||||
case TYPE_CUSTOM:
|
||||
default:
|
||||
printf("Unknown solidity type!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (value == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
cx_hash((cx_hash_t*)&global_sha3,
|
||||
0,
|
||||
(uint8_t*)value,
|
||||
EIP_712_ENCODED_FIELD_LENGTH,
|
||||
NULL,
|
||||
0);
|
||||
|
||||
// restore the memory location
|
||||
mem_dealloc(EIP_712_ENCODED_FIELD_LENGTH);
|
||||
}
|
||||
|
||||
if ((hash_ptr = mem_alloc(KECCAK256_HASH_BYTESIZE)) == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
// copy hash into memory
|
||||
cx_hash((cx_hash_t*)&global_sha3,
|
||||
CX_LAST,
|
||||
NULL,
|
||||
0,
|
||||
hash_ptr,
|
||||
KECCAK256_HASH_BYTESIZE);
|
||||
|
||||
path_advance();
|
||||
fh->state = FHS_IDLE;
|
||||
}
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
if (!partial || !IS_DYN(field_type)) // only makes sense if marked as partial
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return hash_ptr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user