Skip to content

Commit

Permalink
Added unit tests for SSKR functions
Browse files Browse the repository at this point in the history
  • Loading branch information
aido committed Nov 6, 2023
1 parent f26e617 commit ff99f62
Show file tree
Hide file tree
Showing 15 changed files with 339 additions and 263 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## [1.5.1] - 2023-11-04
### Added
- Added unit tests for shamir
- Added unit tests for SSKR

### Changed
- Reduce size of Nano binaries slightly by removing duplicate flows
Expand Down
2 changes: 1 addition & 1 deletion TODO.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# app-sskr-check TODO list
# app-seed-tool TODO list

### Todo

Expand Down
21 changes: 0 additions & 21 deletions src/bc-sskr/bc-shamir/bc-shamir.h

This file was deleted.

90 changes: 0 additions & 90 deletions src/bc-sskr/bc-shamir/hazmat.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,93 +293,3 @@ void gf256_inv(uint32_t r[8], uint32_t x[8]) {
gf256_mul(r, r, z); // r = x^250
gf256_mul(r, r, y); // r = x^254
}

#if 0

/*
* Create `k` key shares of the key given in `key`. The caller has to ensure
* that the array `out` has enough space to hold at least `n` sss_Keyshare
* structs.
*/
void
sss_create_keyshares(sss_Keyshare *out,
const uint8_t key[32],
uint8_t n,
uint8_t k)
{
/* Check if the parameters are valid */
assert(n != 0);
assert(k != 0);
assert(k <= n);

uint8_t share_idx, coeff_idx, unbitsliced_x;
uint32_t poly0[8], poly[k-1][8], x[8], y[8], xpow[8], tmp[8];

/* Put the secret in the bottom part of the polynomial */
bitslice(poly0, key);

/* Generate the other terms of the polynomial */
randombytes((void*) poly, sizeof(poly));

for (share_idx = 0; share_idx < n; share_idx++) {
/* x value is in 1..n */
unbitsliced_x = share_idx + 1;
out[share_idx][0] = unbitsliced_x;
bitslice_setall(x, unbitsliced_x);

/* Calculate y */
memzero(y, sizeof(y));
memzero(xpow, sizeof(xpow));
xpow[0] = ~0;
gf256_add(y, poly0);
for (coeff_idx = 0; coeff_idx < (k-1); coeff_idx++) {
gf256_mul(xpow, xpow, x);
gf256_mul(tmp, xpow, poly[coeff_idx]);
gf256_add(y, tmp);
}
unbitslice(&out[share_idx][1], y);
}
}


/*
* Restore the `k` sss_Keyshare structs given in `shares` and write the result
* to `key`.
*/
void sss_combine_keyshares(uint8_t key[32],
const sss_Keyshare *key_shares,
uint8_t k)
{
size_t share_idx, idx1, idx2;
uint32_t xs[k][8], ys[k][8];
uint32_t num[8], denom[8], tmp[8];
uint32_t secret[8] = {0};

/* Collect the x and y values */
for (share_idx = 0; share_idx < k; share_idx++) {
bitslice_setall(xs[share_idx], key_shares[share_idx][0]);
bitslice(ys[share_idx], &key_shares[share_idx][1]);
}

/* Use Lagrange basis polynomials to calculate the secret coefficient */
for (idx1 = 0; idx1 < k; idx1++) {
memzero(num, sizeof(num));
memzero(denom, sizeof(denom));
num[0] = ~0; /* num is the numerator (=1) */
denom[0] = ~0; /* denom is the numerator (=1) */
for (idx2 = 0; idx2 < k; idx2++) {
if (idx1 == idx2) continue;
gf256_mul(num, num, xs[idx2]);
memcpy(tmp, xs[idx1], sizeof(uint32_t[8]));
gf256_add(tmp, xs[idx2]);
gf256_mul(denom, denom, tmp);
}
gf256_inv(tmp, denom); /* inverted denominator */
gf256_mul(num, num, tmp); /* basis polynomial */
gf256_mul(num, num, ys[idx1]); /* scaled coefficient */
gf256_add(secret, num);
}
unbitslice(key, secret);
}

#endif
53 changes: 0 additions & 53 deletions src/bc-sskr/bc-shamir/hazmat.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,57 +87,4 @@ void gf256_square(uint32_t r[8], const uint32_t x[8]);
*/
void gf256_inv(uint32_t r[8], uint32_t x[8]);

#if 0

#define sss_KEYSHARE_LEN 33 /* 1 + 32 */

/*
* One share of a cryptographic key which is shared using Shamir's
* the `sss_create_keyshares` function.
*/
typedef uint8_t sss_Keyshare[sss_KEYSHARE_LEN];


/*
* Share the secret given in `key` into `n` shares with a threshold value given
* in `k`. The resulting shares are written to `out`.
*
* The share generation that is done in this function is only secure if the key
* that is given is indeed a cryptographic key. This means that it should be
* randomly and uniformly generated string of 32 bytes.
*
* Also, for performance reasons, this function assumes that both `n` and `k`
* are *public* values.
*
* If you are looking for a function that *just* creates shares of arbitrary
* data, you should use the `sss_create_shares` function in `sss.h`.
*/
void sss_create_keyshares(sss_Keyshare *out,
const uint8_t key[32],
uint8_t n,
uint8_t k);


/*
* Combine the `k` shares provided in `shares` and write the resulting key to
* `key`. The amount of shares used to restore a secret may be larger than the
* threshold needed to restore them.
*
* This function does *not* do *any* checking for integrity. If any of the
* shares not original, this will result in an invalid resored value.
* All values written to `key` should be treated as secret. Even if some of the
* shares that were provided as input were incorrect, the resulting key *still*
* allows an attacker to gain information about the real key.
*
* This function treats `shares` and `key` as secret values. `k` is treated as
* a public value (for performance reasons).
*
* If you are looking for a function that combines shares of arbitrary
* data, you should use the `sss_combine_shares` function in `sss.h`.
*/
void sss_combine_keyshares(uint8_t key[32],
const sss_Keyshare *shares,
uint8_t k);
#endif

#endif /* HAZMAT_H */
24 changes: 0 additions & 24 deletions src/bc-sskr/bc-sskr.h

This file was deleted.

13 changes: 9 additions & 4 deletions src/bc-sskr/sskr-errors.h → src/bc-sskr/sskr-constants.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
//
// sskr-errors.c
// sskr-constants.h
//
// Copyright © 2020 by Blockchain Commons, LLC
// Licensed under the "BSD-2-Clause Plus Patent License"
//

#ifndef SSKR_ERRORS_H
#define SSKR_ERRORS_H
#ifndef SSKR_CONSTANTS_H
#define SSKR_CONSTANTS_H

#define SSKR_METADATA_LENGTH_BYTES 5
#define SSKR_MIN_STRENGTH_BYTES 16
#define SSKR_MAX_STRENGTH_BYTES 32
#define SSKR_MIN_SERIALIZED_LENGTH_BYTES (SSKR_METADATA_LENGTH_BYTES + SSKR_MIN_STRENGTH_BYTES)

#define SSKR_ERROR_NOT_ENOUGH_SERIALIZED_BYTES (-1)
#define SSKR_ERROR_SECRET_TOO_SHORT (-2)
Expand All @@ -27,4 +32,4 @@
#define SSKR_ERROR_INVALID_GROUP_LENGTH (-17)
#define SSKR_ERROR_INVALID_GROUP_COUNT (-18)

#endif /* SSKR_ERRORS_H */
#endif /* SSKR_CONSTANTS_H */
25 changes: 12 additions & 13 deletions src/bc-sskr/encoding.c → src/bc-sskr/sskr.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// encoding.c
// sskr.c
//
// Copyright © 2020 by Blockchain Commons, LLC
// Licensed under the "BSD-2-Clause Plus Patent License"
Expand All @@ -9,18 +9,17 @@
#include <string.h>
#include <stdbool.h>

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

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

static int check_secret_length(size_t len) {
if (len < MIN_STRENGTH_BYTES) {
if (len < SSKR_MIN_STRENGTH_BYTES) {
return SSKR_ERROR_SECRET_TOO_SHORT;
}
if (len > MAX_STRENGTH_BYTES) {
if (len > SSKR_MAX_STRENGTH_BYTES) {
return SSKR_ERROR_SECRET_TOO_LONG;
}
if (len & 1) {
Expand All @@ -30,7 +29,7 @@ static int check_secret_length(size_t len) {
}

static int serialize_shard(const sskr_shard *shard, uint8_t *destination, size_t destination_len) {
if (destination_len < METADATA_LENGTH_BYTES + shard->value_len) {
if (destination_len < SSKR_METADATA_LENGTH_BYTES + shard->value_len) {
return SSKR_ERROR_INSUFFICIENT_SPACE;
}

Expand Down Expand Up @@ -62,13 +61,13 @@ static int serialize_shard(const sskr_shard *shard, uint8_t *destination, size_t
destination[3] = (gi << 4) | mt;
destination[4] = mi;

memcpy(destination + METADATA_LENGTH_BYTES, shard->value, shard->value_len);
memcpy(destination + SSKR_METADATA_LENGTH_BYTES, shard->value, shard->value_len);

return shard->value_len + METADATA_LENGTH_BYTES;
return shard->value_len + SSKR_METADATA_LENGTH_BYTES;
}

static int deserialize_shard(const uint8_t *source, size_t source_len, sskr_shard *shard) {
if (source_len < MIN_SERIALIZED_LENGTH_BYTES) {
if (source_len < SSKR_MIN_SERIALIZED_LENGTH_BYTES) {
return SSKR_ERROR_NOT_ENOUGH_SERIALIZED_BYTES;
}

Expand All @@ -89,8 +88,8 @@ static int deserialize_shard(const uint8_t *source, size_t source_len, sskr_shar
return SSKR_ERROR_INVALID_RESERVED_BITS;
}
shard->member_index = source[4] & 0xf;
shard->value_len = source_len - METADATA_LENGTH_BYTES;
memcpy(shard->value, source + METADATA_LENGTH_BYTES, shard->value_len);
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);
if (err) {
Expand Down Expand Up @@ -238,7 +237,7 @@ int sskr_generate(size_t group_threshold,

// 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 = METADATA_LENGTH_BYTES + master_secret_len;
size_t shard_length = SSKR_METADATA_LENGTH_BYTES + master_secret_len;
if (buffer_size < shard_length * total_shards) {
return SSKR_ERROR_INSUFFICIENT_SPACE;
}
Expand Down
15 changes: 6 additions & 9 deletions src/bc-sskr/encoding.h → src/bc-sskr/sskr.h
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
//
// encoding.h
// sskr.h
//
// Copyright © 2020 by Blockchain Commons, LLC
// Licensed under the "BSD-2-Clause Plus Patent License"
//

#ifndef ENCODING_H
#define ENCODING_H
#ifndef SSKR_H
#define SSKR_H

#include <stdlib.h>
#include "group.h"
#include <stdint.h>

#define METADATA_LENGTH_BYTES 5
#define MIN_STRENGTH_BYTES 16
#define MAX_STRENGTH_BYTES 32
#define MIN_SERIALIZED_LENGTH_BYTES (METADATA_LENGTH_BYTES + MIN_STRENGTH_BYTES)
#include "sskr-constants.h"
#include "group.h"

int sskr_count_shards(size_t group_threshold,
const sskr_group_descriptor *groups,
Expand Down Expand Up @@ -71,4 +68,4 @@ int sskr_combine(const uint8_t **input_shards, // an array of pointers to seria
size_t buffer_length // total amount of working space
);

#endif /* ENCODING_H */
#endif /* SSKR_H */
4 changes: 2 additions & 2 deletions src/ux_common/onboarding_seed_sskr.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#include "onboarding_seed_rom_variables.h"
#include "common_bip39.h"
#include "bc-sskr/bc-sskr.h"
#include "bc-sskr/sskr.h"

// Returns the CRC-32 checksum of the input buffer in network byte order (big endian).
uint32_t cx_crc32_hw_nbo(const uint8_t *bytes, size_t len) {
Expand All @@ -31,7 +31,7 @@ unsigned int bolos_ux_sskr_size_get(unsigned int bip39_onboarding_kind,
}

unsigned int share_count_expected = sskr_count_shards(groups_threshold, groups, groups_len);
*share_len = bip39_onboarding_kind * 4 / 3 + METADATA_LENGTH_BYTES;
*share_len = bip39_onboarding_kind * 4 / 3 + SSKR_METADATA_LENGTH_BYTES;

return share_count_expected;
}
Expand Down
Loading

0 comments on commit ff99f62

Please sign in to comment.