Skip to content

Commit

Permalink
Tidy up code that sets 'Processing' screen on Nano devices
Browse files Browse the repository at this point in the history
Fixes #10

Signed-off-by: Aido <aido@users.noreply.github.com>
  • Loading branch information
aido committed Nov 13, 2023
1 parent 57d11bb commit 9883d3f
Show file tree
Hide file tree
Showing 18 changed files with 170 additions and 148 deletions.
10 changes: 6 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
# Change log

## [1.5.2] - 2023-11-10
## [1.5.2] - 2023-11-13
### Added
-

### Changed
-

### Fixed
- Save memory by setting the SSKR word buffer to a sensible size
- There is just enough memory available on Nano S to hold the phrases for 10 shares. Other devices can hold the full 16 shares.
- Tidy up code that sets 'Processing' screen on Nano devices


### Fixed
- Fix screen freezing at 'Processing' screen on Nano devices

## [1.5.1] - 2023-11-09
### Added
Expand Down
6 changes: 2 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,10 @@ APP_LOAD_PARAMS = --appFlags 0x10 $(COMMON_LOAD_PARAMS) --curve secp256k1 --path

ifeq ($(TARGET_NAME), TARGET_NANOS)
ICONNAME=glyphs/seed_nanos.gif
else ifeq ($(TARGET_NAME), TARGET_NANOX)
ICONNAME=glyphs/seed_nanox.gif
else ifeq ($(TARGET_NAME), TARGET_NANOS2)
ICONNAME=glyphs/seed_nanox.gif
else ifeq ($(TARGET_NAME), TARGET_STAX)
ICONNAME=glyphs/seed_stax_32px.gif
else
ICONNAME=glyphs/seed_nanox.gif
endif

# Build configuration
Expand Down
1 change: 1 addition & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- [ ] There is just enough memory available on Nano S to hold the phrases for 10 shares. Maybe just store SSKR Bytewords as shorter two letter minimal Bytewords rather than a 4 letter Byteword plus space for each share. Convert minimal ByteWords back to four letter Bytewords just prior to display.
- [ ] If/when the `cx_bn_gf2_n_mul()` syscall is available on Ledger Nano S change all Galois Field functionality to use syscalls.
- See [gf_syscalls](https://github.com/aido/app-seed-tool/tree/gf_syscalls) branch of repo.
- Remove all variable length arrays

### In Progress

Expand Down
Binary file modified icons/seed_tool.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions src/bc-sskr/bc-shamir/shamir.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ uint8_t *create_digest(const uint8_t *random_data,
return result;
}

static int32_t validate_parameters(uint8_t threshold, uint8_t share_count, uint8_t secret_length) {
static int16_t validate_parameters(uint8_t threshold, uint8_t share_count, uint8_t secret_length) {
if (share_count > SHAMIR_MAX_SHARE_COUNT) {
return SHAMIR_ERROR_TOO_MANY_SHARES;
} else if (threshold < 1 || threshold > share_count) {
Expand All @@ -49,7 +49,7 @@ static int32_t validate_parameters(uint8_t threshold, uint8_t share_count, uint8

//////////////////////////////////////////////////
// shamir sharing
int32_t shamir_split_secret(uint8_t threshold,
int16_t shamir_split_secret(uint8_t threshold,
uint8_t share_count,
const uint8_t *secret,
uint8_t secret_length,
Expand Down Expand Up @@ -110,7 +110,7 @@ int32_t shamir_split_secret(uint8_t threshold,

// returns the number of bytes written to the secret array, or a negative value if there was an
// error
int32_t shamir_recover_secret(uint8_t threshold,
int16_t shamir_recover_secret(uint8_t threshold,
const uint8_t *x,
const uint8_t **shares,
uint8_t share_length,
Expand Down
4 changes: 2 additions & 2 deletions src/bc-sskr/bc-shamir/shamir.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ uint8_t *create_digest(const uint8_t *random_data,
* secret secret_length: length of the secret array. must be >= 16, <= 32 and even. result: place to
* store the resulting shares. Must be able to hold share_count * secret_length bytes
*/
int32_t shamir_split_secret(uint8_t threshold,
int16_t shamir_split_secret(uint8_t threshold,
uint8_t share_count,
const uint8_t *secret,
uint8_t secret_length,
Expand All @@ -65,7 +65,7 @@ int32_t shamir_split_secret(uint8_t threshold,
* share_length: number of bytes in each y value array
* secret: array for writing results (must be at least share_length long)
*/
int32_t shamir_recover_secret(uint8_t threshold,
int16_t shamir_recover_secret(uint8_t threshold,
const uint8_t *x,
const uint8_t **shares,
uint8_t share_length,
Expand Down
119 changes: 61 additions & 58 deletions src/bc-sskr/sskr.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

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

static int check_secret_length(uint8_t len) {
static int16_t check_secret_length(uint8_t len) {
if (len < SSKR_MIN_STRENGTH_BYTES) {
return SSKR_ERROR_SECRET_TOO_SHORT;
}
Expand All @@ -28,7 +28,9 @@ static int check_secret_length(uint8_t len) {
return 0;
}

static int serialize_shard(const sskr_shard *shard, uint8_t *destination, size_t destination_len) {
static int16_t serialize_shard(const sskr_shard *shard,
uint8_t *destination,
uint16_t destination_len) {
if (destination_len < SSKR_METADATA_LENGTH_BYTES + shard->value_len) {
return SSKR_ERROR_INSUFFICIENT_SPACE;
}
Expand Down Expand Up @@ -66,7 +68,7 @@ static int serialize_shard(const sskr_shard *shard, uint8_t *destination, size_t
return shard->value_len + SSKR_METADATA_LENGTH_BYTES;
}

static int deserialize_shard(const uint8_t *source, size_t source_len, sskr_shard *shard) {
static int16_t deserialize_shard(const uint8_t *source, uint16_t source_len, sskr_shard *shard) {
if (source_len < SSKR_MIN_SERIALIZED_LENGTH_BYTES) {
return SSKR_ERROR_NOT_ENOUGH_SERIALIZED_BYTES;
}
Expand All @@ -91,16 +93,16 @@ static int deserialize_shard(const uint8_t *source, size_t source_len, sskr_shar
shard->value_len = source_len - SSKR_METADATA_LENGTH_BYTES;
memcpy(shard->value, source + SSKR_METADATA_LENGTH_BYTES, shard->value_len);

int err = check_secret_length(shard->value_len);
int16_t err = check_secret_length(shard->value_len);
if (err) {
return err;
}
return shard->value_len;
}

int sskr_count_shards(uint8_t group_threshold,
const sskr_group_descriptor *groups,
uint8_t groups_len) {
int16_t sskr_count_shards(uint8_t group_threshold,
const sskr_group_descriptor *groups,
uint8_t groups_len) {
uint8_t shard_count = 0;

if (groups_len < 1) {
Expand Down Expand Up @@ -130,21 +132,21 @@ int sskr_count_shards(uint8_t group_threshold,
//////////////////////////////////////////////////
// generate shards
//
static int generate_shards(uint8_t group_threshold,
const sskr_group_descriptor *groups,
uint8_t groups_len,
const uint8_t *master_secret,
size_t master_secret_len,
sskr_shard *shards,
uint16_t shards_size,
unsigned char *(*random_generator)(uint8_t *, size_t)) {
int err = check_secret_length(master_secret_len);
static int16_t generate_shards(uint8_t group_threshold,
const sskr_group_descriptor *groups,
uint8_t groups_len,
const uint8_t *master_secret,
uint16_t master_secret_len,
sskr_shard *shards,
uint16_t shards_size,
unsigned char *(*random_generator)(uint8_t *, size_t)) {
int16_t err = check_secret_length(master_secret_len);
if (err) {
return err;
}

// Figure out how many shards we are dealing with
int total_shards = sskr_count_shards(group_threshold, groups, groups_len);
int16_t total_shards = sskr_count_shards(group_threshold, groups, groups_len);
if (total_shards < 0) {
return total_shards;
}
Expand Down Expand Up @@ -172,7 +174,7 @@ static int generate_shards(uint8_t group_threshold,

uint8_t *group_share = group_shares;

unsigned int shards_count = 0;
uint16_t shards_count = 0;
sskr_shard *shard;

for (uint8_t i = 0; i < groups_len; ++i, group_share += master_secret_len) {
Expand Down Expand Up @@ -215,34 +217,34 @@ static int generate_shards(uint8_t group_threshold,
//////////////////////////////////////////////////
// generate mnemonics
//
int sskr_generate(uint8_t group_threshold,
const sskr_group_descriptor *groups,
uint8_t groups_len,
const uint8_t *master_secret,
size_t master_secret_len,
uint8_t *shard_len,
uint8_t *output,
size_t buffer_size,
unsigned char *(*random_generator)(uint8_t *, size_t)) {
int err = check_secret_length(master_secret_len);
int16_t sskr_generate(uint8_t group_threshold,
const sskr_group_descriptor *groups,
uint8_t groups_len,
const uint8_t *master_secret,
uint16_t master_secret_len,
uint8_t *shard_len,
uint8_t *output,
uint16_t buffer_size,
unsigned char *(*random_generator)(uint8_t *, size_t)) {
int16_t err = check_secret_length(master_secret_len);
if (err) {
return err;
}

// Figure out how many shards we are dealing with
int total_shards = sskr_count_shards(group_threshold, groups, groups_len);
int16_t total_shards = sskr_count_shards(group_threshold, groups, groups_len);
if (total_shards < 0) {
return total_shards;
}

// figure out how much space we need to store all of the mnemonics
// and make sure that we were provided with sufficient resources
size_t shard_length = SSKR_METADATA_LENGTH_BYTES + master_secret_len;
uint16_t shard_length = SSKR_METADATA_LENGTH_BYTES + master_secret_len;
if (buffer_size < shard_length * total_shards) {
return SSKR_ERROR_INSUFFICIENT_SPACE;
}

int error = 0;
int16_t error = 0;

// allocate space for shard representations
sskr_shard shards[total_shards];
Expand All @@ -262,11 +264,11 @@ int sskr_generate(uint8_t group_threshold,
}

uint8_t *cur_output = output;
unsigned int remaining_buffer = buffer_size;
unsigned int byte_count = 0;
uint16_t remaining_buffer = buffer_size;
uint16_t byte_count = 0;

for (size_t i = 0; !error && i < (unsigned int) total_shards; ++i) {
int bytes = serialize_shard(&shards[i], cur_output, remaining_buffer);
for (uint16_t i = 0; !error && i < (uint16_t) total_shards; ++i) {
int16_t bytes = serialize_shard(&shards[i], cur_output, remaining_buffer);
if (bytes < 0) {
error = bytes;
break;
Expand All @@ -287,9 +289,9 @@ int sskr_generate(uint8_t group_threshold,
}

typedef struct sskr_group_struct {
size_t group_index;
size_t member_threshold;
size_t count;
uint8_t group_index;
uint8_t member_threshold;
uint8_t count;
uint8_t member_index[16];
const uint8_t *value[16];
} sskr_group;
Expand All @@ -299,12 +301,13 @@ typedef struct sskr_group_struct {
* in place, so it is for internal use only, however it provides the implementation
* for both combine_shards and sskr_combine.
*/
static int combine_shards_internal(sskr_shard *shards, // array of shard structures
uint8_t shards_count, // number of shards in array
uint8_t *buffer, // working space, and place to return secret
size_t buffer_len // total amount of working space
static int16_t combine_shards_internal(
sskr_shard *shards, // array of shard structures
uint8_t shards_count, // number of shards in array
uint8_t *buffer, // working space, and place to return secret
uint16_t buffer_len // total amount of working space
) {
int error = 0;
int16_t error = 0;
uint16_t identifier = 0;
uint8_t group_threshold = 0;
uint8_t group_count = 0;
Expand All @@ -315,7 +318,7 @@ static int combine_shards_internal(sskr_shard *shards, // array of shard stru

uint8_t next_group = 0;
sskr_group groups[16];
size_t secret_len = 0;
uint8_t secret_len = 0;

for (uint8_t i = 0; i < shards_count; ++i) {
sskr_shard *shard = &shards[i];
Expand Down Expand Up @@ -389,11 +392,11 @@ static int combine_shards_internal(sskr_shard *shards, // array of shard stru
break;
}

int recovery = shamir_recover_secret(g->member_threshold,
g->member_index,
g->value,
secret_len,
group_share);
int16_t recovery = shamir_recover_secret(g->member_threshold,
g->member_index,
g->value,
secret_len,
group_share);

if (recovery < 0) {
error = recovery;
Expand All @@ -404,7 +407,7 @@ static int combine_shards_internal(sskr_shard *shards, // array of shard stru
group_share += recovery;
}

int recovery = 0;
int16_t recovery = 0;
if (!error) {
recovery = shamir_recover_secret(group_threshold, gx, gy, secret_len, group_share);
}
Expand Down Expand Up @@ -434,24 +437,24 @@ static int combine_shards_internal(sskr_shard *shards, // array of shard stru
/////////////////////////////////////////////////
// sskr_combine

int sskr_combine(const uint8_t **input_shards, // array of pointers to 10-bit words
uint8_t shard_len, // number of bytes in each serialized shard
uint8_t shards_count, // total number of shards
uint8_t *buffer, // working space, and place to return secret
size_t buffer_len // total amount of working space
int16_t sskr_combine(const uint8_t **input_shards, // array of pointers to 10-bit words
uint8_t shard_len, // number of bytes in each serialized shard
uint8_t shards_count, // total number of shards
uint8_t *buffer, // working space, and place to return secret
uint16_t buffer_len // total amount of working space
) {
int result = 0;
int16_t result = 0;

if (shards_count == 0) {
return SSKR_ERROR_EMPTY_SHARD_SET;
}

sskr_shard shards[shards_count];

for (unsigned int i = 0; !result && i < shards_count; ++i) {
for (uint16_t i = 0; !result && i < shards_count; ++i) {
shards[i].value_len = 32;

int bytes = deserialize_shard(input_shards[i], shard_len, &shards[i]);
int16_t bytes = deserialize_shard(input_shards[i], shard_len, &shards[i]);

if (bytes < 0) {
result = bytes;
Expand Down
34 changes: 17 additions & 17 deletions src/bc-sskr/sskr.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
#include "sskr-constants.h"
#include "group.h"

int sskr_count_shards(uint8_t group_threshold,
const sskr_group_descriptor *groups,
uint8_t groups_len);
int16_t sskr_count_shards(uint8_t group_threshold,
const sskr_group_descriptor *groups,
uint8_t groups_len);

/**
* generate a set of shards that can be used to reconstruct a secret
Expand All @@ -39,15 +39,15 @@ int sskr_count_shards(uint8_t group_threshold,
* output[i*shard_len]..output[(i+1)*shard_len -1]
* buffer_size: maximum number of bytes to write to the output array
*/
int sskr_generate(uint8_t group_threshold,
const sskr_group_descriptor *groups,
uint8_t groups_length,
const uint8_t *master_secret,
size_t master_secret_length,
uint8_t *shard_len,
uint8_t *output,
size_t buffer_size,
unsigned char *(*random_generator)(uint8_t *, size_t));
int16_t sskr_generate(uint8_t group_threshold,
const sskr_group_descriptor *groups,
uint8_t groups_length,
const uint8_t *master_secret,
uint16_t master_secret_length,
uint8_t *shard_len,
uint8_t *output,
uint16_t buffer_size,
unsigned char *(*random_generator)(uint8_t *, size_t));

/**
* combine a set of serialized shards to reconstruct a secret
Expand All @@ -61,11 +61,11 @@ int sskr_generate(uint8_t group_threshold,
* buffer: location to store the result
* buffer_length: maximum space available in buffer
*/
int sskr_combine(const uint8_t **input_shards, // an array of pointers to serialized shards
uint8_t shard_len, // number of bytes in each serialized shard
uint8_t shards_count, // total number of shards
uint8_t *buffer, // working space, and place to return secret
size_t buffer_length // total amount of working space
int16_t sskr_combine(const uint8_t **input_shards, // an array of pointers to serialized shards
uint8_t shard_len, // number of bytes in each serialized shard
uint8_t shards_count, // total number of shards
uint8_t *buffer, // working space, and place to return secret
uint16_t buffer_length // total amount of working space
);

#endif /* SSKR_H */
Loading

0 comments on commit 9883d3f

Please sign in to comment.