From: jxnshi Date: Fri, 3 Jan 2025 23:48:32 +0000 (+0100) Subject: Fix seed phrase X-Git-Url: https://jxnshi.xyz/repos?a=commitdiff_plain;h=8dda0962938701cfe9d30a3f19da23f33f038bcc;p=mesange.git Fix seed phrase --- diff --git a/client-cli/client-cli b/client-cli/client-cli index 4681738..21bf908 100755 Binary files a/client-cli/client-cli and b/client-cli/client-cli differ diff --git a/client-cli/command.odin b/client-cli/command.odin index 09c6cbc..aa5bb27 100644 --- a/client-cli/command.odin +++ b/client-cli/command.odin @@ -5,7 +5,16 @@ import "core:sync" import fpath "core:path/filepath" -handle_command :: proc(app: ^App, command: string) -> bool { +Handle_Command_Error :: enum { + Not_A_Command, + Unknown_Command, +} + +handle_command :: proc(app: ^App, command: string) -> Maybe(Handle_Command_Error) { + if len(command) == 0 || command[0] != ':' { + return .Not_A_Command + } + sync.mutex_lock(&app.mutex) defer sync.mutex_unlock(&app.mutex) @@ -14,40 +23,43 @@ handle_command :: proc(app: ^App, command: string) -> bool { case .Invalid_Config: switch command { case ":r", ":retry": - return true + return nil case ":del", ":delete": config_path := fpath.join({ app.storage_path, "config.json" }, context.temp_allocator) os.remove(config_path) - return true + return nil } case .Invalid_Profile: switch command { case ":r", ":retry": - return true + return nil case ":del", ":delete": profile_path := app_get_profile_path(app, context.temp_allocator) os.remove(profile_path) - return true + return nil } case .Ask_Profile_Seed_Phrase: switch command { case ":reg", ":regen": app_reset_seed_phrase(app) - return true + return nil } } // General commands. switch command { - case ":q", ":quit": app.running = false - case: return false + case ":q", ":quit": + app.running = false + return nil } - return true + app_set_info_bar(app, "Unknown_command.") + + return .Unknown_Command } diff --git a/client-cli/profile.odin b/client-cli/profile.odin index ee307d4..2687697 100644 --- a/client-cli/profile.odin +++ b/client-cli/profile.odin @@ -172,7 +172,7 @@ profile_set_private_key_from_seed_phrase :: proc(profile: ^Profile, seed_phrase: bip_0039_words := BIP_0039_WORDS entropy: u128 - checksum: u8 + found_checksum: u8 word_count: int @@ -188,11 +188,12 @@ profile_set_private_key_from_seed_phrase :: proc(profile: ^Profile, seed_phrase: } if word_count + 1 != 12 { - entropy |= u128(word_index) entropy <<= 11 + entropy |= u128(word_index) } else { - entropy |= u128(word_index & 0b1111_111) - checksum |= u8((word_index >> 7) & 0b1111) + entropy <<= 7 + entropy |= u128(word_index & 0b1111_1111_1110_000) >> 4 + found_checksum |= u8(word_index & 0b1111) } word_count += 1 @@ -210,17 +211,14 @@ profile_set_private_key_from_seed_phrase :: proc(profile: ^Profile, seed_phrase: entropy_hash: [sha3.DIGEST_SIZE_256]u8 sha3.final(&sha_context, entropy_hash[:]) - found_checksum := entropy_hash[0] & 0b1111 - - log.infof("- Entropy bytes: %8b", mem.any_to_bytes(entropy)) - log.infof("- Entropy hash: %8b", mem.any_to_bytes(entropy_hash)) - log.infof("- Checksum: %4b", checksum) - log.infof("- Found checksum: %4b", found_checksum) + checksum := entropy_hash[0] & 0b1111 if found_checksum != checksum { return .Invalid_Checksum } + sha3.init_256(&sha_context) + private_key_bytes: [sha3.DIGEST_SIZE_256]u8 sha3.final(&sha_context, private_key_bytes[:]) diff --git a/client-cli/state.odin b/client-cli/state.odin index 125f928..7234732 100644 --- a/client-cli/state.odin +++ b/client-cli/state.odin @@ -61,17 +61,16 @@ state_invalid_config :: proc(app: ^App) { input := app_get_input(app, context.temp_allocator) - if input[0] == ':' { - if !handle_command(app, input) { - app_set_info_bar(app, "Invalid command.") + if err, ok := handle_command(app, input).?; ok { + if err != .Not_A_Command { return } } else { - app_set_info_bar(app, "Invalid input.") + app_set_state(app, .Load_Config) return } - app_set_state(app, .Load_Config) + app_set_info_bar(app, "Invalid input.") } state_load_profile :: proc(app: ^App) { @@ -122,17 +121,16 @@ state_invalid_profile :: proc(app: ^App) { input := app_get_input(app, context.temp_allocator) - if input[0] == ':' { - if !handle_command(app, input) { - app_set_info_bar(app, "Invalid command.") + if err, ok := handle_command(app, input).?; ok { + if err != .Not_A_Command { return } } else { - app_set_info_bar(app, "Invalid input.") + app_set_state(app, .Load_Config) return } - app_set_state(app, .Load_Config) + app_set_info_bar(app, "Invalid input.") } state_ask_profile :: proc(app: ^App) { @@ -153,6 +151,14 @@ state_ask_profile :: proc(app: ^App) { } } + if err, ok := handle_command(app, input).?; ok { + if err != .Not_A_Command { + return + } + } else { + return + } + if !is_identifier(input) { app_set_info_bar(app, "Invalid profile name.") return @@ -161,6 +167,7 @@ state_ask_profile :: proc(app: ^App) { app.config.selected_profile = input config_update(app.config, app) + app_set_state(app, .Load_Profile) } @@ -204,7 +211,7 @@ state_ask_profile_seed_phrase :: proc(app: ^App) { entropy <<= 11 if entropy == 0 { - word_index |= u16(app.seed_phrase_checksum) << 7 + word_index |= u16(app.seed_phrase_checksum) } word := bip_0039_words[word_index] @@ -233,25 +240,22 @@ state_ask_profile_seed_phrase :: proc(app: ^App) { input := app_get_input(app) - if input[0] == ':' { - if !handle_command(app, input) { - app_set_info_bar(app, "Invalid command.") + if err, ok := handle_command(app, input).?; ok { + if err != .Not_A_Command { return } - + } else { return } - err := profile_set_private_key_from_seed_phrase(&app.profile, input) + err2 := profile_set_private_key_from_seed_phrase(&app.profile, input) - if err != nil { - log.errorf("Invalid seed phrase with error %v", err) + if err2 != nil { + log.errorf("Invalid seed phrase with error %v", err2) app_set_info_bar(app, "Invalid seed phrase") return } - profile_update(&app.profile, app) - app_set_state(app, .Ask_Profile_Host) } @@ -262,6 +266,18 @@ state_ask_profile_host :: proc(app: ^App) { "Enter your host.", }, ) + + input := app_get_input(app) + + if err, ok := handle_command(app, input).?; ok { + if err != .Not_A_Command { + return + } + } else { + return + } + + } state_ask_profile_password_protection :: proc(app: ^App) {