Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions context.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ typedef enum coin_kind_e {
COIN_KIND_RESISTANCE,
COIN_KIND_RAVENCOIN,
COIN_KIND_HYDRA,
COIN_KIND_ECASH,
COIN_KIND_UNUSED
} coin_kind_t;

Expand Down
48 changes: 37 additions & 11 deletions display_utils.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "context.h"
#include "filesystem_tx.h"
#include "ledger_assert.h"
#include "read.h"
Expand Down Expand Up @@ -42,6 +43,13 @@ static uint64_t div100000000(uint64_t n) {
return res;
}

static uint64_t div100(uint64_t n) {
uint64_t res = n;
res = div10(res);
res = div10(res);
return res;
}

static size_t n_digits(uint64_t number) {
size_t count = 0;
do {
Expand All @@ -63,11 +71,21 @@ void format_sats_amount(const char *coin_name, uint64_t amount,

char *amount_str = out + coin_name_len + 1;

uint64_t integral_part;
uint32_t fractional_part;

// HACK: avoid __udivmoddi4
// uint64_t integral_part = amount / 100000000;
// uint32_t fractional_part = (uint32_t) (amount % 100000000);
uint64_t integral_part = div100000000(amount);
uint32_t fractional_part = (uint32_t)(amount - integral_part * 100000000);
if (COIN_KIND == COIN_KIND_ECASH) {
// integral_part = amount / 100;
// fractional_part = (uint32_t) (amount % 100);
integral_part = div100(amount);
fractional_part = (uint32_t)(amount - integral_part * 100);
} else {
// integral_part = amount / 100000000;
// fractional_part = (uint32_t) (amount % 100000000);
integral_part = div100000000(amount);
fractional_part = (uint32_t)(amount - integral_part * 100000000);
}

// format the integral part, starting from the least significant digit
size_t integral_part_digit_count = n_digits(integral_part);
Expand All @@ -85,15 +103,23 @@ void format_sats_amount(const char *coin_name, uint64_t amount,
if (fractional_part == 0) {
amount_str[integral_part_digit_count] = '\0';
} else {
// format the fractional part (exactly 8 digits, possibly with trailing
// zeros)
amount_str[integral_part_digit_count] = '.';
char *fract_part_str = amount_str + integral_part_digit_count + 1;
snprintf(fract_part_str, 8 + 1, "%08u", fractional_part);

// drop trailing zeros
for (int i = 7; i > 0 && fract_part_str[i] == '0'; i--) {
fract_part_str[i] = '\0';
if (COIN_KIND == COIN_KIND_ECASH) {
// format the fractional part (exactly 2 digits, possibly with trailing
// zeros). For eCash we don't need to drop the trailing zeros, there is a
// single one at most.
snprintf(fract_part_str, 2 + 1, "%02u", fractional_part);

} else {
// format the fractional part (exactly 8 digits, possibly with trailing
// zeros)
snprintf(fract_part_str, 8 + 1, "%08u", fractional_part);

// drop trailing zeros
for (int i = 7; i > 0 && fract_part_str[i] == '0'; i--) {
fract_part_str[i] = '\0';
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion handler/get_wallet_public_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ WEAK unsigned short handler_get_wallet_public_key(buffer_t *buffer, uint8_t p1,
return io_send_sw(SW_INCORRECT_P1_P2);
}

if (p2 == P2_CASHADDR && COIN_KIND != COIN_KIND_BITCOIN_CASH) {
if (p2 == P2_CASHADDR && COIN_KIND != COIN_KIND_BITCOIN_CASH && COIN_KIND != COIN_KIND_ECASH) {
PRINTF("Wrong P2 value\n");
return io_send_sw(SW_INCORRECT_P1_P2);
}
Expand Down
2 changes: 1 addition & 1 deletion handler/hash_input_start.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ WEAK unsigned short handler_hash_input_start(buffer_t *buffer, uint8_t p1,
context.transactionContext.relaxed = 0;
context.usingSegwit = usingSegwit;

if (COIN_KIND == COIN_KIND_BITCOIN_CASH) {
if ((COIN_KIND == COIN_KIND_BITCOIN_CASH) || (COIN_KIND == COIN_KIND_ECASH)) {
unsigned char usingCashAddr = (p2 == P2_NEW_SEGWIT_CASHADDR);
context.usingCashAddr = usingCashAddr;
} else {
Expand Down
4 changes: 2 additions & 2 deletions handler/hash_sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ WEAK unsigned short handler_hash_sign(buffer_t *buffer, uint8_t p1,
sighashType = *(parameters++);
context.transactionSummary.sighashType = sighashType;

// if bitcoin cash OR forkid is set, then use the fork id
if ((COIN_KIND == COIN_KIND_BITCOIN_CASH) || (COIN_FORKID != 0)) {
// if bitcoin cash OR eCash or forkid is set, then use the fork id
if ((COIN_KIND == COIN_KIND_BITCOIN_CASH) || (COIN_KIND == COIN_KIND_ECASH) || (COIN_FORKID != 0)) {
#define SIGHASH_FORKID 0x40
if (sighashType != (SIGHASH_ALL | SIGHASH_FORKID)) {
context.transactionContext.transactionState = TRANSACTION_NONE;
Expand Down
10 changes: 8 additions & 2 deletions utils/cashaddr.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <string.h>

#include "cashaddr.h"
#include "context.h"

static const char *charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";

Expand Down Expand Up @@ -81,7 +82,12 @@ static int convert_bits(uint8_t *out, size_t *outlen, int outbits,

void create_checksum(uint8_t *payload, size_t payload_length,
uint8_t *checksum) {
uint8_t *prefix = (uint8_t *)"bitcoincash";
uint8_t *prefix;
if (COIN_KIND == COIN_KIND_ECASH) {
prefix = (uint8_t *)"ecash";
} else {
prefix = (uint8_t *)"bitcoincash";
}
uint64_t mod = PolyMod(prefix, payload, payload_length);

for (size_t i = 0; i < 8; ++i) {
Expand Down Expand Up @@ -120,7 +126,7 @@ int cashaddr_encode(uint8_t *hash, const size_t hash_length, uint8_t *addr,
convert_bits(payload, &payload_length, 5, tmp, hash_length + 1, 8, 1);

create_checksum(payload, payload_length,
checksum); // Assume prefix is 'bitcoincash'
checksum);

for (i = 0; i < payload_length; ++i) {
if (*payload >> 5) {
Expand Down
2 changes: 1 addition & 1 deletion utils/cashaddr.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#define CASHADDR_P2PKH 0
#define CASHADDR_P2SH 1

/** Encode a Bitcoin Cash address
/** Encode a Bitcoin Cash or eCash address
*
* In: hash: Pointer to the hash
* hash_length: Length of hash (bytes). Only 20 bytes (160 bits)
Expand Down