Skip to content

Commit a8e9bba

Browse files
committed
Added detailed documentation for all SSKR and SSS functions
1 parent 51d6dbf commit a8e9bba

File tree

9 files changed

+368
-195
lines changed

9 files changed

+368
-195
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Change log
22

3-
## [1.7.0] - 2024-03-02
3+
## [1.7.0] - 2024-03-03
44
### Added
5-
-
5+
- Added detailed documentation for all SSKR and SSS functions
66

77
### Changed
88
- Changed Shamir interpolate function to use `cx_bn_gf2_n_mul()` syscalls

src/sskr/sskr.c

Lines changed: 145 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,20 @@
1515

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

18+
/**
19+
* @brief Validates the length of a secret for SSKR functions.
20+
*
21+
* @details This function checks if the length of a secret is within the acceptable
22+
* range for use in SSKR. It enforces constraints on the secret length to
23+
* ensure security and compatibility.
24+
*
25+
* @param[in] len Length of the secret in bytes.
26+
*
27+
* @return 0 on success, indicating a valid secret length, or a negative error code on failure:
28+
* - SSKR_ERROR_SECRET_TOO_SHORT: if len is less than SSKR_MIN_STRENGTH_BYTES
29+
* - SSKR_ERROR_SECRET_TOO_LONG: if len is greater than SSKR_MAX_STRENGTH_BYTES
30+
* - SSKR_ERROR_SECRET_LENGTH_NOT_EVEN: if len is not even
31+
*/
1832
static int16_t sskr_check_secret_length(uint8_t len) {
1933
if (len < SSKR_MIN_STRENGTH_BYTES) {
2034
return SSKR_ERROR_SECRET_TOO_SHORT;
@@ -28,6 +42,21 @@ static int16_t sskr_check_secret_length(uint8_t len) {
2842
return 0;
2943
}
3044

45+
/**
46+
* @brief Serializes an SSKR shard into a byte array.
47+
*
48+
* @details This function converts an `sskr_shard_t` structure into a byte array suitable for
49+
* storage or transmission. It packs the shard's metadata (identifier, group/member
50+
* information) and value into a single buffer.
51+
*
52+
* @param[in] shard Pointer to the `sskr_shard_t` structure to be serialized.
53+
* @param[out] destination Pointer to the buffer where the serialized data will be written.
54+
* @param[in] destination_len Length of the `destination` buffer in bytes.
55+
*
56+
* @return Length of the serialized shard data on success, or a negative error code:
57+
* - SSKR_ERROR_INSUFFICIENT_SPACE: if `destination_len` is not enough to hold the
58+
* serialized data.
59+
*/
3160
static int16_t sskr_serialize_shard(const sskr_shard_t *shard,
3261
uint8_t *destination,
3362
uint16_t destination_len) {
@@ -68,6 +97,25 @@ static int16_t sskr_serialize_shard(const sskr_shard_t *shard,
6897
return shard->value_len + SSKR_METADATA_LENGTH_BYTES;
6998
}
7099

100+
/**
101+
* @brief Deserializes an SSKR shard from a byte array.
102+
*
103+
* @details This function reconstructs an `sskr_shard_t` structure from a serialized
104+
* byte array created using `sskr_serialize_shard`. It validates the metadata
105+
* and extracts the shard's identifier, group/member information, and value.
106+
*
107+
* @param[in] source Pointer to the serialized shard data.
108+
* @param[in] source_len Length of the `source` array in bytes.
109+
* @param[out] shard Pointer to an `sskr_shard_t` structure to be populated.
110+
*
111+
* @return Length of the shard value on success, or a negative error code:
112+
* - SSKR_ERROR_NOT_ENOUGH_SERIALIZED_BYTES: if `source_len` is too short.
113+
* - SSKR_ERROR_INVALID_GROUP_THRESHOLD: if group threshold exceeds group count.
114+
* - SSKR_ERROR_INVALID_RESERVED_BITS: if reserved bits are not zero.
115+
* - SSKR_ERROR_SECRET_TOO_SHORT, SSKR_ERROR_SECRET_TOO_LONG,
116+
* SSKR_ERROR_SECRET_LENGTH_NOT_EVEN (via `sskr_check_secret_length`)
117+
* if the extracted value length is invalid.
118+
*/
71119
static int16_t sskr_deserialize_shard(const uint8_t *source,
72120
uint16_t source_len,
73121
sskr_shard_t *shard) {
@@ -102,6 +150,25 @@ static int16_t sskr_deserialize_shard(const uint8_t *source,
102150
return shard->value_len;
103151
}
104152

153+
/**
154+
* @brief Calculates the total number of shards generated for a given SSKR configuration.
155+
*
156+
* @details This function determines the total shard count based on the group threshold,
157+
* group descriptors, and their respective member counts. It validates the
158+
* group configuration and enforces constraints to ensure logical consistency.
159+
*
160+
* @param[in] group_threshold Minimum number of groups required for secret reconstruction.
161+
* @param[in] groups Pointer to an array of `sskr_group_descriptor_t` structures.
162+
* @param[in] groups_len Number of groups in the `groups` array.
163+
*
164+
* @return Total number of shards on success, or a negative error code:
165+
* - SSKR_ERROR_INVALID_GROUP_LENGTH: if `groups_len` is less than 1.
166+
* - SSKR_ERROR_INVALID_GROUP_THRESHOLD: if `group_threshold` exceeds `groups_len`.
167+
* - SSKR_ERROR_INVALID_GROUP_COUNT: if any group has a count less than 1.
168+
* - SSKR_ERROR_INVALID_MEMBER_THRESHOLD: if any group's threshold exceeds its count.
169+
* - SSKR_ERROR_INVALID_SINGLETON_MEMBER: if any group with threshold 1 has a count greater
170+
* than 1.
171+
*/
105172
int16_t sskr_count_shards(uint8_t group_threshold,
106173
const sskr_group_descriptor_t *groups,
107174
uint8_t groups_len) {
@@ -131,17 +198,39 @@ int16_t sskr_count_shards(uint8_t group_threshold,
131198
return shard_count;
132199
}
133200

134-
//////////////////////////////////////////////////
135-
// generate shards
136-
//
137-
static int16_t sskr_generate_shards(uint8_t group_threshold,
138-
const sskr_group_descriptor_t *groups,
139-
uint8_t groups_len,
140-
const uint8_t *master_secret,
141-
uint16_t master_secret_len,
142-
sskr_shard_t *shards,
143-
uint16_t shards_size,
144-
unsigned char *(*random_generator)(uint8_t *, size_t)) {
201+
/**
202+
* @brief Internal function to generate SSKR shards from a master secret.
203+
*
204+
* @details This function performs the core logic of generating a set of shards
205+
* from a given master secret, using a specific group configuration and a
206+
* random number generator. It's an internal function, not intended for direct
207+
* use by external applications.
208+
*
209+
* @param[in] group_threshold Minimum number of groups required for secret reconstruction.
210+
* @param[in] groups Pointer to an array of `sskr_group_descriptor_t` structures.
211+
* @param[in] groups_len Number of groups in the `groups` array.
212+
* @param[in] master_secret Pointer to the master secret to be split.
213+
* @param[in] master_secret_len Length of the master secret in bytes.
214+
* @param[out] shards Pointer to an array of `sskr_shard_t` structures to store
215+
* the generated shards.
216+
* @param[in] shards_size Size of the `shards` array in bytes.
217+
* @param[in] random_generator Pointer to a function that generates random bytes.
218+
*
219+
* @return Number of shards generated on success, or a negative error code:
220+
* - SSKR_ERROR_INVALID_SECRET_LENGTH: if master secret length is invalid.
221+
* - SSKR_ERROR_INSUFFICIENT_SPACE: if `shards_size` is insufficient.
222+
* - SSKR_ERROR_INVALID_GROUP_THRESHOLD: if `group_threshold` exceeds `groups_len`.
223+
* - Other error codes from `sss_split_secret`.
224+
*/
225+
static int16_t sskr_generate_shards_internal(uint8_t group_threshold,
226+
const sskr_group_descriptor_t *groups,
227+
uint8_t groups_len,
228+
const uint8_t *master_secret,
229+
uint16_t master_secret_len,
230+
sskr_shard_t *shards,
231+
uint16_t shards_size,
232+
unsigned char *(*random_generator)(uint8_t *,
233+
size_t)) {
145234
int16_t err = sskr_check_secret_length(master_secret_len);
146235
if (err) {
147236
return err;
@@ -216,18 +305,15 @@ static int16_t sskr_generate_shards(uint8_t group_threshold,
216305
return shards_count;
217306
}
218307

219-
//////////////////////////////////////////////////
220-
// generate mnemonics
221-
//
222-
int16_t sskr_generate(uint8_t group_threshold,
223-
const sskr_group_descriptor_t *groups,
224-
uint8_t groups_len,
225-
const uint8_t *master_secret,
226-
uint16_t master_secret_len,
227-
uint8_t *shard_len,
228-
uint8_t *output,
229-
uint16_t buffer_size,
230-
unsigned char *(*random_generator)(uint8_t *, size_t)) {
308+
int16_t sskr_generate_shards(uint8_t group_threshold,
309+
const sskr_group_descriptor_t *groups,
310+
uint8_t groups_len,
311+
const uint8_t *master_secret,
312+
uint16_t master_secret_len,
313+
uint8_t *shard_len,
314+
uint8_t *output,
315+
uint16_t buffer_size,
316+
unsigned char *(*random_generator)(uint8_t *, size_t)) {
231317
int16_t err = sskr_check_secret_length(master_secret_len);
232318
if (err) {
233319
return err;
@@ -252,14 +338,14 @@ int16_t sskr_generate(uint8_t group_threshold,
252338
sskr_shard_t shards[SSS_MAX_SHARE_COUNT * SSKR_MAX_GROUP_COUNT];
253339

254340
// generate shards
255-
total_shards = sskr_generate_shards(group_threshold,
256-
groups,
257-
groups_len,
258-
master_secret,
259-
master_secret_len,
260-
shards,
261-
(uint16_t) total_shards,
262-
random_generator);
341+
total_shards = sskr_generate_shards_internal(group_threshold,
342+
groups,
343+
groups_len,
344+
master_secret,
345+
master_secret_len,
346+
shards,
347+
(uint16_t) total_shards,
348+
random_generator);
263349

264350
if (total_shards < 0) {
265351
error = total_shards;
@@ -296,19 +382,29 @@ typedef struct sskr_group_struct {
296382
uint8_t count;
297383
uint8_t member_index[SSS_MAX_SHARE_COUNT];
298384
const uint8_t *value[SSS_MAX_SHARE_COUNT];
299-
} sskr_group;
385+
} sskr_group_t;
300386

301387
/**
302-
* This version of combine shards potentially modifies the shard structures
303-
* in place, so it is for internal use only, however it provides the implementation
304-
* for both combine_shards and sskr_combine.
388+
* @brief Internal function to combine shards for secret reconstruction.
389+
*
390+
* @details This function implements the core logic for combining SSKR shards to
391+
* recover the original secret. It potentially modifies shard structures in
392+
* place, making it unsuitable for direct public use. It's the underlying
393+
* implementation for and `sskr_combine_shards`.
394+
*
395+
* @param[in,out] shards Pointer to an array of `sskr_shard_t` structures to be combined.
396+
* @param[in] shards_count Number of shards in the `shards` array.
397+
* @param[out] buffer Pointer to a buffer for working space and storing the reconstructed
398+
* secret.
399+
* @param[in] buffer_len Length of the `buffer` array in bytes.
400+
*
401+
* @return Length of the reconstructed secret on success, or a negative error code.
402+
* Specific error codes are implementation-dependent, consult implementation details.
305403
*/
306-
static int16_t sskr_combine_shards_internal(
307-
sskr_shard_t *shards, // array of shard structures
308-
uint8_t shards_count, // number of shards in array
309-
uint8_t *buffer, // working space, and place to return secret
310-
uint16_t buffer_len // total amount of working space
311-
) {
404+
static int16_t sskr_combine_shards_internal(sskr_shard_t *shards,
405+
uint8_t shards_count,
406+
uint8_t *buffer,
407+
uint16_t buffer_len) {
312408
int16_t error = 0;
313409
uint16_t identifier = 0;
314410
uint8_t group_threshold = 0;
@@ -319,7 +415,7 @@ static int16_t sskr_combine_shards_internal(
319415
}
320416

321417
uint8_t next_group = 0;
322-
sskr_group groups[SSKR_MAX_GROUP_COUNT];
418+
sskr_group_t groups[SSKR_MAX_GROUP_COUNT];
323419
uint8_t secret_len = 0;
324420

325421
for (uint8_t i = 0; i < shards_count; ++i) {
@@ -359,7 +455,7 @@ static int16_t sskr_combine_shards_internal(
359455
}
360456

361457
if (!group_found) {
362-
sskr_group *g = &groups[next_group];
458+
sskr_group_t *g = &groups[next_group];
363459
g->group_index = shard->group_index;
364460
g->member_threshold = shard->member_threshold;
365461
g->count = 1;
@@ -387,7 +483,7 @@ static int16_t sskr_combine_shards_internal(
387483
uint8_t *group_share = group_shares;
388484

389485
for (uint8_t i = 0; !error && i < (uint8_t) next_group; ++i) {
390-
sskr_group *g = &groups[i];
486+
sskr_group_t *g = &groups[i];
391487

392488
gx[i] = g->group_index;
393489
if (g->count < g->member_threshold) {
@@ -437,15 +533,11 @@ static int16_t sskr_combine_shards_internal(
437533
return secret_len;
438534
}
439535

440-
/////////////////////////////////////////////////
441-
// sskr_combine
442-
443-
int16_t sskr_combine(const uint8_t **input_shards, // array of pointers to 10-bit words
444-
uint8_t shard_len, // number of bytes in each serialized shard
445-
uint8_t shards_count, // total number of shards
446-
uint8_t *buffer, // working space, and place to return secret
447-
uint16_t buffer_len // total amount of working space
448-
) {
536+
int16_t sskr_combine_shards(const uint8_t **input_shards,
537+
uint8_t shard_len,
538+
uint8_t shards_count,
539+
uint8_t *buffer,
540+
uint16_t buffer_len) {
449541
int16_t result = 0;
450542

451543
if (shards_count == 0) {

0 commit comments

Comments
 (0)