Skip to content

Commit

Permalink
Make generic SSKR functionality more Ledger specific
Browse files Browse the repository at this point in the history
  • Loading branch information
aido committed Nov 1, 2023
1 parent 9995cc5 commit 977fb76
Show file tree
Hide file tree
Showing 11 changed files with 66 additions and 134 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# Change log

## [1.5.1] - 2023-10-26
## [1.5.1] - 2023-11-02
### Added
-

### Changed
- Reduce size of Nano binaries slightly
- Reduce size of Nano binaries slightly by removing duplicate flows
- Make generic SSKR functionality more Ledger specific

### Fixed
-
Expand Down
4 changes: 0 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,12 @@ APP_LOAD_PARAMS = --appFlags 0x10 $(COMMON_LOAD_PARAMS) --curve secp256k1 --path

ifeq ($(TARGET_NAME), TARGET_NANOS)
ICONNAME=glyphs/seed_nanos.gif
DEFINES += LEDGER_NANOS
else ifeq ($(TARGET_NAME), TARGET_NANOX)
ICONNAME=glyphs/seed_nanox.gif
DEFINES += LEDGER_NANOX
else ifeq ($(TARGET_NAME), TARGET_NANOS2)
ICONNAME=glyphs/seed_nanox.gif
DEFINES += LEDGER_NANOS2
else ifeq ($(TARGET_NAME), TARGET_STAX)
ICONNAME=glyphs/seed_stax_32px.gif
DEFINES += LEDGER_STAX
endif

# Build configuration
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
[![Code style check](https://github.com/aido/app-seed-tool/actions/workflows/lint-workflow.yml/badge.svg)](https://github.com/aido/app-seed-tool/actions/workflows/lint-workflow.yml)
[![License](https://img.shields.io/github/license/aido/app-seed-tool)](https://github.com/aido/app-seed-tool/blob/develop/LICENSE)

[![Release](https://img.shields.io/github/release/aido/app-seed-tool)](https://github.com/aido/app-seed-tool/releases)
![nanos](https://img.shields.io/badge/nanos-working-green)
![nanox](https://img.shields.io/badge/nanox-working-green])
![nanosp](https://img.shields.io/badge/nanosp-working-green)
Expand All @@ -23,6 +24,9 @@ The application uses [Sharded Secret Key Reconstruction (SSKR)](https://github.c

For more information about SSKR, see [SSKR for Users](https://github.com/BlockchainCommons/crypto-commons/blob/master/Docs/sskr-users.md).

> [!NOTE]
> Generated Shamir's Secret Shares may be cheaply and safely backed up to a steel wallet using the method described [here](https://blockmit.com/english/guides/diy/make-cold-wallet-washers/) or [here](https://jlopp.github.io/metal-bitcoin-storage-reviews/reviews/safu-ninja/). This will keep your backup safe in event of fire, flood or natural disaster.
## Check Shamir's secret shares
The Ledger application also provides an option to confirm the onboarded seed against SSKR shares.

Expand Down
7 changes: 0 additions & 7 deletions src/bc-sskr/bc-shamir/hazmat.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,7 @@
#include <string.h>
#include "hazmat.h"

#if defined(ARDUINO) || defined(__EMSCRIPTEN__)
#include "bc-crypto-base.h"
#elif defined(LEDGER_NANOS) || defined(LEDGER_NANOS2) || defined(LEDGER_NANOX) || \
defined(LEDGER_STAX)
#define memzero(...) explicit_bzero(__VA_ARGS__)
#else
#include <bc-crypto-base/bc-crypto-base.h>
#endif

/**
* bitslice - Transpose bits of 32 bytes to form 8 32-bit words.
Expand Down
7 changes: 0 additions & 7 deletions src/bc-sskr/bc-shamir/interpolate.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,7 @@
#include "hazmat.h"
#include "shamir-constants.h"

#if defined(ARDUINO) || defined(__EMSCRIPTEN__)
#include "bc-crypto-base.h"
#elif defined(LEDGER_NANOS) || defined(LEDGER_NANOS2) || defined(LEDGER_NANOX) || \
defined(LEDGER_STAX)
#define memzero(...) explicit_bzero(__VA_ARGS__)
#else
#include <bc-crypto-base/bc-crypto-base.h>
#endif

/*
* calculate the lagrange basis coefficients for the lagrange polynomial
Expand Down
48 changes: 19 additions & 29 deletions src/bc-sskr/bc-shamir/shamir.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,13 @@
//

#include <string.h>

#if defined(ARDUINO) || defined(__EMSCRIPTEN__)
#include "bc-crypto-base.h"
#elif defined(LEDGER_NANOS) || defined(LEDGER_NANOS2) || defined(LEDGER_NANOX) || \
defined(LEDGER_STAX)
#define memzero(...) explicit_bzero(__VA_ARGS__)
#define hmac_sha256(random_data, rdlen, shared_secret, sslen, buf) \
cx_hmac_sha256(random_data, rdlen, shared_secret, sslen, buf, sizeof(buf))
#include <cx.h>
#else
#include <bc-crypto-base/bc-crypto-base.h>
#endif

#include "shamir.h"
#include "interpolate.h"

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

//////////////////////////////////////////////////
// hmac sha256

Expand All @@ -32,7 +23,7 @@ uint8_t *create_digest(const uint8_t *random_data,
uint8_t *result) {
uint8_t buf[32];

hmac_sha256(random_data, rdlen, shared_secret, sslen, buf);
cx_hmac_sha256(random_data, rdlen, shared_secret, sslen, buf, sizeof(buf));

for (uint8_t j = 0; j < 4; ++j) {
result[j] = buf[j];
Expand All @@ -41,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, uint32_t secret_length) {
static int32_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 @@ -58,13 +49,12 @@ static int32_t validate_parameters(uint8_t threshold, uint8_t share_count, uint3

//////////////////////////////////////////////////
// shamir sharing
int32_t split_secret(uint8_t threshold,
uint8_t share_count,
const uint8_t *secret,
uint32_t secret_length,
uint8_t *result,
void *ctx,
void (*random_generator)(uint8_t *, size_t, void *)) {
int32_t shamir_split_secret(uint8_t threshold,
uint8_t share_count,
const uint8_t *secret,
uint8_t secret_length,
uint8_t *result,
unsigned char *(*random_generator)(uint8_t *, size_t)) {
int32_t err = validate_parameters(threshold, share_count, secret_length);
if (err) {
return err;
Expand All @@ -74,7 +64,7 @@ int32_t split_secret(uint8_t threshold,
// just return share_count copies of the secret
uint8_t *share = result;
for (uint8_t i = 0; i < share_count; ++i, share += secret_length) {
for (uint8_t j = 0; j < (uint8_t) secret_length; ++j) {
for (uint8_t j = 0; j < secret_length; ++j) {
share[j] = secret[j];
}
}
Expand All @@ -87,14 +77,14 @@ int32_t split_secret(uint8_t threshold,
uint8_t *share = result;

for (uint8_t i = 0; i < threshold - 2; ++i, share += secret_length) {
random_generator(share, secret_length, ctx);
random_generator(share, secret_length);
x[n] = i;
y[n] = share;
n += 1;
}

// generate secret_length - 4 bytes worth of random data
random_generator(digest + 4, secret_length - 4, ctx);
random_generator(digest + 4, secret_length - 4);
// put 4 bytes of digest at the top of the digest array
create_digest(digest + 4, secret_length - 4, secret, secret_length, digest);
x[n] = DIGEST_INDEX;
Expand All @@ -120,11 +110,11 @@ int32_t 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 recover_secret(uint8_t threshold,
const uint8_t *x,
const uint8_t **shares,
uint32_t share_length,
uint8_t *secret) {
int32_t shamir_recover_secret(uint8_t threshold,
const uint8_t *x,
const uint8_t **shares,
uint8_t share_length,
uint8_t *secret) {
int32_t err = validate_parameters(threshold, threshold, share_length);
if (err) {
return err;
Expand All @@ -135,7 +125,7 @@ int32_t recover_secret(uint8_t threshold,
uint8_t valid = 1;

if (threshold == 1) {
for (uint8_t j = 0; j < (uint8_t) share_length; ++j) {
for (uint8_t j = 0; j < share_length; ++j) {
secret[j] = shares[0][j];
}
return share_length;
Expand Down
26 changes: 12 additions & 14 deletions src/bc-sskr/bc-shamir/shamir.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,14 @@ uint8_t *create_digest(const uint8_t *random_data,
* inputs: threshold: number of shares required to recover secret. Must be 1 <= threshold <=
* share_count. share_count: number of shares to generate secret: array of bytes representing the
* 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. ctx:
* user-defined context to be passed to the random_generator function.
* store the resulting shares. Must be able to hold share_count * secret_length bytes
*/
int32_t split_secret(uint8_t threshold,
uint8_t share_count,
const uint8_t *secret,
uint32_t secret_length,
uint8_t *result,
void *ctx,
void (*random_generator)(uint8_t *, size_t, void *));
int32_t shamir_split_secret(uint8_t threshold,
uint8_t share_count,
const uint8_t *secret,
uint8_t secret_length,
uint8_t *result,
unsigned char *(*random_generator)(uint8_t *, size_t));

/**
* recover a secret from shares
Expand All @@ -67,10 +65,10 @@ int32_t 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 recover_secret(uint8_t threshold,
const uint8_t *x,
const uint8_t **shares,
uint32_t share_length,
uint8_t *secret);
int32_t shamir_recover_secret(uint8_t threshold,
const uint8_t *x,
const uint8_t **shares,
uint8_t share_length,
uint8_t *secret);

#endif /* SHAMIR_H */
85 changes: 26 additions & 59 deletions src/bc-sskr/encoding.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,16 @@
// Licensed under the "BSD-2-Clause Plus Patent License"
//

#include <stdio.h>
#include <string.h>
#include <stdbool.h>

#include "encoding.h"
#include "shard.h"
#include "sskr-errors.h"

#if defined(ARDUINO) || defined(__EMSCRIPTEN__)
#include "bc-crypto-base.h"
#include "bc-shamir.h"
#elif defined(LEDGER_NANOS) || defined(LEDGER_NANOS2) || defined(LEDGER_NANOX) || \
defined(LEDGER_STAX)
#include "bc-shamir.h"
#define memzero(...) explicit_bzero(__VA_ARGS__)
#else
#include <bc-crypto-base/bc-crypto-base.h>
#include <bc-shamir/bc-shamir.h>
#endif

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#define memzero(...) explicit_bzero(__VA_ARGS__)

static int check_secret_length(size_t len) {
if (len < MIN_STRENGTH_BYTES) {
Expand Down Expand Up @@ -147,8 +138,7 @@ static int generate_shards(uint8_t group_threshold,
size_t master_secret_len,
sskr_shard *shards,
uint16_t shards_size,
void *ctx,
void (*random_generator)(uint8_t *, size_t, void *)) {
unsigned char *(*random_generator)(uint8_t *, size_t)) {
int err = check_secret_length(master_secret_len);
if (err) {
return err;
Expand All @@ -162,7 +152,7 @@ static int generate_shards(uint8_t group_threshold,

// assign a random identifier
uint16_t identifier = 0;
random_generator((uint8_t *) (&identifier), 2, ctx);
random_generator((uint8_t *) (&identifier), 2);

if (shards_size < total_shards) {
return SSKR_ERROR_INSUFFICIENT_SPACE;
Expand All @@ -174,13 +164,12 @@ static int generate_shards(uint8_t group_threshold,

uint8_t group_shares[master_secret_len * groups_len];

split_secret(group_threshold,
groups_len,
master_secret,
master_secret_len,
group_shares,
ctx,
random_generator);
shamir_split_secret(group_threshold,
groups_len,
master_secret,
master_secret_len,
group_shares,
random_generator);

uint8_t *group_share = group_shares;

Expand All @@ -189,13 +178,12 @@ static int generate_shards(uint8_t group_threshold,

for (uint8_t i = 0; i < groups_len; ++i, group_share += master_secret_len) {
uint8_t member_shares[master_secret_len * groups[i].count];
split_secret(groups[i].threshold,
groups[i].count,
group_share,
master_secret_len,
member_shares,
ctx,
random_generator);
shamir_split_secret(groups[i].threshold,
groups[i].count,
group_share,
master_secret_len,
member_shares,
random_generator);

uint8_t *value = member_shares;
for (uint8_t j = 0; j < groups[i].count; ++j, value += master_secret_len) {
Expand Down Expand Up @@ -236,8 +224,7 @@ int sskr_generate(size_t group_threshold,
size_t *shard_len,
uint8_t *output,
size_t buffer_size,
void *ctx,
void (*random_generator)(uint8_t *, size_t, void *)) {
unsigned char *(*random_generator)(uint8_t *, size_t)) {
int err = check_secret_length(master_secret_len);
if (err) {
return err;
Expand Down Expand Up @@ -269,7 +256,6 @@ int sskr_generate(size_t group_threshold,
master_secret_len,
shards,
total_shards,
ctx,
random_generator);

if (total_shards < 0) {
Expand Down Expand Up @@ -404,8 +390,11 @@ static int combine_shards_internal(sskr_shard *shards, // array of shard struc
break;
}

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

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

int recovery = 0;
if (!error) {
recovery = recover_secret(group_threshold, gx, gy, secret_len, group_share);
recovery = shamir_recover_secret(group_threshold, gx, gy, secret_len, group_share);
}

if (recovery < 0) {
Expand All @@ -443,28 +432,6 @@ static int combine_shards_internal(sskr_shard *shards, // array of shard struc
return secret_len;
}

#if !defined(LEDGER_NANOS) && !defined(LEDGER_NANOS2) && !defined(LEDGER_NANOX) && \
!defined(LEDGER_STAX)
static int combine_shards(const sskr_shard *shards, // array of shard structures
uint16_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
) {
if (shards_count == 0) {
return SSKR_ERROR_EMPTY_SHARD_SET;
}

sskr_shard working_shards[shards_count];
memcpy(working_shards, shards, sizeof(working_shards));

int result = combine_shards_internal(working_shards, shards_count, buffer, buffer_len);

memzero(working_shards, sizeof(working_shards));

return result;
}
#endif

/////////////////////////////////////////////////
// sskr_combine

Expand Down
Loading

0 comments on commit 977fb76

Please sign in to comment.