From 9295748011e1e1c642c5f6033572375e0b201bb9 Mon Sep 17 00:00:00 2001 From: Michele Balistreri Date: Mon, 14 Aug 2023 15:57:21 +0200 Subject: [PATCH] support 256 bit decimal strings --- app/crypto/util.c | 50 ++++++++++++++++++++++++++++++++++++------- app/crypto/util.h | 2 +- app/ethereum/eip712.c | 11 ++-------- 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/app/crypto/util.c b/app/crypto/util.c index dd772a5..c606fe4 100644 --- a/app/crypto/util.c +++ b/app/crypto/util.c @@ -76,32 +76,66 @@ bool base16_decode(const char* s, uint8_t* out, size_t s_len) { return true; } -bool atoi64(const char* str, size_t len, int64_t* res) { +bool atoi256BE(const char* str, size_t len, uint8_t out[32]) { int i; - int sign; + bool neg; if (str[0] == '-') { - sign = -1; + neg = true; i = 1; } else if (str[0] == '+') { - sign = 1; + neg = false; i = 1; } else { - sign = 1; + neg = false; i = 0; } - *res = 0; + uint32_t limbs[9]; + memset(limbs, 0, sizeof(uint32_t) * 9); while(i < len) { if (!(str[i] >= '0' && str[i] <= '9')) { return false; } - *res = (10 * (*res)) + (str[i++] - '0'); + int d = (str[i++] - '0'); + + for (int j = 0; j < 9; j++) { + limbs[j] *= 10; + } + + limbs[0] += d; + + for (int j = 0; j < 8; j++) { + limbs[j + 1] += limbs[j] >> 28; + limbs[j] &= 0x0fffffff; + } } - *res = (*res) * sign; + if (neg) { + for (int i = 0; i < 9; i++) { + limbs[i] = ~limbs[i] & 0x0fffffff; + } + + limbs[0] += 1; + + for (int i = 0; i < 8; i++) { + limbs[i + 1] += limbs[i] >> 28; + limbs[i] &= 0x0fffffff; + } + } + + uint32_t* out32 = (uint32_t*) out; + + out32[7] = rev32(((limbs[1] & 0xf) << 28) | limbs[0]); + out32[6] = rev32(((limbs[2] & 0xff) << 24) | (limbs[1] >> 4)); + out32[5] = rev32(((limbs[3] & 0xfff) << 20) | (limbs[2] >> 8)); + out32[4] = rev32(((limbs[4] & 0xffff) << 16) | (limbs[3] >> 12)); + out32[3] = rev32(((limbs[5] & 0xfffff) << 12) | (limbs[4] >> 16)); + out32[2] = rev32(((limbs[6] & 0xffffff) << 8) | (limbs[5] >> 20)); + out32[1] = rev32(((limbs[7] & 0xfffffff) << 4) | (limbs[6] >> 24)); + out32[0] = rev32((limbs[8] & 0xffffffff) | (limbs[7] >> 28)); return true; } diff --git a/app/crypto/util.h b/app/crypto/util.h index 5ced7f5..5911791 100644 --- a/app/crypto/util.h +++ b/app/crypto/util.h @@ -11,7 +11,7 @@ uint8_t* u32toa(uint32_t value, uint8_t* buf, uint32_t len); size_t strnlen(const char *s, size_t maxlen); bool base16_decode(const char* s, uint8_t* out, size_t s_len); -bool atoi64(const char* str, size_t len, int64_t* res); +bool atoi256BE(const char* str, size_t len, uint8_t out[32]); static inline int memcmp_ct(const uint8_t* a, const uint8_t* b, size_t length) { int compareSum = 0; diff --git a/app/ethereum/eip712.c b/app/ethereum/eip712.c index cb31853..2f6aa74 100644 --- a/app/ethereum/eip712.c +++ b/app/ethereum/eip712.c @@ -416,16 +416,9 @@ static app_err_t eip712_encode_field(uint8_t out[32], uint8_t* heap, size_t heap return ERR_DATA; } } else { - int64_t res; - if (!atoi64(&json[tokens[field_val].start], (tokens[field_val].end - tokens[field_val].start), &res)) { + if (!atoi256BE(&json[tokens[field_val].start], (tokens[field_val].end - tokens[field_val].start), out)) { return ERR_DATA; } - - memset(out, res < 0 ? 0xff : 0x00, 24); - for (int i = 31; i >= 24; i--) { - out[i] = res & 0xff; - res >>= 8; - } } } @@ -443,7 +436,7 @@ static app_err_t eip712_hash_struct(SHA3_CTX* sha3, uint8_t* heap, size_t heap_s return ERR_DATA; } - uint8_t field[32]; + APP_ALIGNED(uint8_t field[32], 4); if (eip712_encode_field(field, heap, heap_size, &t->fields[i].type, field_val, types, types_count, tokens, token_count, json) != ERR_OK) { return ERR_DATA; }