Skip to content

Commit

Permalink
Add function to convert u128 numbers to string
Browse files Browse the repository at this point in the history
  • Loading branch information
neithanmo committed Nov 26, 2024
1 parent f3d6e31 commit 583d23a
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 3 deletions.
30 changes: 30 additions & 0 deletions app/src/constants.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
/*******************************************************************************
* (c) 2018 - 2023 Zondax AG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
#define U128_STR_MAX_LEN 40

// raw address len before encoding
#define ADDRESS_LEN_BYTES 80

// Common BECH32m constants
#define CHECKSUM_LENGTH 8
#define BECH32_BITS_PER_CHAR 5
Expand All @@ -22,3 +42,13 @@
#define ENCODED_ADDR_LEN (ADDR_HRP_LENGTH + SEPARATOR_LENGTH + ENCODED_DATA_LENGTH)

#define ENCODED_ADDR_BUFFER_SIZE (ENCODED_ADDR_LEN + 2)


// MEMO transaction constants
#define MEMO_CIPHERTEXT_LEN_BYTES 528

// This is the `MEMO_CIPHERTEXT_LEN_BYTES` - MAC size (16 bytes).
#define MEMO_LEN_BYTES 512

// This is the largest text length we can support
#define MAX_TEXT_LEN MEMO_LEN_BYTES - ADDRESS_LEN_BYTES
3 changes: 0 additions & 3 deletions app/src/keys_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ extern "C" {
#define INCOMING_VIEWING_KEY_LEN KEY_LEN // Assuming modulo r size
#define ADDR_MAX_ENC_LEN 150 // The maximun length of the encoded address

// raw address len before encoding
#define ADDRESS_LEN_BYTES 80

/// Number of bits in the address short form divided by the number of bits per Bech32m character
#define ADDRESS_NUM_CHARS_SHORT_FORM 24

Expand Down
53 changes: 53 additions & 0 deletions app/src/ui_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,56 @@ parser_error_t printAssetId(uint8_t *asset, uint16_t asset_len, char *out, uint1
asset, asset_len, ASSET_ID_LEN,
out, out_len);
}

parser_error_t uint128_to_str(char *data, int dataLen, uint64_t high, uint64_t low) {
if (data == NULL) return parser_no_data;
if (dataLen < U128_STR_MAX_LEN) return parser_value_out_of_range;

MEMZERO(data, dataLen);
char *p = data;

if (high == 0 && low == 0) {
*(p++) = '0';
return parser_ok;
}

uint64_t temp_high = high;
uint64_t temp_low = low;

while (temp_high != 0 || temp_low != 0) {
if (p - data >= (dataLen - 1)) return parser_value_out_of_range;

uint64_t quotient_high = 0;
uint64_t quotient_low = 0;
uint64_t remainder = 0;
uint64_t current;

current = temp_high;
quotient_high = current / 10;
remainder = current % 10;

current = (remainder << 32) | (temp_low >> 32);
uint64_t q = current / 10;
remainder = current % 10;
quotient_low = (q << 32);

current = (remainder << 32) | (temp_low & 0xFFFFFFFF);
q = current / 10;
remainder = current % 10;
quotient_low |= q;

*(p++) = (char)('0' + remainder);
temp_high = quotient_high;
temp_low = quotient_low;
}

while (p > data) {
p--;
char z = *data;
*data = *p;
*p = z;
data++;
}

return parser_ok;
}
16 changes: 16 additions & 0 deletions app/src/ui_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,19 @@ parser_error_t printBech32Encoded(const char *prefix, uint16_t prefix_len, uint8

parser_error_t printAddress(uint8_t *address, uint16_t address_len, char *out, uint16_t out_len);
parser_error_t printAssetId(uint8_t *asset, uint16_t asset_len, char *out, uint16_t out_len);

/**
* Converts a 128-bit unsigned integer to its decimal string representation.
* Output buffer will be null terminated and cleared using MEMZERO.
*
* @param[out] data Output buffer for the resulting string
* @param[in] dataLen Size of the output buffer
* @param[in] high Upper 64 bits of the 128-bit number
* @param[in] low Lower 64 bits of the 128-bit number
*
* @return parser_error_t:
* - parser_ok on success
* - parser_no_data if data is NULL
* - parser_value_out_of_range if buffer too small (< U128_STR_MAX_LEN)
*/
parser_error_t uint128_to_str(char *data, int dataLen, uint64_t high, uint64_t low);

0 comments on commit 583d23a

Please sign in to comment.