Skip to content

Commit 5b8263b

Browse files
committed
simplifying hex conversion, adding DOGE support!
1 parent 3714144 commit 5b8263b

8 files changed

+114
-75
lines changed

flipbip.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ FlipBip* flipbip_app_alloc() {
4444
app->haptic = 1;
4545
app->led = 1;
4646
app->bip39_strength = 2; // 256 bits (24 words)
47-
app->bip44_coin = 0; // 0 (BTC)
47+
app->bip44_coin = COIN_BTC; // 0 (BTC)
4848
app->overwrite_saved_seed = 0;
4949

5050
view_dispatcher_add_view(

flipbip.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@
1414
#include "views/flipbip_startscreen.h"
1515
#include "views/flipbip_scene_1.h"
1616

17-
#define FLIPBIP_VERSION "v0.0.4"
17+
#define FLIPBIP_VERSION "v0.0.5"
18+
19+
#define COIN_BTC 0
20+
#define COIN_DOGE 3
21+
#define COIN_ETH 60
1822

1923
typedef struct {
2024
Gui* gui;

helpers/flipbip_file.c

+2-6
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,7 @@ bool flipbip_save_settings_secure(const char* settings) {
232232
random_buffer(k2, FILE_KLEN / 2);
233233

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

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

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

255251
// seek <-- header

helpers/flipbip_string.c

+11-11
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,18 @@ char* flipbip_strtok_r(char* s, const char* delim, char** last) {
7777
/* NOTREACHED */
7878
}
7979

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

84-
str += 2;
85-
*str = '\0';
85+
str += 2;
86+
*(str + (i * 2)) = '\0';
8687

87-
for(n = 2; n != 0; --n) {
88-
*--str = "0123456789abcdef"[i & 0x0F];
89-
i >>= 4;
88+
for(n = 2; n != 0; --n) {
89+
*(--str + (i * 2)) = "0123456789abcdef"[x & 0x0F];
90+
x >>= 4;
91+
}
9092
}
9193
}
9294
void flipbip_xtob(const char* str, unsigned char* out, int out_len) {
@@ -121,9 +123,7 @@ void flipbip_cipher(
121123
rc4_init(&ctx, key_in, key_len);
122124
rc4_encrypt(&ctx, buf, 256);
123125

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

128128
memzero(buf, 256);
129129
}

helpers/flipbip_string.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
char* flipbip_strtok(char* s, const char* delim);
22
char* flipbip_strtok_r(char* s, const char* delim, char** last);
33

4-
void flipbip_btox(const unsigned char i, char* str);
4+
void flipbip_btox(const unsigned char* in, int in_len, char* str);
55
void flipbip_xtob(const char* str, unsigned char* out, int out_len);
66

77
void flipbip_cipher(

scenes/flipbip_scene_menu.c

+16-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
enum SubmenuIndex {
55
SubmenuIndexScene1BTC = 10,
66
SubmenuIndexScene1ETH,
7+
SubmenuIndexScene1DOGE,
78
SubmenuIndexScene1New,
89
SubmenuIndexSettings,
910
};
@@ -29,6 +30,12 @@ void flipbip_scene_menu_on_enter(void* context) {
2930
SubmenuIndexScene1ETH,
3031
flipbip_scene_menu_submenu_callback,
3132
app);
33+
submenu_add_item(
34+
app->submenu,
35+
"View saved DOGE wallet",
36+
SubmenuIndexScene1DOGE,
37+
flipbip_scene_menu_submenu_callback,
38+
app);
3239
}
3340
submenu_add_item(
3441
app->submenu,
@@ -57,18 +64,25 @@ bool flipbip_scene_menu_on_event(void* context, SceneManagerEvent event) {
5764
} else if(event.type == SceneManagerEventTypeCustom) {
5865
if(event.event == SubmenuIndexScene1BTC) {
5966
app->overwrite_saved_seed = 0;
60-
app->bip44_coin = FlipBipCoinBTC0;
67+
app->bip44_coin = COIN_BTC;
6168
scene_manager_set_scene_state(
6269
app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1BTC);
6370
scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1);
6471
return true;
6572
} else if(event.event == SubmenuIndexScene1ETH) {
6673
app->overwrite_saved_seed = 0;
67-
app->bip44_coin = FlipBipCoinETH60;
74+
app->bip44_coin = COIN_ETH;
6875
scene_manager_set_scene_state(
6976
app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1ETH);
7077
scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1);
7178
return true;
79+
} else if(event.event == SubmenuIndexScene1DOGE) {
80+
app->overwrite_saved_seed = 0;
81+
app->bip44_coin = COIN_DOGE;
82+
scene_manager_set_scene_state(
83+
app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1DOGE);
84+
scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1);
85+
return true;
7286
} else if(event.event == SubmenuIndexScene1New) {
7387
app->overwrite_saved_seed = 1;
7488
scene_manager_set_scene_state(

scenes/flipbip_scene_settings.c

+8-8
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@ const uint32_t bip39_strength_value[3] = {
3737
FlipBipStrength256,
3838
};
3939

40-
const char* const bip44_coin_text[2] = {
41-
"BTC",
42-
"ETH",
43-
};
44-
const uint32_t bip44_coin_value[2] = {
45-
FlipBipCoinBTC0,
46-
FlipBipCoinETH60,
47-
};
40+
// const char* const bip44_coin_text[2] = {
41+
// "BTC",
42+
// "ETH",
43+
// };
44+
// const uint32_t bip44_coin_value[2] = {
45+
// FlipBipCoinBTC0,
46+
// FlipBipCoinETH60,
47+
// };
4848

4949
static void flipbip_scene_settings_set_haptic(VariableItem* item) {
5050
FlipBip* app = variable_item_get_context(item);

views/flipbip_scene_1.c

+70-45
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,20 @@
1818
#include "../crypto/curves.h"
1919
#include "../crypto/memzero.h"
2020

21+
#define DERIV_PURPOSE 44
22+
#define DERIV_ACCOUNT 0
23+
#define DERIV_CHANGE 0
24+
25+
#define VERSION_PRIVATE 0x0488ade4
26+
#define VERSION_PUBLIC 0x0488b21e
27+
#define ADDR_VERSION 0x00
28+
#define WIF_VERSION 0x80
29+
30+
#define DOGE_VERSION_PRIVATE 0x02fac398
31+
#define DOGE_VERSION_PUBLIC 0x02facafd
32+
#define DOGE_ADDR_VERSION 0x1e
33+
#define DOGE_WIF_VERSION 0x9e
34+
2135
struct FlipBipScene1 {
2236
View* view;
2337
FlipBipScene1Callback callback;
@@ -46,6 +60,7 @@ static CONFIDENTIAL char s_disp_text3[30 + 1];
4660
static CONFIDENTIAL char s_disp_text4[30 + 1];
4761
static CONFIDENTIAL char s_disp_text5[30 + 1];
4862
static CONFIDENTIAL char s_disp_text6[30 + 1];
63+
static char* s_derivation_text = "m/44'/x'/0'/0";
4964
static bool s_busy = false;
5065

5166
void flipbip_scene_1_set_callback(
@@ -137,9 +152,7 @@ static void flipbip_scene_1_draw_mnemonic(const char* mnemonic) {
137152
static void flipbip_scene_1_draw_seed(FlipBipScene1Model* const model) {
138153
char* seed_working = malloc(64 * 2 + 1);
139154
// Convert the seed to a hex string
140-
for(size_t i = 0; i < 64; i++) {
141-
flipbip_btox(model->seed[i], seed_working + (i * 2));
142-
}
155+
flipbip_btox(model->seed, 64, seed_working);
143156

144157
flipbip_scene_1_draw_generic(seed_working, 22);
145158

@@ -162,31 +175,33 @@ static void
162175
hdnode_private_ckd(addr_node, addr_index);
163176
hdnode_fill_public_key(addr_node);
164177

165-
if(addr_type == 0) { // BTC
166-
// BTC style address
167-
const char addr_version = 0x00;
168-
//const char wif_version = 0x80;
169-
ecdsa_get_address(
170-
addr_node->public_key, addr_version, HASHER_SHA2_RIPEMD, HASHER_SHA2D, buf, buflen);
178+
if(addr_type == COIN_BTC || addr_type == COIN_DOGE) { // BTC / DOGE
179+
if (addr_type == COIN_BTC) {
180+
// BTC style address
181+
ecdsa_get_address(
182+
addr_node->public_key, ADDR_VERSION, HASHER_SHA2_RIPEMD, HASHER_SHA2D, buf, buflen);
183+
} else if (addr_type == COIN_DOGE) {
184+
// DOGE style address
185+
ecdsa_get_address(
186+
addr_node->public_key, DOGE_ADDR_VERSION, HASHER_SHA2_RIPEMD, HASHER_SHA2D, buf, buflen);
187+
}
171188

172189
char* address = malloc(buflen + 1);
173190
strncpy(address, buf, buflen);
174191
flipbip_scene_1_draw_generic(address, 12);
175192
memzero(address, buflen + 1);
176193
free(address);
177194

178-
//ecdsa_get_wif(addr_node->private_key, wif_version, HASHER_SHA2D, buf, buflen);
195+
//ecdsa_get_wif(addr_node->private_key, WIF_VERSION, HASHER_SHA2D, buf, buflen);
179196
//char *wif = malloc(buflen + 1);
180197
//strncpy(wif, buf, buflen);
181-
} else if(addr_type == 60) { // ETH
198+
} else if(addr_type == COIN_ETH) { // ETH
182199
// ETH style address
183200
hdnode_get_ethereum_pubkeyhash(addr_node, (uint8_t*)buf);
184201
char* address = malloc(42 + 1);
185202
memcpy(address, "0x", 2);
186203
// Convert the hash to a hex string
187-
for(size_t i = 0; i < 20; i++) {
188-
flipbip_btox(buf[i], address + 2 + (i * 2));
189-
}
204+
flipbip_btox((uint8_t*)buf, 20, address + 2);
190205
flipbip_scene_1_draw_generic(address, 12);
191206
memzero(address, 42 + 1);
192207
free(address);
@@ -242,14 +257,16 @@ void flipbip_scene_1_draw(Canvas* canvas, FlipBipScene1Model* model) {
242257
if(model->page == 0) {
243258
canvas_set_font(canvas, FontPrimary);
244259
canvas_draw_str(canvas, 1, 10, "Loading...");
245-
canvas_draw_str(canvas, 6, 30, "m/44'/x'/0'/0");
260+
canvas_draw_str(canvas, 6, 30, s_derivation_text);
246261
canvas_draw_icon(canvas, 86, 25, &I_Keychain_39x36);
247262
} else if(model->page >= 9 && model->page <= 13) {
248263
canvas_set_font(canvas, FontSecondary);
249264
const char* receive_text;
250-
if(model->coin == 0) { // BTC
265+
if(model->coin == COIN_BTC) { // BTC
251266
receive_text = "BTC receive address:";
252-
} else if(model->coin == 60) { // ETH
267+
} else if(model->coin == COIN_DOGE) { // DOGE
268+
receive_text = "DOGE receive address:";
269+
} else if(model->coin == COIN_ETH) { // ETH
253270
receive_text = "ETH receive address:";
254271
} else {
255272
receive_text = "Receive address:";
@@ -318,30 +335,17 @@ static int flipbip_scene_1_model_init(
318335
HDNode* root = malloc(sizeof(HDNode));
319336
hdnode_from_seed(model->seed, 64, SECP256K1_NAME, root);
320337

321-
// m/44'/0'/0'/0 or m/44'/60'/0'/0
322-
const uint32_t purpose = 44;
323-
//const uint32_t coin = 0; // BTC
324-
//const uint32_t coin = 60; // ETH
325-
const uint32_t account = 0;
326-
const uint32_t change = 0;
327-
328-
// constants for BTC / ETH
329-
const uint32_t version_public = 0x0488b21e;
330-
const uint32_t version_private = 0x0488ade4;
331-
// "xprv_magic": 76066276,
332-
// "xpub_magic": 76067358,
333-
// "xpub_magic_segwit_p2sh": 77429938,
334-
// "xpub_magic_segwit_native": 78792518,
335-
// "xpub_magic_multisig_segwit_p2sh": 43365439,
336-
// "xpub_magic_multisig_segwit_native": 44728019,
337-
338338
// buffer for key serialization
339339
const size_t buflen = 128;
340340
char buf[128 + 1];
341341

342342
// root
343343
uint32_t fingerprint = 0;
344-
hdnode_serialize_private(root, fingerprint, version_private, buf, buflen);
344+
if (model->coin == COIN_DOGE) {
345+
hdnode_serialize_private(root, fingerprint, DOGE_VERSION_PRIVATE, buf, buflen);
346+
} else {
347+
hdnode_serialize_private(root, fingerprint, VERSION_PRIVATE, buf, buflen);
348+
}
345349
char* xprv_root = malloc(buflen + 1);
346350
strncpy(xprv_root, buf, buflen);
347351
model->xprv_root = xprv_root;
@@ -350,36 +354,52 @@ static int flipbip_scene_1_model_init(
350354

351355
// purpose m/44'
352356
fingerprint = hdnode_fingerprint(node);
353-
hdnode_private_ckd_prime(node, purpose); // purpose
357+
hdnode_private_ckd_prime(node, DERIV_PURPOSE); // purpose
354358

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

359363
// account m/44'/0'/0' or m/44'/60'/0'
360364
fingerprint = hdnode_fingerprint(node);
361-
hdnode_private_ckd_prime(node, account); // account
365+
hdnode_private_ckd_prime(node, DERIV_ACCOUNT); // account
362366

363-
hdnode_serialize_private(node, fingerprint, version_private, buf, buflen);
367+
if (model->coin == COIN_DOGE) {
368+
hdnode_serialize_private(node, fingerprint, DOGE_VERSION_PRIVATE, buf, buflen);
369+
} else {
370+
hdnode_serialize_private(node, fingerprint, VERSION_PRIVATE, buf, buflen);
371+
}
364372
char* xprv_acc = malloc(buflen + 1);
365373
strncpy(xprv_acc, buf, buflen);
366374
model->xprv_account = xprv_acc;
367375

368-
hdnode_serialize_public(node, fingerprint, version_public, buf, buflen);
376+
if (model->coin == COIN_DOGE) {
377+
hdnode_serialize_public(node, fingerprint, DOGE_VERSION_PUBLIC, buf, buflen);
378+
} else {
379+
hdnode_serialize_public(node, fingerprint, VERSION_PUBLIC, buf, buflen);
380+
}
369381
char* xpub_acc = malloc(buflen + 1);
370382
strncpy(xpub_acc, buf, buflen);
371383
model->xpub_account = xpub_acc;
372384

373385
// external/internal (change) m/44'/0'/0'/0 or m/44'/60'/0'/0
374386
fingerprint = hdnode_fingerprint(node);
375-
hdnode_private_ckd(node, change); // external/internal (change)
387+
hdnode_private_ckd(node, DERIV_CHANGE); // external/internal (change)
376388

377-
hdnode_serialize_private(node, fingerprint, version_private, buf, buflen);
389+
if (model->coin == COIN_DOGE) {
390+
hdnode_serialize_private(node, fingerprint, DOGE_VERSION_PRIVATE, buf, buflen);
391+
} else {
392+
hdnode_serialize_private(node, fingerprint, VERSION_PRIVATE, buf, buflen);
393+
}
378394
char* xprv_ext = malloc(buflen + 1);
379395
strncpy(xprv_ext, buf, buflen);
380396
model->xprv_extended = xprv_ext;
381397

382-
hdnode_serialize_public(node, fingerprint, version_public, buf, buflen);
398+
if (model->coin == COIN_DOGE) {
399+
hdnode_serialize_public(node, fingerprint, DOGE_VERSION_PUBLIC, buf, buflen);
400+
} else {
401+
hdnode_serialize_public(node, fingerprint, VERSION_PUBLIC, buf, buflen);
402+
}
383403
char* xpub_ext = malloc(buflen + 1);
384404
strncpy(xpub_ext, buf, buflen);
385405
model->xpub_extended = xpub_ext;
@@ -504,9 +524,14 @@ void flipbip_scene_1_enter(void* context) {
504524
strength = 192; // 18 words (192 bit)
505525

506526
// BIP44 Coin setting
507-
int coin_setting = app->bip44_coin;
508-
uint32_t coin = 0; //FlipBipCoinBTC0 // BTC (0)
509-
if(coin_setting == FlipBipCoinETH60) coin = 60; // ETH (60)
527+
uint32_t coin = app->bip44_coin;
528+
if (coin == COIN_BTC) {
529+
s_derivation_text = "m/44'/0'/0'/0";
530+
} else if (coin == COIN_DOGE) {
531+
s_derivation_text = "m/44'/3'/0'/0";
532+
} else if (coin == COIN_ETH) {
533+
s_derivation_text = "m/44'/60'/0'/0";
534+
}
510535

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

0 commit comments

Comments
 (0)