support 256 bit decimal strings

This commit is contained in:
Michele Balistreri 2023-08-14 15:57:21 +02:00
parent 5d1e989581
commit 9295748011
No known key found for this signature in database
GPG Key ID: E9567DA33A4F791A
3 changed files with 45 additions and 18 deletions

View File

@ -76,32 +76,66 @@ bool base16_decode(const char* s, uint8_t* out, size_t s_len) {
return true; 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 i;
int sign; bool neg;
if (str[0] == '-') { if (str[0] == '-') {
sign = -1; neg = true;
i = 1; i = 1;
} else if (str[0] == '+') { } else if (str[0] == '+') {
sign = 1; neg = false;
i = 1; i = 1;
} else { } else {
sign = 1; neg = false;
i = 0; i = 0;
} }
*res = 0; uint32_t limbs[9];
memset(limbs, 0, sizeof(uint32_t) * 9);
while(i < len) { while(i < len) {
if (!(str[i] >= '0' && str[i] <= '9')) { if (!(str[i] >= '0' && str[i] <= '9')) {
return false; 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; return true;
} }

View File

@ -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); size_t strnlen(const char *s, size_t maxlen);
bool base16_decode(const char* s, uint8_t* out, size_t s_len); 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) { static inline int memcmp_ct(const uint8_t* a, const uint8_t* b, size_t length) {
int compareSum = 0; int compareSum = 0;

View File

@ -416,16 +416,9 @@ static app_err_t eip712_encode_field(uint8_t out[32], uint8_t* heap, size_t heap
return ERR_DATA; return ERR_DATA;
} }
} else { } else {
int64_t res; if (!atoi256BE(&json[tokens[field_val].start], (tokens[field_val].end - tokens[field_val].start), out)) {
if (!atoi64(&json[tokens[field_val].start], (tokens[field_val].end - tokens[field_val].start), &res)) {
return ERR_DATA; 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; 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) { 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; return ERR_DATA;
} }