|
|
|
/*
|
|
|
|
* This file is Copyright Daniel Silverstone <dsilvers@digital-scurf.org> 2006
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person
|
|
|
|
* obtaining a copy of this software and associated documentation
|
|
|
|
* files (the "Software"), to deal in the Software without
|
|
|
|
* restriction, including without limitation the rights to use, copy,
|
|
|
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
|
|
* of the Software, and to permit persons to whom the Software is
|
|
|
|
* furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be
|
|
|
|
* included in all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
|
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
* DEALINGS IN THE SOFTWARE.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
//#include "config.h"
|
|
|
|
#include "OS_portable.h"
|
|
|
|
#include "../includes/libgfshare.h"
|
|
|
|
//#include "../includes/libgfshare_tables.h"
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#define XMALLOC malloc
|
|
|
|
#define XFREE free
|
|
|
|
|
|
|
|
struct _gfshare_ctx
|
|
|
|
{
|
|
|
|
uint32_t sharecount,threshold,size,buffersize;
|
|
|
|
uint8_t sharenrs[255],buffer[];
|
|
|
|
};
|
|
|
|
|
|
|
|
uint8_t ctx_logs[256] = {
|
|
|
|
0x00, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6,
|
|
|
|
0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
|
|
|
|
0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81,
|
|
|
|
0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
|
|
|
|
0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21,
|
|
|
|
0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
|
|
|
|
0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9,
|
|
|
|
0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
|
|
|
|
0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd,
|
|
|
|
0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
|
|
|
|
0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd,
|
|
|
|
0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
|
|
|
|
0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e,
|
|
|
|
0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
|
|
|
|
0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b,
|
|
|
|
0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
|
|
|
|
0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d,
|
|
|
|
0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
|
|
|
|
0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c,
|
|
|
|
0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
|
|
|
|
0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd,
|
|
|
|
0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
|
|
|
|
0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e,
|
|
|
|
0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
|
|
|
|
0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76,
|
|
|
|
0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
|
|
|
|
0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa,
|
|
|
|
0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
|
|
|
|
0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51,
|
|
|
|
0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
|
|
|
|
0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8,
|
|
|
|
0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf };
|
|
|
|
|
|
|
|
uint8_t ctx_exps[510] = {
|
|
|
|
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
|
|
|
|
0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
|
|
|
|
0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9,
|
|
|
|
0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
|
|
|
|
0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35,
|
|
|
|
0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
|
|
|
|
0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0,
|
|
|
|
0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
|
|
|
|
0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc,
|
|
|
|
0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
|
|
|
|
0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f,
|
|
|
|
0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
|
|
|
|
0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88,
|
|
|
|
0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
|
|
|
|
0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93,
|
|
|
|
0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
|
|
|
|
0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9,
|
|
|
|
0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
|
|
|
|
0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa,
|
|
|
|
0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
|
|
|
|
0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e,
|
|
|
|
0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
|
|
|
|
0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4,
|
|
|
|
0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
|
|
|
|
0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e,
|
|
|
|
0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
|
|
|
|
0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef,
|
|
|
|
0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
|
|
|
|
0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5,
|
|
|
|
0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
|
|
|
|
0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83,
|
|
|
|
0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01,
|
|
|
|
0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1d,
|
|
|
|
0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26, 0x4c,
|
|
|
|
0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, 0x8f,
|
|
|
|
0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x9d,
|
|
|
|
0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, 0x6a,
|
|
|
|
0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23, 0x46,
|
|
|
|
0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, 0x5d,
|
|
|
|
0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1, 0x5f,
|
|
|
|
0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, 0x65,
|
|
|
|
0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0, 0xfd,
|
|
|
|
0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe,
|
|
|
|
0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2, 0xd9,
|
|
|
|
0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0x0d,
|
|
|
|
0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce, 0x81,
|
|
|
|
0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, 0x3b,
|
|
|
|
0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc, 0x85,
|
|
|
|
0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f,
|
|
|
|
0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54, 0xa8,
|
|
|
|
0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49,
|
|
|
|
0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73, 0xe6,
|
|
|
|
0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc,
|
|
|
|
0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff, 0xe3,
|
|
|
|
0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, 0x95,
|
|
|
|
0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41, 0x82,
|
|
|
|
0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, 0x1c,
|
|
|
|
0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6, 0x51,
|
|
|
|
0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3,
|
|
|
|
0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09, 0x12,
|
|
|
|
0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, 0xf7,
|
|
|
|
0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16, 0x2c,
|
|
|
|
0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b,
|
|
|
|
0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e };
|
|
|
|
|
|
|
|
/*void _gfshare_fill_rand_using_random(uint8_t *buffer,unsigned long long count)
|
|
|
|
{
|
|
|
|
uint32_t i;
|
|
|
|
for (i=0; i<count; i++)
|
|
|
|
buffer[i] = (random() & 0xff00) >> 8; // apparently the bottom 8 aren't very random but the middles ones are
|
|
|
|
}*/
|
|
|
|
//void randombytes(uint8_t *x,long xlen);
|
|
|
|
|
|
|
|
//gfshare_rand_func_t gfshare_fill_rand = _gfshare_fill_rand_using_random;
|
|
|
|
//gfshare_rand_func_t gfshare_fill_rand = OS_randombytes;
|
|
|
|
|
|
|
|
// ------------------------------------------------------[ Preparation ]----
|
|
|
|
|
|
|
|
gfshare_ctx *_gfshare_ctx_init_core(uint8_t *sharenrs,uint32_t sharecount,uint8_t threshold,uint32_t size)
|
|
|
|
{
|
|
|
|
gfshare_ctx *ctx;
|
|
|
|
ctx = XMALLOC(sizeof(struct _gfshare_ctx) + threshold * size);
|
|
|
|
if ( ctx == NULL )
|
|
|
|
return(NULL); // errno should still be set from XMALLOC()
|
|
|
|
ctx->sharecount = sharecount;
|
|
|
|
ctx->threshold = threshold;
|
|
|
|
ctx->size = size;
|
|
|
|
memcpy(ctx->sharenrs,sharenrs,sharecount);
|
|
|
|
ctx->buffersize = threshold * size;
|
|
|
|
return(ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialise a gfshare context for producing shares
|
|
|
|
gfshare_ctx *gfshare_ctx_init_enc(uint8_t *sharenrs,uint32_t sharecount,uint8_t threshold,uint32_t size)
|
|
|
|
{
|
|
|
|
uint32_t i;
|
|
|
|
// can't have x[i] = 0 - that would just be a copy of the secret, in theory
|
|
|
|
// in fact, due to the way we use exp/log for multiplication and treat log(0) as 0, it ends up as a copy of x[i] = 1
|
|
|
|
for (i=0; i<sharecount; i++)
|
|
|
|
{
|
|
|
|
if ( sharenrs[i] == 0 )
|
|
|
|
{
|
|
|
|
printf("null sharenrs error\n");
|
|
|
|
errno = EINVAL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return(_gfshare_ctx_init_core(sharenrs,sharecount,threshold,size));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialise a gfshare context for recombining shares
|
|
|
|
gfshare_ctx *gfshare_ctx_init_dec(uint8_t *sharenrs,uint32_t sharecount,uint32_t size)
|
|
|
|
{
|
|
|
|
gfshare_ctx *ctx = _gfshare_ctx_init_core(sharenrs,sharecount,sharecount,size);
|
|
|
|
if ( ctx != NULL )
|
|
|
|
ctx->threshold = 0;
|
|
|
|
return(ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Free a share context's memory.
|
|
|
|
void gfshare_ctx_free(gfshare_ctx *ctx)
|
|
|
|
{
|
|
|
|
long len = sizeof(struct _gfshare_ctx) + ctx->buffersize;
|
|
|
|
//gfshare_fill_rand((uint8_t*)ctx,len);
|
|
|
|
OS_randombytes((uint8_t *)ctx,len);
|
|
|
|
XFREE(ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------[ Splitting ]----
|
|
|
|
|
|
|
|
// Provide a secret to the encoder. (this re-scrambles the coefficients)
|
|
|
|
void gfshare_ctx_enc_setsecret(gfshare_ctx *ctx,uint8_t *secret)
|
|
|
|
{
|
|
|
|
memcpy(ctx->buffer + ((ctx->threshold-1) * ctx->size),secret,ctx->size);
|
|
|
|
//gfshare_fill_rand(ctx->buffer,(ctx->threshold-1) * ctx->size);
|
|
|
|
OS_randombytes(ctx->buffer,(ctx->threshold-1) * ctx->size);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Extract a share from the context. 'share' must be preallocated and at least 'size' bytes long.
|
|
|
|
// 'sharenr' is the index into the 'sharenrs' array of the share you want.
|
|
|
|
void calc_share(uint8_t *buffer,int32_t size,int32_t M,uint32_t ilog,uint8_t *share)
|
|
|
|
{
|
|
|
|
uint32_t pos,coefficient;//,ilog = ctx_logs[ctx->sharenrs[sharenr]];
|
|
|
|
//uint8_t *coefficient_ptr = buffer;
|
|
|
|
uint8_t *share_ptr,share_byte;
|
|
|
|
for (pos=0; pos<size; pos++)
|
|
|
|
share[pos] = *(buffer++);
|
|
|
|
for (coefficient=1; coefficient<M; coefficient++)
|
|
|
|
{
|
|
|
|
share_ptr = share;
|
|
|
|
for (pos=0; pos<size; pos++)
|
|
|
|
{
|
|
|
|
share_byte = *share_ptr;
|
|
|
|
if ( share_byte != 0 )
|
|
|
|
share_byte = ctx_exps[ilog + ctx_logs[share_byte]];
|
|
|
|
*share_ptr++ = (share_byte ^ *buffer++);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void gfshare_ctx_enc_getshare(gfshare_ctx *ctx,uint8_t sharenr,uint8_t *share)
|
|
|
|
{
|
|
|
|
calc_share(ctx->buffer,ctx->size,ctx->threshold,ctx_logs[ctx->sharenrs[sharenr]],share);
|
|
|
|
}
|
|
|
|
|
|
|
|
void calc_shares(uint8_t *shares,uint8_t *secret,int32_t size,int32_t width,int32_t M,int32_t N,uint8_t *sharenrs)
|
|
|
|
{
|
|
|
|
int32_t i;
|
|
|
|
uint8_t *buffer = calloc(M,width);
|
|
|
|
memset(shares,0,N*width);
|
|
|
|
memcpy(buffer + ((M - 1) * size),secret,size);
|
|
|
|
//gfshare_fill_rand(buffer,(M - 1) * size);
|
|
|
|
OS_randombytes(buffer,(M - 1) * size);
|
|
|
|
for (i=0; i<N; i++)
|
|
|
|
{
|
|
|
|
//uint32_t _crc32(uint32_t crc, const void *buf, size_t size);
|
|
|
|
calc_share(buffer,size,M,ctx_logs[sharenrs[i]],&shares[i * width]);
|
|
|
|
printf("(%02x %08x) ",sharenrs[i],calc_crc32(0,&shares[i*width],size));
|
|
|
|
}
|
|
|
|
free(buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------[ Recombination ]----
|
|
|
|
|
|
|
|
// Inform a recombination context of a change in share indexes
|
|
|
|
void gfshare_ctx_dec_newshares(gfshare_ctx *ctx,uint8_t *sharenrs)
|
|
|
|
{
|
|
|
|
memcpy(ctx->sharenrs,sharenrs,ctx->sharecount);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Provide a share context with one of the shares. The 'sharenr' is the index into the 'sharenrs' array
|
|
|
|
void gfshare_ctx_dec_giveshare(gfshare_ctx *ctx,uint8_t sharenr,uint8_t *share)
|
|
|
|
{
|
|
|
|
memcpy(ctx->buffer + (sharenr * ctx->size),share,ctx->size);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Extract the secret by interpolation of the shares. secretbuf must be allocated and at least 'size' bytes long
|
|
|
|
void gfshare_extract(uint8_t *secretbuf,uint8_t *sharenrs,int32_t N,uint8_t *buffer,int32_t size,int32_t width)
|
|
|
|
{
|
|
|
|
uint32_t i,j,Li_top,Li_bottom; uint8_t *secret_ptr,*share_ptr,sharei,sharej;
|
|
|
|
memset(secretbuf,0,width);
|
|
|
|
for (i=0; i<N; i++)
|
|
|
|
{
|
|
|
|
// Compute L(i) as per Lagrange Interpolation
|
|
|
|
Li_top = Li_bottom = 0;
|
|
|
|
if ( (sharei= sharenrs[i]) == 0 )
|
|
|
|
continue; // this share is not provided.
|
|
|
|
for (j=0; j<N; j++)
|
|
|
|
{
|
|
|
|
if ( i == j )
|
|
|
|
continue;
|
|
|
|
if ( (sharej= sharenrs[j]) == 0 )
|
|
|
|
continue; // skip empty share
|
|
|
|
Li_top += ctx_logs[sharej];
|
|
|
|
if ( Li_top >= 0xff )
|
|
|
|
Li_top -= 0xff;
|
|
|
|
Li_bottom += ctx_logs[sharei ^ sharej];
|
|
|
|
if ( Li_bottom >= 0xff )
|
|
|
|
Li_bottom -= 0xff;
|
|
|
|
}
|
|
|
|
if ( Li_bottom > Li_top )
|
|
|
|
Li_top += 0xff;
|
|
|
|
Li_top -= Li_bottom; // Li_top is now log(L(i))
|
|
|
|
secret_ptr = secretbuf;
|
|
|
|
share_ptr = buffer + (width * i);
|
|
|
|
for (j=0; j<size; j++)
|
|
|
|
{
|
|
|
|
if ( *share_ptr != 0 )
|
|
|
|
(*secret_ptr) ^= ctx_exps[Li_top + ctx_logs[*share_ptr]];
|
|
|
|
share_ptr++;
|
|
|
|
secret_ptr++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void gfshare_ctx_dec_extract(gfshare_ctx *ctx,uint8_t *secretbuf)
|
|
|
|
{
|
|
|
|
gfshare_extract(secretbuf,ctx->sharenrs,ctx->sharecount,ctx->buffer,ctx->size,ctx->size);
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t init_sharenrs(uint8_t sharenrs[255],uint8_t *orig,int32_t m,int32_t n)
|
|
|
|
{
|
|
|
|
uint8_t *randvals,valid[255];
|
|
|
|
int32_t i,j,r,remains,orign;
|
|
|
|
if ( m > n || n >= 0xff ) // reserve 255 for illegal sharei
|
|
|
|
{
|
|
|
|
printf("illegal M.%d of N.%d\n",m,n);
|
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
randvals = calloc(1,65536);
|
|
|
|
OS_randombytes(randvals,65536);
|
|
|
|
memset(sharenrs,0,n);
|
|
|
|
if ( orig == 0 && n == m )
|
|
|
|
{
|
|
|
|
for (i=0; i<255; i++)
|
|
|
|
valid[i] = (i + 1);
|
|
|
|
remains = orign = 255;
|
|
|
|
for (i=0; i<n; i++)
|
|
|
|
{
|
|
|
|
r = (randvals[i] % remains);
|
|
|
|
sharenrs[i] = valid[r];
|
|
|
|
printf("%d ",sharenrs[i]);
|
|
|
|
valid[r] = valid[--remains];
|
|
|
|
}
|
|
|
|
printf("FULL SET\n");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
remains = n;
|
|
|
|
orign = n;
|
|
|
|
memcpy(valid,sharenrs,n);
|
|
|
|
i = j = 0;
|
|
|
|
memset(sharenrs,0,n);
|
|
|
|
for (i=0; i<m; i++)
|
|
|
|
{
|
|
|
|
r = (rand() >> 8) % remains;
|
|
|
|
sharenrs[i] = valid[r];
|
|
|
|
valid[r] = valid[--remains];
|
|
|
|
}
|
|
|
|
/*while ( i < m )
|
|
|
|
{
|
|
|
|
if ( j >= 65536 )
|
|
|
|
{
|
|
|
|
gfshare_fill_rand(randvals,65536);
|
|
|
|
printf("refill j.%d\n",j);
|
|
|
|
j = 0;
|
|
|
|
}
|
|
|
|
r = (randvals[j++] % n);
|
|
|
|
if ( valid[r] != 0 )
|
|
|
|
{
|
|
|
|
remains--;
|
|
|
|
i++;
|
|
|
|
sharenrs[r] = valid[r];
|
|
|
|
//printf("%d ",sharenrs[i]);
|
|
|
|
valid[r] = 0;
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
for (i=0; i<n; i++)
|
|
|
|
printf("%d ",valid[i]);
|
|
|
|
printf("valid\n");
|
|
|
|
for (i=0; i<m; i++)
|
|
|
|
printf("%d ",sharenrs[i]);
|
|
|
|
printf("sharenrs vals m.%d of n.%d\n",m,n);
|
|
|
|
//getchar();
|
|
|
|
}
|
|
|
|
free(randvals);
|
|
|
|
//printf("sharenrs m.%d of n.%d\n",m,n);
|
|
|
|
if ( remains != (orign - m) )
|
|
|
|
{
|
|
|
|
printf("remains algo error??\n");
|
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
for (i=0; i<m; i++)
|
|
|
|
{
|
|
|
|
for (j=0; j<m; j++)
|
|
|
|
{
|
|
|
|
if ( i == j )
|
|
|
|
continue;
|
|
|
|
if ( sharenrs[i] != 0 && sharenrs[i] == sharenrs[j] )
|
|
|
|
{
|
|
|
|
printf("FATAL: duplicate entry sharenrs[%d] %d vs %d sharenrs[%d]\n",i,sharenrs[i],sharenrs[j],j);
|
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// test
|
|
|
|
int test_m_of_n(int m,int n,int size,int maxiters)
|
|
|
|
{
|
|
|
|
int32_t i,j,r,err = -1;
|
|
|
|
uint8_t *secret,*recomb,**shares,*allshares,sharenrs[255],testnrs[255];
|
|
|
|
gfshare_ctx *G;
|
|
|
|
if ( init_sharenrs(sharenrs,0,n,n) < 0 )
|
|
|
|
return(err);
|
|
|
|
secret = malloc(size);
|
|
|
|
recomb = malloc(size);
|
|
|
|
shares = calloc(n,sizeof(*shares));
|
|
|
|
allshares = calloc(254,size);
|
|
|
|
for (i=0; i<n; i++)
|
|
|
|
shares[i] = malloc(size);
|
|
|
|
// Stage 1, make a secret
|
|
|
|
OS_randombytes(secret,size);
|
|
|
|
|
|
|
|
err = 0;
|
|
|
|
r = m;
|
|
|
|
for (j=0; j<maxiters; j++)
|
|
|
|
{
|
|
|
|
memset(allshares,0,254*size);
|
|
|
|
// Stage 2, split it n ways with a threshold of m
|
|
|
|
if ( 1 )
|
|
|
|
{
|
|
|
|
G = gfshare_ctx_init_enc(sharenrs,n,r,size);
|
|
|
|
gfshare_ctx_enc_setsecret(G,secret);
|
|
|
|
for (i=0; i<n; i++)
|
|
|
|
gfshare_ctx_enc_getshare(G,i,shares[i]);
|
|
|
|
gfshare_ctx_free(G);
|
|
|
|
}
|
|
|
|
else calc_shares(allshares,secret,size,size,r,n,sharenrs);
|
|
|
|
|
|
|
|
// Prep the decode shape
|
|
|
|
memset(testnrs,0,n);
|
|
|
|
if ( init_sharenrs(testnrs,sharenrs,r,n) < 0 )
|
|
|
|
{
|
|
|
|
printf("iter.%d error init_sharenrs(m.%d of n.%d)\n",j,r,n);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
G = gfshare_ctx_init_dec(testnrs,n,size);
|
|
|
|
for (i=0; i<n; i++)
|
|
|
|
if ( testnrs[i] == sharenrs[i] )
|
|
|
|
gfshare_ctx_dec_giveshare(G,i,&allshares[i*size]);//shares[i]); //
|
|
|
|
|
|
|
|
gfshare_ctx_dec_newshares(G,testnrs);
|
|
|
|
gfshare_ctx_dec_extract(G,recomb);
|
|
|
|
if ( memcmp(secret,recomb,size) != 0 )
|
|
|
|
fprintf(stderr,"(ERRROR M.%d)\n",r), err++;
|
|
|
|
else fprintf(stderr,"M.%d\n",r);
|
|
|
|
r = ((rand() >> 8) % n) + 1;
|
|
|
|
}
|
|
|
|
err = 0;
|
|
|
|
printf("err.%d\n",err);
|
|
|
|
//#ifdef hardcoded_m_of_n_test
|
|
|
|
int32_t ok;
|
|
|
|
// Stage 3, attempt a recombination with shares 1 and 2
|
|
|
|
sharenrs[2] = 0;
|
|
|
|
gfshare_ctx_dec_newshares(G,sharenrs);
|
|
|
|
gfshare_ctx_dec_extract( G, recomb );
|
|
|
|
for( i = 0; i < 512; ++i )
|
|
|
|
if( secret[i] != recomb[i] )
|
|
|
|
ok = 0;
|
|
|
|
printf("shares 1 + 2: ok.%d\n",ok);
|
|
|
|
err += (ok == 0), ok = 1;
|
|
|
|
// Stage 4, attempt a recombination with shares 1 and 3
|
|
|
|
sharenrs[2] = '2';
|
|
|
|
sharenrs[1] = 0;
|
|
|
|
gfshare_ctx_dec_newshares( G, sharenrs );
|
|
|
|
gfshare_ctx_dec_extract( G, recomb );
|
|
|
|
for( i = 0; i < 512; ++i )
|
|
|
|
if( secret[i] != recomb[i] )
|
|
|
|
ok = 0;
|
|
|
|
printf("shares 1 + 3: ok.%d\n",ok);
|
|
|
|
err += (ok == 0), ok = 1;
|
|
|
|
// Stage 5, attempt a recombination with shares 2 and 3
|
|
|
|
sharenrs[0] = 0;
|
|
|
|
sharenrs[1] = '1';
|
|
|
|
gfshare_ctx_dec_newshares( G, sharenrs );
|
|
|
|
gfshare_ctx_dec_extract( G, recomb );
|
|
|
|
for( i = 0; i < 512; ++i )
|
|
|
|
if( secret[i] != recomb[i] )
|
|
|
|
ok = 0;
|
|
|
|
printf("shares 2 + 3: ok.%d\n",ok);
|
|
|
|
err += (ok == 0), ok = 1;
|
|
|
|
// Stage 6, attempt a recombination with shares 1, 2 and 3
|
|
|
|
sharenrs[0] = '0';
|
|
|
|
gfshare_ctx_dec_newshares( G, sharenrs );
|
|
|
|
gfshare_ctx_dec_extract( G, recomb );
|
|
|
|
for( i = 0; i < 512; ++i )
|
|
|
|
if( secret[i] != recomb[i] )
|
|
|
|
ok = 0;
|
|
|
|
printf("shares 1 + 2 + 3: ok.%d\n",ok);
|
|
|
|
err += (ok == 0), ok = 1;
|
|
|
|
gfshare_ctx_free( G );
|
|
|
|
printf("total error test_m_of_n %d\n",err);
|
|
|
|
//#endif
|
|
|
|
cleanup:
|
|
|
|
for (i=0; i<n; i++)
|
|
|
|
free(shares[i]);
|
|
|
|
free(shares);
|
|
|
|
free(allshares);
|
|
|
|
free(secret);
|
|
|
|
free(recomb);
|
|
|
|
return(-err);
|
|
|
|
}
|
|
|
|
|
|
|
|
|