Change sss_Keyshare type to uint8_t[33]

This change is introduced, because this makes it a lot easier to
expose the API the other languages that do not support C structs.

This is a break in the API contract for the `hazmat.h` module.
No API changes have been introduced in the `sss.c` module so all
current language bindings should be okay.
This commit is contained in:
Daan Sprenkels
2017-07-06 10:51:42 +08:00
parent 46227f5595
commit 5ad67a192b
6 changed files with 34 additions and 75 deletions

View File

@@ -19,10 +19,9 @@ hazmat.o: CFLAGS += -funroll-loops
test_hazmat.out: $(filter-out hazmat.o,$(OBJS))
test_sss.out: $(OBJS)
test_serialize.out: $(OBJS)
.PHONY: test
test: test_hazmat.out test_serialize.out test_sss.out
test: test_hazmat.out test_sss.out
.PHONY: clean
clean:

View File

@@ -34,19 +34,6 @@ FIPS202_SHAKE256(const unsigned char *in, unsigned long long inLen,
unsigned char *out, unsigned long long outLen);
void sss_serialize_keyshare(uint8_t *out, const sss_Keyshare *keyshare)
{
out[0] = keyshare->x;
memcpy(&out[1], &keyshare->y, sizeof(uint8_t[32]));
}
void sss_deserialize_keyshare(sss_Keyshare *keyshare, const uint8_t *in)
{
keyshare->x = in[0];
memcpy(&keyshare->y, &in[1], sizeof(uint8_t[32]));
}
static inline void
bitslice(uint32_t r[8], const uint8_t x[32])
@@ -312,7 +299,7 @@ gf256_inv(uint32_t r[8], uint32_t x[8])
for (share_idx = 0; share_idx < n; share_idx++) {
/* x value is in 1..n */
unbitsliced_x = share_idx + 1;
out[share_idx].x = unbitsliced_x;
out[share_idx][0] = unbitsliced_x;
bitslice_setall(x, unbitsliced_x);
/* Calculate y */
@@ -325,7 +312,7 @@ gf256_inv(uint32_t r[8], uint32_t x[8])
gf256_mul(tmp, xpow, poly[coeff_idx]);
gf256_add(y, tmp);
}
unbitslice(out[share_idx].y, y);
unbitslice(&out[share_idx][1], y);
}
}
@@ -345,8 +332,8 @@ gf256_inv(uint32_t r[8], uint32_t x[8])
/* Collect the x and y values */
for (share_idx = 0; share_idx < k; share_idx++) {
bitslice_setall(xs[share_idx], key_shares[share_idx].x);
bitslice(ys[share_idx], key_shares[share_idx].y);
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 */

View File

@@ -15,33 +15,14 @@
#include <inttypes.h>
#define sss_KEYSHARE_SERIALIZED_LEN 33 /* 1 + 32 */
#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 struct {
uint8_t x;
uint8_t y[32];
} sss_Keyshare;
/*
* Serialize a `sss_Keyshare` struct into a bytestring pointed to by `out`.
* The resulting bytestring will be `sss_KEYSHARE_SERIALIZED_LEN` long. The
* caller must make sure that `out` is large enough to contain this data.
*/
void sss_serialize_keyshare(uint8_t *out, const sss_Keyshare *keyshare);
/*
* Parse the bytestring `in` that has previously been generated by the
* `sss_serialize_keyshare` function. This function will write the resulting
* `sss_Keyshare` struct to the location pointed to by `keyshare`.
*/
void sss_deserialize_keyshare(sss_Keyshare *keyshare, const uint8_t *in);
typedef uint8_t sss_Keyshare[sss_KEYSHARE_LEN];
/*

33
sss.c
View File

@@ -37,6 +37,24 @@
static const unsigned char nonce[crypto_secretbox_NONCEBYTES] = { 0 };
/*
* Return a pointer to the ciphertext part of this Share
*/
static uint8_t* get_ciphertext(const sss_Share *share)
{
return (uint8_t*) &(*share)[sss_KEYSHARE_LEN];
}
/*
* Return a pointer to the KeyShare part of this Share
*/
static sss_Keyshare* get_keyshare(const sss_Share *share)
{
return (sss_Keyshare*) &share[0];
}
/*
* Create `n` shares with theshold `k` and write them to `out`
*/
@@ -64,8 +82,9 @@ void sss_create_shares(sss_Share *out, const unsigned char *data,
/* Build regular shares */
for (idx = 0; idx < n; idx++) {
sss_serialize_keyshare(out[idx], &keyshares[idx]);
memcpy(&out[idx][sss_KEYSHARE_SERIALIZED_LEN],
memcpy(get_keyshare(&out[idx]), &keyshares[idx][0],
sss_KEYSHARE_LEN);
memcpy(get_ciphertext(&out[idx]),
&c[crypto_secretbox_BOXZEROBYTES], sss_CLEN);
}
}
@@ -91,22 +110,22 @@ int sss_combine_shares(uint8_t *data, const sss_Share *shares, uint8_t k)
/* Check if all ciphertexts are the same */
if (k < 1) return -1;
for (idx = 1; idx < k; idx++) {
if (memcmp(&shares[0][sss_KEYSHARE_SERIALIZED_LEN],
&shares[idx][sss_KEYSHARE_SERIALIZED_LEN],
sss_CLEN) != 0) {
if (memcmp(get_ciphertext(&shares[0]),
get_ciphertext(&shares[idx]), sss_CLEN) != 0) {
return -1;
}
}
/* Restore the key */
for (idx = 0; idx < k; idx++) {
sss_deserialize_keyshare(&keyshares[idx], &shares[idx][0]);
memcpy(&keyshares[idx], get_keyshare(&shares[idx]),
sss_KEYSHARE_LEN);
}
sss_combine_keyshares(key, keyshares, k);
/* Decrypt the ciphertext */
memcpy(&c[crypto_secretbox_BOXZEROBYTES],
&shares[0][sss_KEYSHARE_SERIALIZED_LEN], sss_CLEN);
&shares[0][sss_KEYSHARE_LEN], sss_CLEN);
ret |= crypto_secretbox_open(m, c, clen, nonce, key);
memcpy(data, &m[crypto_secretbox_ZEROBYTES], sss_MLEN);

2
sss.h
View File

@@ -29,7 +29,7 @@ Length of the message (must be known at compile-time)
/*
* Length of a SSS share
*/
#define sss_SHARE_LEN (sss_CLEN + sss_KEYSHARE_SERIALIZED_LEN)
#define sss_SHARE_LEN (sss_CLEN + sss_KEYSHARE_LEN)
/*

View File

@@ -1,27 +0,0 @@
#include "hazmat.h"
#include <assert.h>
#include <string.h>
#include <stdio.h>
int main()
{
uint8_t serialized[sss_KEYSHARE_SERIALIZED_LEN];
sss_Keyshare keyshare;
size_t idx;
/* Serializing a KeyShare */
keyshare.x = 42;
for (idx = 0; idx < sizeof(uint8_t[32]); idx++) {
keyshare.y[idx] = idx + 0x80;
}
sss_serialize_keyshare(serialized, &keyshare);
memset(&keyshare, 0, sizeof(sss_Keyshare));
sss_deserialize_keyshare(&keyshare, serialized);
assert(keyshare.x == 42);
for (idx = 0; idx < sizeof(uint8_t[32]); idx++) {
assert(keyshare.y[idx] == idx + 0x80);
}
return 0;
}