Skip to content

Commit

Permalink
simplifying hex conversion, adding DOGE support!
Browse files Browse the repository at this point in the history
  • Loading branch information
xtruan committed Mar 9, 2023
1 parent 3714144 commit 5b8263b
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 75 deletions.
2 changes: 1 addition & 1 deletion flipbip.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ FlipBip* flipbip_app_alloc() {
app->haptic = 1;
app->led = 1;
app->bip39_strength = 2; // 256 bits (24 words)
app->bip44_coin = 0; // 0 (BTC)
app->bip44_coin = COIN_BTC; // 0 (BTC)
app->overwrite_saved_seed = 0;

view_dispatcher_add_view(
Expand Down
6 changes: 5 additions & 1 deletion flipbip.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
#include "views/flipbip_startscreen.h"
#include "views/flipbip_scene_1.h"

#define FLIPBIP_VERSION "v0.0.4"
#define FLIPBIP_VERSION "v0.0.5"

#define COIN_BTC 0
#define COIN_DOGE 3
#define COIN_ETH 60

typedef struct {
Gui* gui;
Expand Down
8 changes: 2 additions & 6 deletions helpers/flipbip_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,7 @@ bool flipbip_save_settings_secure(const char* settings) {
random_buffer(k2, FILE_KLEN / 2);

// write k2 to file buffer (secured by k1)
for(size_t i = 0; i < (FILE_KLEN / 2); i++) {
flipbip_btox(k2[i], data + (i * 2));
}
flipbip_btox(k2, FILE_KLEN / 2, data);
flipbip_cipher(k1, strlen(FILE_K1) / 2, data, data, FILE_KLEN);

// seek <-- header
Expand All @@ -247,9 +245,7 @@ bool flipbip_save_settings_secure(const char* settings) {
memzero(data, FILE_KLEN);

// write settings to file buffer (secured by k2)
for(size_t i = 0; i < len; i++) {
flipbip_btox((uint8_t)settings[i], data + (i * 2));
}
flipbip_btox((uint8_t*)settings, len, data);
flipbip_cipher(k2, FILE_KLEN / 2, data, data, FILE_SLEN);

// seek <-- header
Expand Down
22 changes: 11 additions & 11 deletions helpers/flipbip_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,18 @@ char* flipbip_strtok_r(char* s, const char* delim, char** last) {
/* NOTREACHED */
}

void flipbip_btox(const unsigned char in, char* str) {
unsigned char n;
unsigned char i = in;
void flipbip_btox(const unsigned char* in, int in_len, char* str) {
for(int i = 0; i < in_len; i++) {
unsigned char n;
unsigned char x = in[i];

str += 2;
*str = '\0';
str += 2;
*(str + (i * 2)) = '\0';

for(n = 2; n != 0; --n) {
*--str = "0123456789abcdef"[i & 0x0F];
i >>= 4;
for(n = 2; n != 0; --n) {
*(--str + (i * 2)) = "0123456789abcdef"[x & 0x0F];
x >>= 4;
}
}
}
void flipbip_xtob(const char* str, unsigned char* out, int out_len) {
Expand Down Expand Up @@ -121,9 +123,7 @@ void flipbip_cipher(
rc4_init(&ctx, key_in, key_len);
rc4_encrypt(&ctx, buf, 256);

for(size_t i = 0; i < (io_len / 2); i++) {
flipbip_btox(buf[i], out + i * 2);
}
flipbip_btox(buf, io_len / 2, out);

memzero(buf, 256);
}
2 changes: 1 addition & 1 deletion helpers/flipbip_string.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
char* flipbip_strtok(char* s, const char* delim);
char* flipbip_strtok_r(char* s, const char* delim, char** last);

void flipbip_btox(const unsigned char i, char* str);
void flipbip_btox(const unsigned char* in, int in_len, char* str);
void flipbip_xtob(const char* str, unsigned char* out, int out_len);

void flipbip_cipher(
Expand Down
18 changes: 16 additions & 2 deletions scenes/flipbip_scene_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
enum SubmenuIndex {
SubmenuIndexScene1BTC = 10,
SubmenuIndexScene1ETH,
SubmenuIndexScene1DOGE,
SubmenuIndexScene1New,
SubmenuIndexSettings,
};
Expand All @@ -29,6 +30,12 @@ void flipbip_scene_menu_on_enter(void* context) {
SubmenuIndexScene1ETH,
flipbip_scene_menu_submenu_callback,
app);
submenu_add_item(
app->submenu,
"View saved DOGE wallet",
SubmenuIndexScene1DOGE,
flipbip_scene_menu_submenu_callback,
app);
}
submenu_add_item(
app->submenu,
Expand Down Expand Up @@ -57,18 +64,25 @@ bool flipbip_scene_menu_on_event(void* context, SceneManagerEvent event) {
} else if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubmenuIndexScene1BTC) {
app->overwrite_saved_seed = 0;
app->bip44_coin = FlipBipCoinBTC0;
app->bip44_coin = COIN_BTC;
scene_manager_set_scene_state(
app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1BTC);
scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1);
return true;
} else if(event.event == SubmenuIndexScene1ETH) {
app->overwrite_saved_seed = 0;
app->bip44_coin = FlipBipCoinETH60;
app->bip44_coin = COIN_ETH;
scene_manager_set_scene_state(
app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1ETH);
scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1);
return true;
} else if(event.event == SubmenuIndexScene1DOGE) {
app->overwrite_saved_seed = 0;
app->bip44_coin = COIN_DOGE;
scene_manager_set_scene_state(
app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1DOGE);
scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1);
return true;
} else if(event.event == SubmenuIndexScene1New) {
app->overwrite_saved_seed = 1;
scene_manager_set_scene_state(
Expand Down
16 changes: 8 additions & 8 deletions scenes/flipbip_scene_settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ const uint32_t bip39_strength_value[3] = {
FlipBipStrength256,
};

const char* const bip44_coin_text[2] = {
"BTC",
"ETH",
};
const uint32_t bip44_coin_value[2] = {
FlipBipCoinBTC0,
FlipBipCoinETH60,
};
// const char* const bip44_coin_text[2] = {
// "BTC",
// "ETH",
// };
// const uint32_t bip44_coin_value[2] = {
// FlipBipCoinBTC0,
// FlipBipCoinETH60,
// };

static void flipbip_scene_settings_set_haptic(VariableItem* item) {
FlipBip* app = variable_item_get_context(item);
Expand Down
115 changes: 70 additions & 45 deletions views/flipbip_scene_1.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@
#include "../crypto/curves.h"
#include "../crypto/memzero.h"

#define DERIV_PURPOSE 44
#define DERIV_ACCOUNT 0
#define DERIV_CHANGE 0

#define VERSION_PRIVATE 0x0488ade4
#define VERSION_PUBLIC 0x0488b21e
#define ADDR_VERSION 0x00
#define WIF_VERSION 0x80

#define DOGE_VERSION_PRIVATE 0x02fac398
#define DOGE_VERSION_PUBLIC 0x02facafd
#define DOGE_ADDR_VERSION 0x1e
#define DOGE_WIF_VERSION 0x9e

struct FlipBipScene1 {
View* view;
FlipBipScene1Callback callback;
Expand Down Expand Up @@ -46,6 +60,7 @@ static CONFIDENTIAL char s_disp_text3[30 + 1];
static CONFIDENTIAL char s_disp_text4[30 + 1];
static CONFIDENTIAL char s_disp_text5[30 + 1];
static CONFIDENTIAL char s_disp_text6[30 + 1];
static char* s_derivation_text = "m/44'/x'/0'/0";
static bool s_busy = false;

void flipbip_scene_1_set_callback(
Expand Down Expand Up @@ -137,9 +152,7 @@ static void flipbip_scene_1_draw_mnemonic(const char* mnemonic) {
static void flipbip_scene_1_draw_seed(FlipBipScene1Model* const model) {
char* seed_working = malloc(64 * 2 + 1);
// Convert the seed to a hex string
for(size_t i = 0; i < 64; i++) {
flipbip_btox(model->seed[i], seed_working + (i * 2));
}
flipbip_btox(model->seed, 64, seed_working);

flipbip_scene_1_draw_generic(seed_working, 22);

Expand All @@ -162,31 +175,33 @@ static void
hdnode_private_ckd(addr_node, addr_index);
hdnode_fill_public_key(addr_node);

if(addr_type == 0) { // BTC
// BTC style address
const char addr_version = 0x00;
//const char wif_version = 0x80;
ecdsa_get_address(
addr_node->public_key, addr_version, HASHER_SHA2_RIPEMD, HASHER_SHA2D, buf, buflen);
if(addr_type == COIN_BTC || addr_type == COIN_DOGE) { // BTC / DOGE
if (addr_type == COIN_BTC) {
// BTC style address
ecdsa_get_address(
addr_node->public_key, ADDR_VERSION, HASHER_SHA2_RIPEMD, HASHER_SHA2D, buf, buflen);
} else if (addr_type == COIN_DOGE) {
// DOGE style address
ecdsa_get_address(
addr_node->public_key, DOGE_ADDR_VERSION, HASHER_SHA2_RIPEMD, HASHER_SHA2D, buf, buflen);
}

char* address = malloc(buflen + 1);
strncpy(address, buf, buflen);
flipbip_scene_1_draw_generic(address, 12);
memzero(address, buflen + 1);
free(address);

//ecdsa_get_wif(addr_node->private_key, wif_version, HASHER_SHA2D, buf, buflen);
//ecdsa_get_wif(addr_node->private_key, WIF_VERSION, HASHER_SHA2D, buf, buflen);
//char *wif = malloc(buflen + 1);
//strncpy(wif, buf, buflen);
} else if(addr_type == 60) { // ETH
} else if(addr_type == COIN_ETH) { // ETH
// ETH style address
hdnode_get_ethereum_pubkeyhash(addr_node, (uint8_t*)buf);
char* address = malloc(42 + 1);
memcpy(address, "0x", 2);
// Convert the hash to a hex string
for(size_t i = 0; i < 20; i++) {
flipbip_btox(buf[i], address + 2 + (i * 2));
}
flipbip_btox((uint8_t*)buf, 20, address + 2);
flipbip_scene_1_draw_generic(address, 12);
memzero(address, 42 + 1);
free(address);
Expand Down Expand Up @@ -242,14 +257,16 @@ void flipbip_scene_1_draw(Canvas* canvas, FlipBipScene1Model* model) {
if(model->page == 0) {
canvas_set_font(canvas, FontPrimary);
canvas_draw_str(canvas, 1, 10, "Loading...");
canvas_draw_str(canvas, 6, 30, "m/44'/x'/0'/0");
canvas_draw_str(canvas, 6, 30, s_derivation_text);
canvas_draw_icon(canvas, 86, 25, &I_Keychain_39x36);
} else if(model->page >= 9 && model->page <= 13) {
canvas_set_font(canvas, FontSecondary);
const char* receive_text;
if(model->coin == 0) { // BTC
if(model->coin == COIN_BTC) { // BTC
receive_text = "BTC receive address:";
} else if(model->coin == 60) { // ETH
} else if(model->coin == COIN_DOGE) { // DOGE
receive_text = "DOGE receive address:";
} else if(model->coin == COIN_ETH) { // ETH
receive_text = "ETH receive address:";
} else {
receive_text = "Receive address:";
Expand Down Expand Up @@ -318,30 +335,17 @@ static int flipbip_scene_1_model_init(
HDNode* root = malloc(sizeof(HDNode));
hdnode_from_seed(model->seed, 64, SECP256K1_NAME, root);

// m/44'/0'/0'/0 or m/44'/60'/0'/0
const uint32_t purpose = 44;
//const uint32_t coin = 0; // BTC
//const uint32_t coin = 60; // ETH
const uint32_t account = 0;
const uint32_t change = 0;

// constants for BTC / ETH
const uint32_t version_public = 0x0488b21e;
const uint32_t version_private = 0x0488ade4;
// "xprv_magic": 76066276,
// "xpub_magic": 76067358,
// "xpub_magic_segwit_p2sh": 77429938,
// "xpub_magic_segwit_native": 78792518,
// "xpub_magic_multisig_segwit_p2sh": 43365439,
// "xpub_magic_multisig_segwit_native": 44728019,

// buffer for key serialization
const size_t buflen = 128;
char buf[128 + 1];

// root
uint32_t fingerprint = 0;
hdnode_serialize_private(root, fingerprint, version_private, buf, buflen);
if (model->coin == COIN_DOGE) {
hdnode_serialize_private(root, fingerprint, DOGE_VERSION_PRIVATE, buf, buflen);
} else {
hdnode_serialize_private(root, fingerprint, VERSION_PRIVATE, buf, buflen);
}
char* xprv_root = malloc(buflen + 1);
strncpy(xprv_root, buf, buflen);
model->xprv_root = xprv_root;
Expand All @@ -350,36 +354,52 @@ static int flipbip_scene_1_model_init(

// purpose m/44'
fingerprint = hdnode_fingerprint(node);
hdnode_private_ckd_prime(node, purpose); // purpose
hdnode_private_ckd_prime(node, DERIV_PURPOSE); // purpose

// coin m/44'/0' or m/44'/60'
fingerprint = hdnode_fingerprint(node);
hdnode_private_ckd_prime(node, model->coin); // coin

// account m/44'/0'/0' or m/44'/60'/0'
fingerprint = hdnode_fingerprint(node);
hdnode_private_ckd_prime(node, account); // account
hdnode_private_ckd_prime(node, DERIV_ACCOUNT); // account

hdnode_serialize_private(node, fingerprint, version_private, buf, buflen);
if (model->coin == COIN_DOGE) {
hdnode_serialize_private(node, fingerprint, DOGE_VERSION_PRIVATE, buf, buflen);
} else {
hdnode_serialize_private(node, fingerprint, VERSION_PRIVATE, buf, buflen);
}
char* xprv_acc = malloc(buflen + 1);
strncpy(xprv_acc, buf, buflen);
model->xprv_account = xprv_acc;

hdnode_serialize_public(node, fingerprint, version_public, buf, buflen);
if (model->coin == COIN_DOGE) {
hdnode_serialize_public(node, fingerprint, DOGE_VERSION_PUBLIC, buf, buflen);
} else {
hdnode_serialize_public(node, fingerprint, VERSION_PUBLIC, buf, buflen);
}
char* xpub_acc = malloc(buflen + 1);
strncpy(xpub_acc, buf, buflen);
model->xpub_account = xpub_acc;

// external/internal (change) m/44'/0'/0'/0 or m/44'/60'/0'/0
fingerprint = hdnode_fingerprint(node);
hdnode_private_ckd(node, change); // external/internal (change)
hdnode_private_ckd(node, DERIV_CHANGE); // external/internal (change)

hdnode_serialize_private(node, fingerprint, version_private, buf, buflen);
if (model->coin == COIN_DOGE) {
hdnode_serialize_private(node, fingerprint, DOGE_VERSION_PRIVATE, buf, buflen);
} else {
hdnode_serialize_private(node, fingerprint, VERSION_PRIVATE, buf, buflen);
}
char* xprv_ext = malloc(buflen + 1);
strncpy(xprv_ext, buf, buflen);
model->xprv_extended = xprv_ext;

hdnode_serialize_public(node, fingerprint, version_public, buf, buflen);
if (model->coin == COIN_DOGE) {
hdnode_serialize_public(node, fingerprint, DOGE_VERSION_PUBLIC, buf, buflen);
} else {
hdnode_serialize_public(node, fingerprint, VERSION_PUBLIC, buf, buflen);
}
char* xpub_ext = malloc(buflen + 1);
strncpy(xpub_ext, buf, buflen);
model->xpub_extended = xpub_ext;
Expand Down Expand Up @@ -504,9 +524,14 @@ void flipbip_scene_1_enter(void* context) {
strength = 192; // 18 words (192 bit)

// BIP44 Coin setting
int coin_setting = app->bip44_coin;
uint32_t coin = 0; //FlipBipCoinBTC0 // BTC (0)
if(coin_setting == FlipBipCoinETH60) coin = 60; // ETH (60)
uint32_t coin = app->bip44_coin;
if (coin == COIN_BTC) {
s_derivation_text = "m/44'/0'/0'/0";
} else if (coin == COIN_DOGE) {
s_derivation_text = "m/44'/3'/0'/0";
} else if (coin == COIN_ETH) {
s_derivation_text = "m/44'/60'/0'/0";
}

// Overwrite the saved seed with a new one setting
bool overwrite = app->overwrite_saved_seed != 0;
Expand Down

0 comments on commit 5b8263b

Please sign in to comment.