Skip to content

Commit

Permalink
Add Stax layouts for generating SSKR shares
Browse files Browse the repository at this point in the history
  • Loading branch information
aido committed Jul 16, 2024
1 parent aa58ae5 commit b1268bb
Show file tree
Hide file tree
Showing 13 changed files with 367 additions and 191 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Using Ledger SDK `cx_crc32()` function rather than buggy `cx_crc32_hw()`.
- Fix build with SDK master for Nano S

## [1.7.1] - 2024-03-06
## [1.7.1] - 2024-04-06

### Changed

Expand Down
10 changes: 5 additions & 5 deletions src/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@
#define ONBOARDING_WORD_COMPLETION_MAX_ITEMS 8
#define BOLOS_UX_HASH_LENGTH 4 // as on the blue

#define MAX_WORD_LENGTH 8
#define MAX_NUMBER_LENGTH 2
#define BIP39_MAX_WORD_LENGTH 8
#define MAX_NUMBER_LENGTH 2

enum {
MNEMONIC_SIZE_12 = 12,
MNEMONIC_SIZE_18 = 18,
MNEMONIC_SIZE_24 = 24,
BIP39_MNEMONIC_SIZE_12 = 12,
BIP39_MNEMONIC_SIZE_18 = 18,
BIP39_MNEMONIC_SIZE_24 = 24,
};

// Type of onboarding we are performing (BIP39 or SSKR)
Expand Down
6 changes: 3 additions & 3 deletions src/nano/ui_nano.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ const char* number_of_bip39_words_getter(unsigned int idx) {
void number_of_bip39_words_selector(unsigned int idx) {
switch (idx) {
case 0:
G_bolos_ux_context.onboarding_kind = MNEMONIC_SIZE_12;
G_bolos_ux_context.onboarding_kind = BIP39_MNEMONIC_SIZE_12;
goto word_init;
case 1:
G_bolos_ux_context.onboarding_kind = MNEMONIC_SIZE_18;
G_bolos_ux_context.onboarding_kind = BIP39_MNEMONIC_SIZE_18;
goto word_init;
case 2:
G_bolos_ux_context.onboarding_kind = MNEMONIC_SIZE_24;
G_bolos_ux_context.onboarding_kind = BIP39_MNEMONIC_SIZE_24;
goto word_init;
word_init:
screen_onboarding_bip39_restore_init();
Expand Down
55 changes: 29 additions & 26 deletions src/stax/mnemonic.c → src/stax/bip39_mnemonic.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@
#include <string.h>

#include "../ux_common/common_bip39.h"
#include "./mnemonic.h"
#include "./bip39_mnemonic.h"

#if defined(TARGET_STAX)

typedef struct buffer {
typedef struct bip39_buffer_struct {
// the mnemonic passphrase, built over time
char buffer[MAX_MNEMONIC_LENGTH];
char buffer[BIP39_MNEMONIC_MAX_LENGTH];
// current length of the mnemonic passphrase
size_t length;
// index of the current word ((size_t)-1 mean there is no word currently)
size_t current_word_index;
// array of every stored word lengths (used for removing them if needed)
size_t word_lengths[MNEMONIC_SIZE_24];
size_t word_lengths[BIP39_MNEMONIC_SIZE_24];
// expected number of word in the final mnemonic (12 or 18 or 24)
size_t final_size;
} buffer_t;
} bip39_buffer_t;

static buffer_t mnemonic = {0};
static bip39_buffer_t mnemonic = {0};

size_t mnemonic_shrink(const size_t size) {
if (size == 0 || size > mnemonic.length) {
Expand All @@ -28,41 +28,41 @@ size_t mnemonic_shrink(const size_t size) {
} else {
mnemonic.length -= size;
}
memzero(&mnemonic.buffer[mnemonic.length], MAX_MNEMONIC_LENGTH - mnemonic.length);
memzero(&mnemonic.buffer[mnemonic.length], BIP39_MNEMONIC_MAX_LENGTH - mnemonic.length);
return mnemonic.length;
}

void set_mnemonic_final_size(const size_t size) {
void bip39_mnemonic_final_size_set(const size_t size) {
mnemonic.final_size = size;
}

size_t get_mnemonic_final_size() {
size_t bip39_mnemonic_final_size_get(void) {
return mnemonic.final_size;
}

size_t get_current_word_number() {
size_t bip39_mnemonic_current_word_number_get(void) {
return mnemonic.current_word_index + 1;
}

void reset_mnemonic() {
void bip39_mnemonic_reset(void) {
memzero(&mnemonic, sizeof(mnemonic));
mnemonic.current_word_index = (size_t) -1;
}

bool remove_word_from_mnemonic() {
PRINTF("Removing a word, currently there is '%ld' of them\n", mnemonic.current_word_index + 1);
bool bip39_mnemonic_word_remove(void) {
PRINTF("Removing a word, currently there is '%d' of them\n", mnemonic.current_word_index + 1);
if (mnemonic.current_word_index == (size_t) -1) {
return false;
}
const size_t current_length = mnemonic.word_lengths[mnemonic.current_word_index];
mnemonic.current_word_index--;
// removing previous word from mnemonic buffer (+ 1 blank space)
mnemonic_shrink(current_length + 1);
PRINTF("Number of remaining words in the mnemonic: '%ld'\n", mnemonic.current_word_index + 1);
PRINTF("Number of remaining words in the mnemonic: '%d'\n", mnemonic.current_word_index + 1);
return true;
}

size_t add_word_in_mnemonic(const char* const buffer, const size_t size) {
size_t bip39_mnemonic_word_add(const char* const buffer, const size_t size) {
if (mnemonic.current_word_index != (size_t) -1) {
// adding an extra white space ' ' between words
mnemonic.buffer[mnemonic.length++] = ' ';
Expand All @@ -72,35 +72,38 @@ size_t add_word_in_mnemonic(const char* const buffer, const size_t size) {
mnemonic.length += size;
mnemonic.current_word_index++;
mnemonic.word_lengths[mnemonic.current_word_index] = size;
PRINTF("Number of words in the mnemonic: '%ld'\n", get_current_word_number());
PRINTF("Number of words in the mnemonic: '%d'\n", bip39_mnemonic_current_word_number_get());
PRINTF("Current mnemonic: '%s'\n", &mnemonic.buffer[0]);
return get_current_word_number();
return bip39_mnemonic_current_word_number_get();
}

bool is_mnemonic_complete() {
bool bip39_mnemonic_complete_check(void) {
return (mnemonic.final_size == 0
? false
: (mnemonic.current_word_index + 1) >= get_mnemonic_final_size());
: (mnemonic.current_word_index + 1) >= bip39_mnemonic_final_size_get());
}

bool check_mnemonic() {
if (!is_mnemonic_complete()) {
bool bip39_mnemonic_check(void) {
if (!bip39_mnemonic_complete_check()) {
return false;
}
PRINTF("Checking the following mnemonic: '%s' (size %ld)\n",
PRINTF("Checking the following mnemonic: '%s' (size %d)\n",
&mnemonic.buffer[0],
mnemonic.length);
const bool result =
bolos_ux_bip39_mnemonic_check((unsigned char*) &mnemonic.buffer[0], mnemonic.length);
// Don;t clear the mneminic just yet as we may need it to generate SSKR shares
// reset_mnemonic();
// bip39_mnemonic_reset();
return result;
}

#if defined(TEST)
char* get_mnemonic() {
// Used for BIP39 <-> SSKR roundtrip
char* bip39_mnemonic_get(void) {
return mnemonic.buffer;
}
#endif

size_t bip39_mnemonic_length_get(void) {
return mnemonic.length;
}

#endif
34 changes: 20 additions & 14 deletions src/stax/mnemonic.h → src/stax/bip39_mnemonic.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,52 +21,58 @@

#if defined(TARGET_STAX)

#define memzero(...) explicit_bzero(__VA_ARGS__)
#define MAX_MNEMONIC_LENGTH (MNEMONIC_SIZE_24 * (MAX_WORD_LENGTH + 1))
#define memzero(...) explicit_bzero(__VA_ARGS__)
#define BIP39_MNEMONIC_MAX_LENGTH (BIP39_MNEMONIC_SIZE_24 * (BIP39_MAX_WORD_LENGTH + 1))

/*
* Sets how many words are expected in the mnemonic passphrase
*/
void set_mnemonic_final_size(const size_t size);
void bip39_mnemonic_final_size_set(const size_t size);

/*
* Returns how many words are expected in the mnemonic passphrase
*/
size_t get_mnemonic_final_size(void);
size_t bip39_mnemonic_final_size_get(void);

/*
* Returns how many words are currently stored in the mnemonic
*/
size_t get_current_word_number(void);
size_t bip39_mnemonic_current_word_number_get(void);

/*
* Check if the current number of words in the mnemonic fits the expected number of words
*/
bool is_mnemonic_complete(void);
bool bip39_mnemonic_complete_check(void);

/*
* Check if the currently stored mnemonic generates the same seed as the current device's one
*/
bool check_mnemonic(void);
bool bip39_mnemonic_check(void);

/*
* Erase all information and reset the indexes
*/
void reset_mnemonic(void);
void bip39_mnemonic_reset(void);

/*
* Remove the latest word from the passphrase, returns true if there was at least one to remove,
* else false (there was no word)
*/
bool remove_word_from_mnemonic(void);
bool bip39_mnemonic_word_remove(void);

/*
* Adds a word in the passphrase, returns how many words are stored in the mnemonic
*/
size_t add_word_in_mnemonic(const char* const buffer, const size_t size);
size_t bip39_mnemonic_word_add(const char* const buffer, const size_t size);

#if defined(TEST)
char* get_mnemonic();
#endif
/*
* Returns the mnemonic passphrase
*/
char* bip39_mnemonic_get(void);

/*
* Returns length of the mnemonic passphrase
*/
size_t bip39_mnemonic_length_get(void);

#endif // TARGET_NANOS
#endif // TARGET_STAX
2 changes: 1 addition & 1 deletion src/stax/layout_generic_screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ nbgl_button_t *generic_screen_set_back_button() {
button->obj.area.height = BUTTON_DIAMETER;
button->radius = BUTTON_RADIUS;
button->text = NULL;
button->icon = &C_leftArrow32px;
button->icon = &C_Back_32px;
button->obj.alignmentMarginX = 0;
button->obj.alignmentMarginY = UPPER_MARGIN;
button->obj.alignment = TOP_LEFT;
Expand Down
69 changes: 69 additions & 0 deletions src/stax/sskr_shares.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include <os.h>
#include <string.h>

#include "../ux_common/common_sskr.h"
#include "./sskr_shares.h"
#include "./bip39_mnemonic.h"

#if defined(TARGET_STAX)

typedef struct sskr_buffer_struct {
// The SSKR shares, built over time
char buffer[SSKR_SHARES_MAX_LENGTH];
// current length of the shares buffer
unsigned int length;
unsigned int group_descriptor[1][2];
uint8_t count;
} sskr_buffer_t;

static sskr_buffer_t shares = {0};

void sskr_sharenum_set(const uint8_t sharenum) {
shares.group_descriptor[0][1] = sharenum;
}

uint8_t sskr_sharenum_get(void) {
return shares.group_descriptor[0][1];
}

void sskr_threshold_set(const uint8_t threshold) {
shares.group_descriptor[0][0] = threshold;
}

uint8_t sskr_threshold_get(void) {
return shares.group_descriptor[0][0];
}

uint8_t sskr_sharecount_get(void) {
return shares.count;
}

void sskr_shares_reset(void) {
memzero(&shares, sizeof(shares));
}

void sskr_shares_from_bip39_mnemonic(void) {

shares.length = 0;

bolos_ux_bip39_to_sskr_convert((unsigned char*) bip39_mnemonic_get(),
bip39_mnemonic_length_get(),
bip39_mnemonic_final_size_get(),
shares.group_descriptor[0],
&shares.count,
(unsigned char*) shares.buffer,
&shares.length);

if (shares.count > 0) {
PRINTF("SSKR share count is %d\n", shares.count);
PRINTF("SSKR share buffer length is %d\n", shares.length);
for (uint8_t share = 0; share < shares.count; share++) {
PRINTF("SSKR share %d:\n", share + 1);
PRINTF("%.*s\n",
shares.length / shares.count,
shares.buffer + share * shares.length / shares.count);
}
}
}

#endif
62 changes: 62 additions & 0 deletions src/stax/sskr_shares.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*******************************************************************************
* (c) 2016-2022 Ledger SAS
*
* 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.
********************************************************************************/

#pragma once

#if defined(TARGET_STAX)

#define memzero(...) explicit_bzero(__VA_ARGS__)

// 16 shares * 229 chars per share (46 SSKR ByteWords)
#define SSKR_SHARES_MAX_LENGTH 3664

/*
* Sets the number of SSKR shares
*/
void sskr_sharenum_set(const uint8_t sharenum);

/*
* Returns the SSKR shares
*/
uint8_t sskr_sharenum_get(void);

/*
* Sets the SSKR threshold
*/
void sskr_threshold_set(const uint8_t threshold);

/*
* Returns the SSKR threshold
*/
uint8_t sskr_threshold_get(void);

/*
* Returns the SSKR share count
*/

uint8_t sskr_sharecount_get(void);

/*
* Erase all information and reset the indexes
*/
void sskr_shares_reset(void);

/*
* Generate SSKR shares from BIP39 mnemonic
*/
void sskr_shares_from_bip39_mnemonic(void);

#endif // TARGET_STAX
Loading

0 comments on commit b1268bb

Please sign in to comment.